@@ -80,13 +80,11 @@ class ProfileConfigFragment : PreferenceFragmentCompatDividers(), Toolbar.OnMenu
|
||||
val serviceMode = DataStore.serviceMode
|
||||
findPreference(Key.remoteDns).isEnabled = serviceMode != Key.modeProxy
|
||||
isProxyApps = findPreference(Key.proxyApps) as SwitchPreference
|
||||
if (Build.VERSION.SDK_INT < 21) isProxyApps.parent!!.removePreference(isProxyApps) else {
|
||||
isProxyApps.isEnabled = serviceMode == Key.modeVpn
|
||||
isProxyApps.setOnPreferenceClickListener {
|
||||
startActivity(Intent(activity, AppManager::class.java))
|
||||
isProxyApps.isChecked = true
|
||||
false
|
||||
}
|
||||
isProxyApps.isEnabled = serviceMode == Key.modeVpn
|
||||
isProxyApps.setOnPreferenceClickListener {
|
||||
startActivity(Intent(activity, AppManager::class.java))
|
||||
isProxyApps.isChecked = true
|
||||
false
|
||||
}
|
||||
findPreference(Key.udpdns).isEnabled = serviceMode != Key.modeProxy
|
||||
plugin = findPreference(Key.plugin) as IconListPreference
|
||||
|
||||
@@ -20,49 +20,19 @@
|
||||
|
||||
package com.github.shadowsocks.bg
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.LinkProperties
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import com.github.shadowsocks.App.Companion.app
|
||||
import com.github.shadowsocks.BuildConfig
|
||||
import okhttp3.Dns as Okdns
|
||||
import org.xbill.DNS.*
|
||||
import java.net.Inet6Address
|
||||
import java.net.InetAddress
|
||||
import java.net.NetworkInterface
|
||||
import java.net.UnknownHostException
|
||||
import java.util.*
|
||||
import okhttp3.Dns as Okdns
|
||||
|
||||
object Dns {
|
||||
private const val TAG = "Dns"
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun getDnsResolver(context: Context): String {
|
||||
val dnsResolvers = getDnsResolvers(context)
|
||||
if (dnsResolvers.isEmpty()) throw Exception("Couldn't find an active DNS resolver")
|
||||
val dnsResolver = dnsResolvers.iterator().next().toString()
|
||||
if (dnsResolver.startsWith("/")) return dnsResolver.substring(1)
|
||||
return dnsResolver
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun getDnsResolvers(context: Context): Collection<InetAddress> {
|
||||
val addresses = ArrayList<InetAddress>()
|
||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val classLinkProperties = Class.forName("android.net.LinkProperties")
|
||||
val getActiveLinkPropertiesMethod = ConnectivityManager::class.java.getMethod("getActiveLinkProperties")
|
||||
val linkProperties = getActiveLinkPropertiesMethod.invoke(connectivityManager)
|
||||
if (linkProperties != null) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
val dnses = classLinkProperties.getMethod("getDnses").invoke(linkProperties) as Collection<*>
|
||||
dnses.mapTo(addresses) { it as InetAddress }
|
||||
} else addresses.addAll((linkProperties as LinkProperties).dnsServers)
|
||||
}
|
||||
return addresses
|
||||
}
|
||||
|
||||
private val hasIPv6Support get() = try {
|
||||
val result = NetworkInterface.getNetworkInterfaces().asSequence().flatMap { it.inetAddresses.asSequence() }
|
||||
.count { it is Inet6Address && !it.isLoopbackAddress && !it.isLinkLocalAddress } > 0
|
||||
|
||||
@@ -40,8 +40,7 @@ import java.util.*
|
||||
|
||||
/**
|
||||
* Android < 8 VPN: always invisible because of VPN notification/icon
|
||||
* Android 4.x other: always visible
|
||||
* Android 5-7 other: only invisible in (possibly unsecure) lockscreen
|
||||
* Android < 8 other: only invisible in (possibly unsecure) lockscreen
|
||||
* Android 8+: always visible due to system limitations
|
||||
* (user can choose to hide the notification in secure lockscreen or anywhere)
|
||||
*/
|
||||
@@ -85,24 +84,22 @@ class ServiceNotification(private val service: BaseService.Interface, profileNam
|
||||
if (Build.VERSION.SDK_INT < 24) builder.addAction(R.drawable.ic_navigation_close,
|
||||
service.getString(R.string.stop), PendingIntent.getBroadcast(service, 0, Intent(Action.CLOSE), 0))
|
||||
val power = service.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
update(if (if (Build.VERSION.SDK_INT >= 20) power.isInteractive else @Suppress("DEPRECATION") power.isScreenOn)
|
||||
Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, true)
|
||||
update(if (power.isInteractive) Intent.ACTION_SCREEN_ON else Intent.ACTION_SCREEN_OFF, true)
|
||||
val screenFilter = IntentFilter()
|
||||
screenFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||
screenFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||
if (visible && Build.VERSION.SDK_INT in 21 until 26) screenFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||
if (visible && Build.VERSION.SDK_INT < 26) screenFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||
service.registerReceiver(lockReceiver, screenFilter)
|
||||
}
|
||||
|
||||
private fun update(action: String, forceShow: Boolean = false) {
|
||||
if (forceShow || service.data.state == BaseService.CONNECTED) when (action) {
|
||||
Intent.ACTION_SCREEN_OFF -> {
|
||||
setVisible(visible && Build.VERSION.SDK_INT < 21, forceShow)
|
||||
setVisible(false, forceShow)
|
||||
unregisterCallback() // unregister callback to save battery
|
||||
}
|
||||
Intent.ACTION_SCREEN_ON -> {
|
||||
setVisible(visible && (Build.VERSION.SDK_INT < 21 || !keyGuard.inKeyguardRestrictedInputMode()),
|
||||
forceShow)
|
||||
setVisible(visible && !keyGuard.inKeyguardRestrictedInputMode(), forceShow)
|
||||
service.data.binder.registerCallback(callback)
|
||||
service.data.binder.startListeningForBandwidth(callback)
|
||||
callbackRegistered = true
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.LocalSocket
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.util.Log
|
||||
@@ -140,7 +139,7 @@ class VpnService : BaseVpnService(), LocalDnsService.Interface {
|
||||
builder.addRoute("::", 0)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21 && profile.proxyApps) {
|
||||
if (profile.proxyApps) {
|
||||
val me = packageName
|
||||
profile.individual.split('\n')
|
||||
.filter { it != me }
|
||||
|
||||
@@ -22,7 +22,6 @@ package com.github.shadowsocks.tasker
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Resources
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.DefaultItemAnimator
|
||||
@@ -71,13 +70,12 @@ class ConfigActivity : AppCompatActivity() {
|
||||
|
||||
inner class ProfilesAdapter : RecyclerView.Adapter<ProfileViewHolder>() {
|
||||
internal val profiles = ProfileManager.getAllProfiles()?.toMutableList() ?: mutableListOf()
|
||||
private val name = "select_dialog_singlechoice_" + (if (Build.VERSION.SDK_INT >= 21) "material" else "holo")
|
||||
|
||||
override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) =
|
||||
if (position == 0) holder.bindDefault() else holder.bind(profiles[position - 1])
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileViewHolder = ProfileViewHolder(
|
||||
LayoutInflater.from(parent.context).inflate(Resources.getSystem()
|
||||
.getIdentifier(name, "layout", "android"), parent, false))
|
||||
.getIdentifier("select_dialog_singlechoice_material", "layout", "android"), parent, false))
|
||||
override fun getItemCount(): Int = 1 + profiles.size
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user