improved dns compatibility on newer versions
This commit is contained in:
parent
7365137548
commit
bddd1bb679
|
@ -27,6 +27,7 @@ env:
|
||||||
global:
|
global:
|
||||||
# COMPONENT_GOOGLE_REPO
|
# COMPONENT_GOOGLE_REPO
|
||||||
- secure: "OQ/wkORxY2qv4CmAdMxyW4ihRt5GRyxKxQRZpsdjMbwIKf3DlY6vBoNIEQ46sRRLAKOzkQ3LirodbWRCBlDN9WFw4XRsLTveqqtslMGeLf04peazXMIa6rJ22BCDGEmnzRNx6r3JRb9wEK1plNv4u4G9DgQ7ShzbwdZ8A5grlg8="
|
- secure: "OQ/wkORxY2qv4CmAdMxyW4ihRt5GRyxKxQRZpsdjMbwIKf3DlY6vBoNIEQ46sRRLAKOzkQ3LirodbWRCBlDN9WFw4XRsLTveqqtslMGeLf04peazXMIa6rJ22BCDGEmnzRNx6r3JRb9wEK1plNv4u4G9DgQ7ShzbwdZ8A5grlg8="
|
||||||
|
- GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.parallel=false -Dkotlin.incremental=false -Dkotlin.compiler.execution.strategy=in-process"
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
|
|
@ -44,7 +44,7 @@ subprojects {
|
||||||
SupportLib : '26.0.1',
|
SupportLib : '26.0.1',
|
||||||
SupportTest : '1.0.0',
|
SupportTest : '1.0.0',
|
||||||
MariotakuCommons : '0.9.17',
|
MariotakuCommons : '0.9.17',
|
||||||
RestFu : '0.9.57',
|
RestFu : '0.9.60',
|
||||||
ObjectCursor : '0.9.20',
|
ObjectCursor : '0.9.20',
|
||||||
PlayServices : '11.2.0',
|
PlayServices : '11.2.0',
|
||||||
MapsUtils : '0.5',
|
MapsUtils : '0.5',
|
||||||
|
@ -78,6 +78,7 @@ subprojects {
|
||||||
ExportablePreferences: '0.9.6',
|
ExportablePreferences: '0.9.6',
|
||||||
ACRA : '4.9.2',
|
ACRA : '4.9.2',
|
||||||
AbstractTask : '0.9.5',
|
AbstractTask : '0.9.5',
|
||||||
|
Dagger : '2.11',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
|
-Dorg.gradle.jvmargs=-Xmx6g
|
||||||
kotlin.incremental=true
|
kotlin.incremental=true
|
|
@ -87,7 +87,7 @@ android {
|
||||||
it.res.srcDirs += project.files("src/${it.name}/res-svg2png")
|
it.res.srcDirs += project.files("src/${it.name}/res-svg2png")
|
||||||
it.java.srcDirs += "src/${it.name}/kotlin"
|
it.java.srcDirs += "src/${it.name}/kotlin"
|
||||||
}
|
}
|
||||||
|
|
||||||
testOptions {
|
testOptions {
|
||||||
unitTests.returnDefaultValues = true
|
unitTests.returnDefaultValues = true
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ dependencies {
|
||||||
// wearApp project(':twidere.wear')
|
// wearApp project(':twidere.wear')
|
||||||
kapt "com.bluelinelabs:logansquare-compiler:${libVersions['LoganSquare']}"
|
kapt "com.bluelinelabs:logansquare-compiler:${libVersions['LoganSquare']}"
|
||||||
kapt "com.hannesdorfmann.parcelableplease:processor:${libVersions['ParcelablePlease']}"
|
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']}"
|
kapt "com.github.mariotaku.ObjectCursor:processor:${libVersions['ObjectCursor']}"
|
||||||
|
|
||||||
implementation project(':twidere.component.common')
|
implementation project(':twidere.component.common')
|
||||||
|
@ -186,7 +186,7 @@ dependencies {
|
||||||
implementation "com.github.mariotaku.RestFu:logansquare:${libVersions['RestFu']}"
|
implementation "com.github.mariotaku.RestFu:logansquare:${libVersions['RestFu']}"
|
||||||
implementation "com.squareup.okhttp3:okhttp:${libVersions['OkHttp']}"
|
implementation "com.squareup.okhttp3:okhttp:${libVersions['OkHttp']}"
|
||||||
implementation 'com.lnikkila:extendedtouchview:0.1.1'
|
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 'org.attoparser:attoparser:2.0.4.RELEASE'
|
||||||
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.9.1'
|
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.9.1'
|
||||||
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
|
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
|
||||||
|
|
|
@ -51,7 +51,10 @@ import android.support.v7.app.AlertDialog
|
||||||
import android.support.v7.app.AppCompatDelegate
|
import android.support.v7.app.AppCompatDelegate
|
||||||
import android.support.v7.widget.TintTypedArray
|
import android.support.v7.widget.TintTypedArray
|
||||||
import android.util.SparseIntArray
|
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.OnClickListener
|
||||||
import android.view.View.OnLongClickListener
|
import android.view.View.OnLongClickListener
|
||||||
import android.view.ViewGroup.MarginLayoutParams
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
|
@ -393,11 +396,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
|
||||||
super.onCreateOptionsMenu(menu)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
|
override fun getSystemWindowInsets(caller: Fragment, insets: Rect): Boolean {
|
||||||
if (caller === leftDrawerFragment) return super.getSystemWindowInsets(caller, insets)
|
if (caller === leftDrawerFragment) return super.getSystemWindowInsets(caller, insets)
|
||||||
if (mainTabs == null || homeContent == null) return false
|
if (mainTabs == null || homeContent == null) return false
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.mariotaku.twidere.extension.restfu
|
||||||
|
|
||||||
|
import org.mariotaku.restfu.http.HttpRequest
|
||||||
|
import org.mariotaku.restfu.http.MultiValueMap
|
||||||
|
|
||||||
|
fun HttpRequest.Builder.headers(config: MultiValueMap<String>.() -> Unit): HttpRequest.Builder {
|
||||||
|
headers(MultiValueMap<String>().apply { config(this) })
|
||||||
|
return this
|
||||||
|
}
|
|
@ -21,10 +21,11 @@ package org.mariotaku.twidere.extension.restfu
|
||||||
|
|
||||||
import org.mariotaku.restfu.http.MultiValueMap
|
import org.mariotaku.restfu.http.MultiValueMap
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mariotaku on 2017/4/29.
|
|
||||||
*/
|
|
||||||
|
|
||||||
operator fun <T> MultiValueMap<T>.contains(key: String): Boolean {
|
operator fun <T> MultiValueMap<T>.contains(key: String): Boolean {
|
||||||
return getFirst(key) != null
|
return getFirst(key) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun <T> MultiValueMap<T>.set(key: String, value: T) {
|
||||||
|
if (value in get(key)) return
|
||||||
|
add(key, value)
|
||||||
|
}
|
||||||
|
|
|
@ -33,13 +33,15 @@ import org.mariotaku.twidere.annotation.AccountType
|
||||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
|
import org.mariotaku.twidere.constant.SharedPreferenceConstants.*
|
||||||
import org.mariotaku.twidere.extension.model.getEndpoint
|
import org.mariotaku.twidere.extension.model.getEndpoint
|
||||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
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.account.cred.OAuthCredentials
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
import org.mariotaku.twidere.util.DataStoreUtils
|
import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.MicroBlogAPIFactory
|
import org.mariotaku.twidere.util.MicroBlogAPIFactory
|
||||||
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
||||||
|
import org.mariotaku.twidere.util.net.SystemDnsFetcher
|
||||||
import org.mariotaku.twidere.util.net.TwidereDns
|
import org.mariotaku.twidere.util.net.TwidereDns
|
||||||
import org.xbill.DNS.ResolverConfig
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
|
@ -115,12 +117,8 @@ class NetworkDiagnosticsFragment : BaseFragment() {
|
||||||
logPrintln(("System DNS servers"))
|
logPrintln(("System DNS servers"))
|
||||||
|
|
||||||
|
|
||||||
val servers = ResolverConfig.getCurrentConfig().servers()
|
val servers = SystemDnsFetcher.get(context)
|
||||||
if (servers != null) {
|
logPrintln(servers?.toString() ?: "null")
|
||||||
logPrintln(Arrays.toString(servers))
|
|
||||||
} else {
|
|
||||||
logPrintln("null")
|
|
||||||
}
|
|
||||||
logPrintln()
|
logPrintln()
|
||||||
|
|
||||||
for (accountKey in DataStoreUtils.getAccountKeys(context)) {
|
for (accountKey in DataStoreUtils.getAccountKeys(context)) {
|
||||||
|
@ -167,11 +165,14 @@ class NetworkDiagnosticsFragment : BaseFragment() {
|
||||||
val builder = HttpRequest.Builder()
|
val builder = HttpRequest.Builder()
|
||||||
builder.method(GET.METHOD)
|
builder.method(GET.METHOD)
|
||||||
builder.url(baseUrl)
|
builder.url(baseUrl)
|
||||||
|
builder.headers {
|
||||||
|
this["Accept"] = "*/*"
|
||||||
|
}
|
||||||
val start = SystemClock.uptimeMillis()
|
val start = SystemClock.uptimeMillis()
|
||||||
response = client.newCall(builder.build()).execute()
|
response = client.newCall(builder.build()).execute()
|
||||||
logPrint(" OK (${SystemClock.uptimeMillis() - start} ms)")
|
logPrint(" OK (${SystemClock.uptimeMillis() - start} ms)")
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
logPrint("ERROR: ${e.message}", LogText.State.ERROR)
|
logPrint(" ERROR: ${e.message}", LogText.State.ERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
logPrintln()
|
logPrintln()
|
||||||
|
@ -289,9 +290,9 @@ class NetworkDiagnosticsFragment : BaseFragment() {
|
||||||
try {
|
try {
|
||||||
val start = SystemClock.uptimeMillis()
|
val start = SystemClock.uptimeMillis()
|
||||||
test()
|
test()
|
||||||
logPrint("OK (${SystemClock.uptimeMillis() - start} ms)", LogText.State.OK)
|
logPrint(" OK (${SystemClock.uptimeMillis() - start} ms)", LogText.State.OK)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logPrint("ERROR: ${e.message}", LogText.State.ERROR)
|
logPrint(" ERROR: ${e.message}", LogText.State.ERROR)
|
||||||
}
|
}
|
||||||
|
|
||||||
logPrintln()
|
logPrintln()
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<String>? {
|
||||||
|
return impl.get(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class DnsFetcherBase {
|
||||||
|
@SuppressLint("PrivateApi")
|
||||||
|
open fun get(context: Context): List<String>? {
|
||||||
|
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<String>? {
|
||||||
|
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
|
val activeNetwork = cm.activateNetworkCompat ?: return null
|
||||||
|
return cm.getLinkProperties(activeNetwork)?.dnsServers?.map(InetAddress::getHostAddress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ import java.util.*
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@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,
|
private val hostMapping = context.getSharedPreferences(HOST_MAPPING_PREFERENCES_NAME,
|
||||||
Context.MODE_PRIVATE)
|
Context.MODE_PRIVATE)
|
||||||
|
@ -200,7 +200,9 @@ class TwidereDns(context: Context, private val preferences: SharedPreferences) :
|
||||||
private fun getResolver(): Resolver {
|
private fun getResolver(): Resolver {
|
||||||
return this.resolver ?: run {
|
return this.resolver ?: run {
|
||||||
val tcp = preferences.getBoolean(KEY_TCP_DNS_QUERY, false)
|
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)
|
val segs = it.split("#", limit = 2)
|
||||||
if (segs.isEmpty()) return@mapNotNull null
|
if (segs.isEmpty()) return@mapNotNull null
|
||||||
if (!isValidIpAddress(segs[0])) 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
|
val resolver: Resolver
|
||||||
if (resolvers != null && resolvers.isNotEmpty()) {
|
resolver = if (resolvers != null && resolvers.isNotEmpty()) {
|
||||||
resolver = ExtendedResolver(resolvers.toTypedArray())
|
ExtendedResolver(resolvers.toTypedArray())
|
||||||
} else {
|
} else {
|
||||||
resolver = SimpleResolver()
|
SimpleResolver()
|
||||||
}
|
}
|
||||||
resolver.setTCP(tcp)
|
resolver.setTCP(tcp)
|
||||||
this.resolver = resolver
|
this.resolver = resolver
|
||||||
|
|
Loading…
Reference in New Issue