Support new Wi-Fi locks in Android Q

This commit is contained in:
Mygod
2019-03-20 11:42:05 +08:00
parent da9d647339
commit 841ee5ce9d
7 changed files with 82 additions and 9 deletions

View File

@@ -15,6 +15,7 @@ import be.mygod.vpnhotspot.client.ClientViewModel
import be.mygod.vpnhotspot.client.ClientsFragment
import be.mygod.vpnhotspot.databinding.ActivityMainBinding
import be.mygod.vpnhotspot.manage.TetheringFragment
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
import be.mygod.vpnhotspot.util.ServiceForegroundConnector
import be.mygod.vpnhotspot.widget.SmartSnackbar
import com.google.android.material.bottomnavigation.BottomNavigationMenuView
@@ -41,6 +42,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
if (RepeaterService.supported) ServiceForegroundConnector(this, model, RepeaterService::class)
model.clients.observe(this, Observer { badge.badgeNumber = it.size })
SmartSnackbar.Register(lifecycle, binding.fragmentHolder)
WifiDoubleLock.ActivityListener(this)
}
override fun onNavigationItemSelected(item: MenuItem) = when (item.itemId) {

View File

@@ -12,6 +12,7 @@ import be.mygod.vpnhotspot.App.Companion.app
import be.mygod.vpnhotspot.net.Routing.Companion.IPTABLES
import be.mygod.vpnhotspot.net.monitor.IpMonitor
import be.mygod.vpnhotspot.net.monitor.UpstreamMonitor
import be.mygod.vpnhotspot.net.wifi.WifiDoubleLock
import be.mygod.vpnhotspot.preference.AlwaysAutoCompleteEditTextPreferenceDialogFragmentCompat
import be.mygod.vpnhotspot.preference.SharedPreferenceDataStore
import be.mygod.vpnhotspot.util.RootSession
@@ -26,6 +27,7 @@ import java.net.SocketException
class SettingsPreferenceFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
WifiDoubleLock.mode = WifiDoubleLock.mode // handle complicated default value and possible system upgrades
preferenceManager.preferenceDataStore = SharedPreferenceDataStore(app.pref)
RoutingManager.masqueradeMode = RoutingManager.masqueradeMode // flush default value
addPreferencesFromResource(R.xml.pref_settings)

View File

@@ -4,7 +4,15 @@ import android.annotation.SuppressLint
import android.content.SharedPreferences
import android.net.wifi.WifiManager
import android.os.PowerManager
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.core.content.edit
import androidx.core.content.getSystemService
import androidx.core.os.BuildCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import be.mygod.vpnhotspot.App.Companion.app
/**
@@ -13,8 +21,12 @@ import be.mygod.vpnhotspot.App.Companion.app
class WifiDoubleLock(lockType: Int) : AutoCloseable {
companion object : SharedPreferences.OnSharedPreferenceChangeListener {
private const val KEY = "service.wifiLock"
private val lockType get() =
WifiDoubleLock.Mode.valueOf(app.pref.getString(KEY, WifiDoubleLock.Mode.Full.toString()) ?: "").lockType
var mode: Mode
@Suppress("DEPRECATION")
get() = Mode.valueOf(app.pref.getString(KEY, Mode.Full.toString()) ?: "").let {
if (it == Mode.Full && BuildCompat.isAtLeastQ()) Mode.None else it
}
set(value) = app.pref.edit { putString(KEY, value.toString()) }
private val service by lazy { app.getSystemService<PowerManager>()!! }
private var holders = mutableSetOf<Any>()
@@ -23,7 +35,7 @@ class WifiDoubleLock(lockType: Int) : AutoCloseable {
fun acquire(holder: Any) = synchronized(this) {
if (holders.isEmpty()) {
app.pref.registerOnSharedPreferenceChangeListener(this)
val lockType = lockType
val lockType = mode.lockType
if (lockType != null) lock = WifiDoubleLock(lockType)
}
check(holders.add(holder))
@@ -40,14 +52,45 @@ class WifiDoubleLock(lockType: Int) : AutoCloseable {
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == KEY) synchronized(this) {
lock?.close()
val lockType = lockType
val lockType = mode.lockType
lock = if (lockType == null) null else WifiDoubleLock(lockType)
}
}
}
enum class Mode(val lockType: Int? = null) {
None, Full(WifiManager.WIFI_MODE_FULL), HighPerf(WifiManager.WIFI_MODE_FULL_HIGH_PERF)
enum class Mode(val lockType: Int? = null, val keepScreenOn: Boolean = false) {
None,
@Suppress("DEPRECATION")
@Deprecated("This constant was deprecated in API level Q.\n" +
"This API is non-functional and will have no impact.")
Full(WifiManager.WIFI_MODE_FULL),
HighPerf(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
@RequiresApi(29)
LowLatency(WifiManager.WIFI_MODE_FULL_LOW_LATENCY, true),
}
class ActivityListener(val activity: ComponentActivity) :
LifecycleObserver, SharedPreferences.OnSharedPreferenceChangeListener {
private var keepScreenOn: Boolean = false
set(value) {
if (field == value) return
field = value
if (value) activity.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
else activity.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
init {
activity.lifecycle.addObserver(this)
app.pref.registerOnSharedPreferenceChangeListener(this)
keepScreenOn = mode.keepScreenOn
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == KEY) keepScreenOn = mode.keepScreenOn
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun shutdown() = app.pref.unregisterOnSharedPreferenceChangeListener(this)
}
private val wifi = app.wifi.createWifiLock(lockType, "vpnhotspot:wifi").apply { acquire() }

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="settings_service_wifi_lock">
<item>@string/settings_service_wifi_lock_none</item>
<item>@string/settings_service_wifi_lock_high_perf_v29</item>
<item>@string/settings_service_wifi_lock_low_latency</item>
</string-array>
<string-array name="settings_service_wifi_lock_values">
<item>None</item>
<item>HighPerf</item>
<item>LowLatency</item>
</string-array>
</resources>

View File

@@ -101,6 +101,8 @@
<string name="settings_service_wifi_lock_none">System default</string>
<string name="settings_service_wifi_lock_full">On</string>
<string name="settings_service_wifi_lock_high_perf">High Performance Mode</string>
<string name="settings_service_wifi_lock_high_perf_v29">Disable power save</string>
<string name="settings_service_wifi_lock_low_latency">Low latency mode</string>
<string name="settings_service_ip_monitor">Network status monitor mode</string>
<string name="settings_service_ip_monitor_monitor">Netlink monitor</string>
<string name="settings_service_ip_monitor_monitor_root">Netlink monitor with root</string>

View File

@@ -41,7 +41,6 @@
app:icon="@drawable/ic_device_wifi_lock"
app:entries="@array/settings_service_wifi_lock"
app:entryValues="@array/settings_service_wifi_lock_values"
app:defaultValue="Full"
app:title="@string/settings_service_wifi_lock"
app:useSimpleSummaryProvider="true"/>
<SwitchPreference