diff --git a/.travis.yml b/.travis.yml index 969d4d804..764f0d3c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,7 @@ env: global: # COMPONENT_GOOGLE_REPO - secure: "OQ/wkORxY2qv4CmAdMxyW4ihRt5GRyxKxQRZpsdjMbwIKf3DlY6vBoNIEQ46sRRLAKOzkQ3LirodbWRCBlDN9WFw4XRsLTveqqtslMGeLf04peazXMIa6rJ22BCDGEmnzRNx6r3JRb9wEK1plNv4u4G9DgQ7ShzbwdZ8A5grlg8=" + - GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.parallel=false -Dkotlin.incremental=false -Dkotlin.compiler.execution.strategy=in-process" addons: apt: diff --git a/build.gradle b/build.gradle index 1399550b4..c2ddab827 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ subprojects { SupportLib : '26.0.1', SupportTest : '1.0.0', MariotakuCommons : '0.9.17', - RestFu : '0.9.57', + RestFu : '0.9.60', ObjectCursor : '0.9.20', PlayServices : '11.2.0', MapsUtils : '0.5', @@ -78,6 +78,7 @@ subprojects { ExportablePreferences: '0.9.6', ACRA : '4.9.2', AbstractTask : '0.9.5', + Dagger : '2.11', ] } diff --git a/gradle.properties b/gradle.properties index 587b72778..1ed9c3ef6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ +-Dorg.gradle.jvmargs=-Xmx6g kotlin.incremental=true \ No newline at end of file diff --git a/twidere/build.gradle b/twidere/build.gradle index 189d9f266..161264029 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -87,7 +87,7 @@ android { it.res.srcDirs += project.files("src/${it.name}/res-svg2png") it.java.srcDirs += "src/${it.name}/kotlin" } - + testOptions { unitTests.returnDefaultValues = true } @@ -104,7 +104,7 @@ dependencies { // wearApp project(':twidere.wear') kapt "com.bluelinelabs:logansquare-compiler:${libVersions['LoganSquare']}" kapt "com.hannesdorfmann.parcelableplease:processor:${libVersions['ParcelablePlease']}" - kapt 'com.google.dagger:dagger-compiler:2.11' + kapt "com.google.dagger:dagger-compiler:${libVersions['Dagger']}" kapt "com.github.mariotaku.ObjectCursor:processor:${libVersions['ObjectCursor']}" implementation project(':twidere.component.common') @@ -186,7 +186,7 @@ dependencies { implementation "com.github.mariotaku.RestFu:logansquare:${libVersions['RestFu']}" implementation "com.squareup.okhttp3:okhttp:${libVersions['OkHttp']}" implementation 'com.lnikkila:extendedtouchview:0.1.1' - implementation 'com.google.dagger:dagger:2.11' + implementation "com.google.dagger:dagger:${libVersions['Dagger']}" implementation 'org.attoparser:attoparser:2.0.4.RELEASE' implementation 'com.getkeepsafe.taptargetview:taptargetview:1.9.1' implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0' diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt index 5bee36723..d40103e77 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt @@ -51,7 +51,10 @@ import android.support.v7.app.AlertDialog import android.support.v7.app.AppCompatDelegate import android.support.v7.widget.TintTypedArray import android.util.SparseIntArray -import android.view.* +import android.view.Gravity +import android.view.KeyEvent +import android.view.MenuItem +import android.view.View import android.view.View.OnClickListener import android.view.View.OnLongClickListener import android.view.ViewGroup.MarginLayoutParams @@ -393,11 +396,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp return true } - override fun onCreateOptionsMenu(menu: Menu): Boolean { - super.onCreateOptionsMenu(menu) - return false - } - override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean { if (caller === leftDrawerFragment) return super.getSystemWindowInsets(caller, insets) if (mainTabs == null || homeContent == null) return false diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ConnectivityManagerExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ConnectivityManagerExtensions.kt new file mode 100644 index 000000000..243518b4e --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ConnectivityManagerExtensions.kt @@ -0,0 +1,38 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.extension + +import android.annotation.TargetApi +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkInfo +import android.os.Build + +val ConnectivityManager.activateNetworkCompat: Network? + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + get() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return activeNetwork + } + val activeInfo = activeNetworkInfo ?: return null + return allNetworks.firstOrNull { activeInfo.same(getNetworkInfo(it)) } + } + +private fun NetworkInfo.same(another: NetworkInfo) = type == another.type && subtype == another.subtype \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/HttpRequestExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/HttpRequestExtensions.kt new file mode 100644 index 000000000..52f51ad6e --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/HttpRequestExtensions.kt @@ -0,0 +1,28 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.extension.restfu + +import org.mariotaku.restfu.http.HttpRequest +import org.mariotaku.restfu.http.MultiValueMap + +fun HttpRequest.Builder.headers(config: MultiValueMap.() -> Unit): HttpRequest.Builder { + headers(MultiValueMap().apply { config(this) }) + return this +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/MultiValueMapExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/MultiValueMapExtensions.kt index 88c50349c..7a5c9bcf1 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/MultiValueMapExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/restfu/MultiValueMapExtensions.kt @@ -21,10 +21,11 @@ package org.mariotaku.twidere.extension.restfu import org.mariotaku.restfu.http.MultiValueMap -/** - * Created by mariotaku on 2017/4/29. - */ - operator fun MultiValueMap.contains(key: String): Boolean { return getFirst(key) != null } + +operator fun MultiValueMap.set(key: String, value: T) { + if (value in get(key)) return + add(key, value) +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.kt index d1a077631..8aafca0b4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/NetworkDiagnosticsFragment.kt @@ -33,13 +33,15 @@ import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.constant.SharedPreferenceConstants.* import org.mariotaku.twidere.extension.model.getEndpoint import org.mariotaku.twidere.extension.model.newMicroBlogInstance +import org.mariotaku.twidere.extension.restfu.headers +import org.mariotaku.twidere.extension.restfu.set import org.mariotaku.twidere.model.account.cred.OAuthCredentials import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.util.DataStoreUtils import org.mariotaku.twidere.util.MicroBlogAPIFactory import org.mariotaku.twidere.util.dagger.DependencyHolder +import org.mariotaku.twidere.util.net.SystemDnsFetcher import org.mariotaku.twidere.util.net.TwidereDns -import org.xbill.DNS.ResolverConfig import java.io.IOException import java.io.OutputStream import java.lang.ref.WeakReference @@ -115,12 +117,8 @@ class NetworkDiagnosticsFragment : BaseFragment() { logPrintln(("System DNS servers")) - val servers = ResolverConfig.getCurrentConfig().servers() - if (servers != null) { - logPrintln(Arrays.toString(servers)) - } else { - logPrintln("null") - } + val servers = SystemDnsFetcher.get(context) + logPrintln(servers?.toString() ?: "null") logPrintln() for (accountKey in DataStoreUtils.getAccountKeys(context)) { @@ -167,11 +165,14 @@ class NetworkDiagnosticsFragment : BaseFragment() { val builder = HttpRequest.Builder() builder.method(GET.METHOD) builder.url(baseUrl) + builder.headers { + this["Accept"] = "*/*" + } val start = SystemClock.uptimeMillis() response = client.newCall(builder.build()).execute() logPrint(" OK (${SystemClock.uptimeMillis() - start} ms)") } catch (e: IOException) { - logPrint("ERROR: ${e.message}", LogText.State.ERROR) + logPrint(" ERROR: ${e.message}", LogText.State.ERROR) } logPrintln() @@ -289,9 +290,9 @@ class NetworkDiagnosticsFragment : BaseFragment() { try { val start = SystemClock.uptimeMillis() test() - logPrint("OK (${SystemClock.uptimeMillis() - start} ms)", LogText.State.OK) + logPrint(" OK (${SystemClock.uptimeMillis() - start} ms)", LogText.State.OK) } catch (e: Exception) { - logPrint("ERROR: ${e.message}", LogText.State.ERROR) + logPrint(" ERROR: ${e.message}", LogText.State.ERROR) } logPrintln() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/SystemDnsFetcher.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/SystemDnsFetcher.kt new file mode 100644 index 000000000..dfdab473e --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/SystemDnsFetcher.kt @@ -0,0 +1,67 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.mariotaku.twidere.util.net + +import android.annotation.SuppressLint +import android.content.Context +import android.net.ConnectivityManager +import android.os.Build +import android.support.annotation.RequiresApi +import org.mariotaku.twidere.extension.activateNetworkCompat +import java.net.InetAddress + +object SystemDnsFetcher { + val impl = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + DnsFetcherBase() + } else { + DnsFetcherLollipop() + } + + fun get(context: Context): List? { + return impl.get(context) + } + + open class DnsFetcherBase { + @SuppressLint("PrivateApi") + open fun get(context: Context): List? { + try { + val SystemProperties = Class.forName("android.os.SystemProperties") + val method = SystemProperties.getMethod("get", String::class.java) + val netdns = arrayOf("net.dns1", "net.dns2", "net.dns3", "net.dns4") + return netdns.mapNotNull { key -> + return@mapNotNull method(null, key) as? String + } + } catch (e: Exception) { + return null + } + } + } + + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + class DnsFetcherLollipop : DnsFetcherBase() { + + override fun get(context: Context): List? { + val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + val activeNetwork = cm.activateNetworkCompat ?: return null + return cm.getLinkProperties(activeNetwork)?.dnsServers?.map(InetAddress::getHostAddress) + } + } + +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/TwidereDns.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/TwidereDns.kt index 4b5b2d8a5..cb00fd429 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/TwidereDns.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/net/TwidereDns.kt @@ -36,7 +36,7 @@ import java.util.* import javax.inject.Singleton @Singleton -class TwidereDns(context: Context, private val preferences: SharedPreferences) : Dns { +class TwidereDns(val context: Context, private val preferences: SharedPreferences) : Dns { private val hostMapping = context.getSharedPreferences(HOST_MAPPING_PREFERENCES_NAME, Context.MODE_PRIVATE) @@ -200,7 +200,9 @@ class TwidereDns(context: Context, private val preferences: SharedPreferences) : private fun getResolver(): Resolver { return this.resolver ?: run { val tcp = preferences.getBoolean(KEY_TCP_DNS_QUERY, false) - val resolvers = preferences.getString(KEY_DNS_SERVER, null)?.split(';', ',', ' ')?.mapNotNull { + val servers = preferences.getString(KEY_DNS_SERVER, null)?.split(';', ',', ' ') ?: + SystemDnsFetcher.get(context) + val resolvers = servers?.mapNotNull { val segs = it.split("#", limit = 2) if (segs.isEmpty()) return@mapNotNull null if (!isValidIpAddress(segs[0])) return@mapNotNull null @@ -214,10 +216,10 @@ class TwidereDns(context: Context, private val preferences: SharedPreferences) : } } val resolver: Resolver - if (resolvers != null && resolvers.isNotEmpty()) { - resolver = ExtendedResolver(resolvers.toTypedArray()) + resolver = if (resolvers != null && resolvers.isNotEmpty()) { + ExtendedResolver(resolvers.toTypedArray()) } else { - resolver = SimpleResolver() + SimpleResolver() } resolver.setTCP(tcp) this.resolver = resolver