diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-03-09 15:19:02 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-03-09 15:21:34 -0600 |
commit | 492fcce0530028952e787aaec266b223b4305bde (patch) | |
tree | 16c807b3c34a3baacca5c6433c87fe12d034a5d1 | |
parent | d61f17dbd3ce45fc56654d2475499f7dcb277f30 (diff) |
KernelModuleDisabler: allow disabling the kernel module backend
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
5 files changed, 93 insertions, 1 deletions
diff --git a/ui/src/main/java/com/wireguard/android/Application.java b/ui/src/main/java/com/wireguard/android/Application.java index 6cf4da36..c0c89fcd 100644 --- a/ui/src/main/java/com/wireguard/android/Application.java +++ b/ui/src/main/java/com/wireguard/android/Application.java @@ -75,7 +75,7 @@ public class Application extends android.app.Application implements SharedPrefer } catch (final Exception ignored) { } } - if (ModuleLoader.isModuleLoaded()) { + if (!app.sharedPreferences.getBoolean("disable_kernel_module", false) && ModuleLoader.isModuleLoaded()) { try { if (!didStartRootShell) app.rootShell.start(); diff --git a/ui/src/main/java/com/wireguard/android/activity/SettingsActivity.java b/ui/src/main/java/com/wireguard/android/activity/SettingsActivity.java index 4d13bfbf..5d8e91f9 100644 --- a/ui/src/main/java/com/wireguard/android/activity/SettingsActivity.java +++ b/ui/src/main/java/com/wireguard/android/activity/SettingsActivity.java @@ -117,10 +117,12 @@ public class SettingsActivity extends ThemeChangeAwareActivity { }); final Preference moduleInstaller = getPreferenceManager().findPreference("module_downloader"); + final Preference kernelModuleDisabler = getPreferenceManager().findPreference("kernel_module_disabler"); moduleInstaller.setVisible(false); if (ModuleLoader.isModuleLoaded()) { screen.removePreference(moduleInstaller); } else { + screen.removePreference(kernelModuleDisabler); Application.getAsyncWorker().runAsync(Application.getRootShell()::start).whenComplete((v, e) -> { if (e == null) moduleInstaller.setVisible(true); diff --git a/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java new file mode 100644 index 00000000..b3d945bd --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/preference/KernelModuleDisablerPreference.java @@ -0,0 +1,84 @@ +/* + * 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 com.wireguard.android.Application; +import com.wireguard.android.R; +import com.wireguard.android.backend.WgQuickBackend; +import com.wireguard.util.NonNullForAll; + +import androidx.preference.Preference; + +@NonNullForAll +public class KernelModuleDisablerPreference extends Preference { + private State state; + + public KernelModuleDisablerPreference(final Context context, final AttributeSet attrs) { + super(context, attrs); + state = Application.getBackend() instanceof WgQuickBackend ? State.ENABLED : State.DISABLED; + } + + @Override + public CharSequence getSummary() { + return getContext().getString(state.summaryResourceId); + } + + @Override + public CharSequence getTitle() { + return getContext().getString(state.titleResourceId); + } + + @Override + protected void onClick() { + if (state == State.DISABLED) { + setState(State.ENABLING); + Application.getSharedPreferences().edit().putBoolean("disable_kernel_module", false).apply(); + } else if (state == State.ENABLED) { + setState(State.DISABLING); + Application.getSharedPreferences().edit().putBoolean("disable_kernel_module", true).apply(); + } + Application.getAsyncWorker().runAsync(() -> { + Thread.sleep(1000 * 5); + Intent i = getContext().getPackageManager().getLaunchIntentForPackage(getContext().getPackageName()); + if (i == null) + return; + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Application.get().startActivity(i); + System.exit(0); + }); + } + + private void setState(final State state) { + if (this.state == state) + return; + this.state = state; + if (isEnabled() != state.shouldEnableView) + setEnabled(state.shouldEnableView); + notifyChanged(); + } + + private enum State { + ENABLED(R.string.module_disabler_enabled_title, R.string.module_disabler_enabled_summary, true), + DISABLED(R.string.module_disabler_disabled_title, R.string.module_disabler_disabled_summary, true), + ENABLING(R.string.module_disabler_disabled_title, R.string.module_disabler_working, false), + DISABLING(R.string.module_disabler_enabled_title, R.string.module_disabler_working, false); + + private final boolean shouldEnableView; + private final int summaryResourceId; + private final int titleResourceId; + + State(final int titleResourceId, final int summaryResourceId, final boolean shouldEnableView) { + this.summaryResourceId = summaryResourceId; + this.titleResourceId = titleResourceId; + this.shouldEnableView = shouldEnableView; + } + } +} diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 13aa1b6d..71d88930 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -103,6 +103,11 @@ <string name="module_installer_title">Download and install kernel module</string> <string name="module_installer_working">Downloading and installing…</string> <string name="module_installer_error">Something went wrong. Please try again</string> + <string name="module_disabler_disabled_title">Enable kernel module backend</string> + <string name="module_disabler_disabled_summary">The experimental kernel module can improve performance</string> + <string name="module_disabler_enabled_title">Disable kernel module backend</string> + <string name="module_disabler_enabled_summary">The slower userspace backend may improve stability</string> + <string name="module_disabler_working">The application will restart in 5 seconds</string> <string name="mtu">MTU</string> <string name="multiple_tunnels_title">Allow multiple simultaneous tunnels</string> <string name="multiple_tunnels_summary_on">Multiple tunnels may be turned on simultaneously</string> diff --git a/ui/src/main/res/xml/preferences.xml b/ui/src/main/res/xml/preferences.xml index 670c8665..d7955052 100644 --- a/ui/src/main/res/xml/preferences.xml +++ b/ui/src/main/res/xml/preferences.xml @@ -23,4 +23,5 @@ android:summaryOff="@string/dark_theme_summary_off" android:summaryOn="@string/dark_theme_summary_on" android:title="@string/dark_theme_title" /> + <com.wireguard.android.preference.KernelModuleDisablerPreference android:key="kernel_module_disabler" /> </androidx.preference.PreferenceScreen> |