summaryrefslogtreecommitdiffhomepage
path: root/ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt')
-rw-r--r--ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt88
1 files changed, 88 insertions, 0 deletions
diff --git a/ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt b/ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt
new file mode 100644
index 00000000..46f699a5
--- /dev/null
+++ b/ui/src/main/java/com/wireguard/android/preference/KernelModuleEnablerPreference.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2020 WireGuard LLC. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.wireguard.android.preference
+
+import android.content.Context
+import android.content.Intent
+import android.util.AttributeSet
+import android.util.Log
+import androidx.lifecycle.lifecycleScope
+import androidx.preference.Preference
+import com.wireguard.android.Application
+import com.wireguard.android.R
+import com.wireguard.android.activity.SettingsActivity
+import com.wireguard.android.backend.Tunnel
+import com.wireguard.android.backend.WgQuickBackend
+import com.wireguard.android.util.UserKnobs
+import com.wireguard.android.util.activity
+import com.wireguard.android.util.lifecycleScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlin.system.exitProcess
+
+class KernelModuleEnablerPreference(context: Context, attrs: AttributeSet?) : Preference(context, attrs) {
+ private var state = State.UNKNOWN
+
+ init {
+ isVisible = false
+ lifecycleScope.launch {
+ setState(if (Application.getBackend() is WgQuickBackend) State.ENABLED else State.DISABLED)
+ }
+ }
+
+ override fun getSummary() = if (state == State.UNKNOWN) "" else context.getString(state.summaryResourceId)
+
+ override fun getTitle() = if (state == State.UNKNOWN) "" else context.getString(state.titleResourceId)
+
+ override fun onClick() {
+ activity.lifecycleScope.launch {
+ if (state == State.DISABLED) {
+ setState(State.ENABLING)
+ UserKnobs.setEnableKernelModule(true)
+ } else if (state == State.ENABLED) {
+ setState(State.DISABLING)
+ UserKnobs.setEnableKernelModule(false)
+ }
+ val observableTunnels = Application.getTunnelManager().getTunnels()
+ val downings = observableTunnels.map { async(SupervisorJob()) { it.setStateAsync(Tunnel.State.DOWN) } }
+ try {
+ downings.awaitAll()
+ withContext(Dispatchers.IO) {
+ val restartIntent = Intent(context, SettingsActivity::class.java)
+ restartIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ Application.get().startActivity(restartIntent)
+ exitProcess(0)
+ }
+ } catch (e: Throwable) {
+ Log.e(TAG, Log.getStackTraceString(e))
+ }
+ }
+ }
+
+ private fun setState(state: State) {
+ if (this.state == state) return
+ this.state = state
+ if (isEnabled != state.shouldEnableView) isEnabled = state.shouldEnableView
+ if (isVisible != state.visible) isVisible = state.visible
+ notifyChanged()
+ }
+
+ private enum class State(val titleResourceId: Int, val summaryResourceId: Int, val shouldEnableView: Boolean, val visible: Boolean) {
+ UNKNOWN(0, 0, false, false),
+ ENABLED(R.string.module_enabler_enabled_title, R.string.module_enabler_enabled_summary, true, true),
+ DISABLED(R.string.module_enabler_disabled_title, R.string.module_enabler_disabled_summary, true, true),
+ ENABLING(R.string.module_enabler_disabled_title, R.string.success_application_will_restart, false, true),
+ DISABLING(R.string.module_enabler_enabled_title, R.string.success_application_will_restart, false, true);
+ }
+
+ companion object {
+ private const val TAG = "WireGuard/KernelModuleEnablerPreference"
+ }
+}