From 85dd303c88f636024ce8b32e17ff76bcb3a19911 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 26 Mar 2020 01:55:44 -0600 Subject: ui: root: rewrite in kotlin Signed-off-by: Jason A. Donenfeld --- .../main/java/com/wireguard/android/Application.kt | 159 +++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ui/src/main/java/com/wireguard/android/Application.kt (limited to 'ui/src/main/java/com/wireguard/android/Application.kt') diff --git a/ui/src/main/java/com/wireguard/android/Application.kt b/ui/src/main/java/com/wireguard/android/Application.kt new file mode 100644 index 00000000..0e522abf --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/Application.kt @@ -0,0 +1,159 @@ +/* + * Copyright © 2017-2019 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package com.wireguard.android + +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.os.AsyncTask +import android.os.Build +import android.os.Handler +import android.os.Looper +import android.os.StrictMode +import android.os.StrictMode.VmPolicy +import android.util.Log +import androidx.appcompat.app.AppCompatDelegate +import androidx.preference.PreferenceManager +import com.wireguard.android.backend.Backend +import com.wireguard.android.backend.GoBackend +import com.wireguard.android.backend.WgQuickBackend +import com.wireguard.android.configStore.FileConfigStore +import com.wireguard.android.model.TunnelManager +import com.wireguard.android.util.AsyncWorker +import com.wireguard.android.util.ExceptionLoggers +import com.wireguard.android.util.ModuleLoader +import com.wireguard.android.util.RootShell +import com.wireguard.android.util.ToolsInstaller +import java9.util.concurrent.CompletableFuture +import java.lang.ref.WeakReference +import java.util.Locale + +class Application : android.app.Application(), OnSharedPreferenceChangeListener { + private val futureBackend = CompletableFuture() + private lateinit var asyncWorker: AsyncWorker + private var backend: Backend? = null + private lateinit var moduleLoader: ModuleLoader + private lateinit var rootShell: RootShell + private lateinit var sharedPreferences: SharedPreferences + private lateinit var toolsInstaller: ToolsInstaller + private lateinit var tunnelManager: TunnelManager + + override fun attachBaseContext(context: Context) { + super.attachBaseContext(context) + if (BuildConfig.MIN_SDK_VERSION > Build.VERSION.SDK_INT) { + val intent = Intent(Intent.ACTION_MAIN) + intent.addCategory(Intent.CATEGORY_HOME) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) + System.exit(0) + } + if (BuildConfig.DEBUG) { + StrictMode.setVmPolicy(VmPolicy.Builder().detectAll().penaltyLog().build()) + } + } + + override fun onCreate() { + Log.i(TAG, USER_AGENT) + super.onCreate() + asyncWorker = AsyncWorker(AsyncTask.SERIAL_EXECUTOR, Handler(Looper.getMainLooper())) + rootShell = RootShell(applicationContext) + toolsInstaller = ToolsInstaller(applicationContext, rootShell) + moduleLoader = ModuleLoader(applicationContext, rootShell, USER_AGENT) + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + AppCompatDelegate.setDefaultNightMode( + if (sharedPreferences.getBoolean("dark_theme", false)) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO) + } else { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) + } + tunnelManager = TunnelManager(FileConfigStore(applicationContext)) + tunnelManager.onCreate() + asyncWorker.supplyAsync { getBackend() }.thenAccept { futureBackend.complete(it) } + sharedPreferences.registerOnSharedPreferenceChangeListener(this) + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + if ("multiple_tunnels" == key && backend != null && backend is WgQuickBackend) + (backend as WgQuickBackend).setMultipleTunnels(sharedPreferences.getBoolean(key, false)) + } + + override fun onTerminate() { + sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + super.onTerminate() + } + + companion object { + val USER_AGENT = String.format(Locale.ENGLISH, "WireGuard/%s (Android %d; %s; %s; %s %s; %s)", BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT, if (Build.SUPPORTED_ABIS.isNotEmpty()) Build.SUPPORTED_ABIS[0] else "unknown ABI", Build.BOARD, Build.MANUFACTURER, Build.MODEL, Build.FINGERPRINT) + private val TAG = "WireGuard/" + Application::class.java.simpleName + private lateinit var weakSelf: WeakReference + + @JvmStatic + fun get(): Application { + return weakSelf.get()!! + } + + @JvmStatic + fun getAsyncWorker() = get().asyncWorker + + @JvmStatic + fun getBackend(): Backend { + val app = get() + synchronized(app.futureBackend) { + if (app.backend == null) { + var backend: Backend? = null + var didStartRootShell = false + if (!ModuleLoader.isModuleLoaded() && app.moduleLoader.moduleMightExist()) { + try { + app.rootShell.start() + didStartRootShell = true + app.moduleLoader.loadModule() + } catch (ignored: Exception) { + } + } + if (!app.sharedPreferences.getBoolean("disable_kernel_module", false) && ModuleLoader.isModuleLoaded()) { + try { + if (!didStartRootShell) + app.rootShell.start() + val wgQuickBackend = WgQuickBackend(app.applicationContext, app.rootShell, app.toolsInstaller) + wgQuickBackend.setMultipleTunnels(app.sharedPreferences.getBoolean("multiple_tunnels", false)) + backend = wgQuickBackend + } catch (ignored: Exception) { + } + } + if (backend == null) { + backend = GoBackend(app.applicationContext) + GoBackend.setAlwaysOnCallback { get().tunnelManager.restoreState(true).whenComplete(ExceptionLoggers.D) } + } + app.backend = backend + } + return app.backend!! + } + } + + @JvmStatic + fun getBackendAsync() = get().futureBackend + + @JvmStatic + fun getModuleLoader() = get().moduleLoader + + @JvmStatic + fun getRootShell() = get().rootShell + + @JvmStatic + fun getSharedPreferences() = get().sharedPreferences + + @JvmStatic + fun getToolsInstaller() = get().toolsInstaller + + @JvmStatic + fun getTunnelManager() = get().tunnelManager + } + + init { + weakSelf = WeakReference(this) + } +} -- cgit v1.2.3-59-g8ed1b