diff --git a/app/src/full/AndroidManifest.xml b/app/src/full/AndroidManifest.xml
index e463b6e6c..4e5849b0d 100644
--- a/app/src/full/AndroidManifest.xml
+++ b/app/src/full/AndroidManifest.xml
@@ -28,9 +28,6 @@
-
finish());
-
- ActionBar ab = getSupportActionBar();
- if (ab != null) {
- ab.setTitle(R.string.settings);
- ab.setDisplayHomeAsUpEnabled(true);
- }
-
- setFloating();
-
- if (savedInstanceState == null) {
- getSupportFragmentManager().beginTransaction().add(R.id.container, new SettingsFragment()).commit();
- }
-
- }
-
- @Override
- public int[] getSubscribedTopics() {
- return new int[] {Topic.RELOAD_ACTIVITY};
- }
-
- @Override
- public void onPublish(int topic, Object[] result) {
- recreate();
- }
-
- public static class SettingsFragment extends PreferenceFragmentCompat
- implements SharedPreferences.OnSharedPreferenceChangeListener,
- Topic.Subscriber, Topic.AutoSubscriber {
-
- private PreferenceScreen prefScreen;
-
- private ListPreference updateChannel, suAccess, autoRes, suNotification,
- requestTimeout, multiuserMode, namespaceMode;
- private MagiskManager mm;
- private PreferenceCategory generalCatagory;
-
- @Override
- public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- setPreferencesFromResource(R.xml.app_settings, rootKey);
- mm = Data.MM();
- prefScreen = getPreferenceScreen();
-
- generalCatagory = (PreferenceCategory) findPreference("general");
- PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
- PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
- Preference hideManager = findPreference("hide");
- Preference restoreManager = findPreference("restore");
- findPreference("clear").setOnPreferenceClickListener((pref) -> {
- mm.prefs.edit().remove(Const.Key.ETAG_KEY).apply();
- mm.repoDB.clearRepo();
- Utils.toast(R.string.repo_cache_cleared, Toast.LENGTH_SHORT);
- return true;
- });
-
- updateChannel = (ListPreference) findPreference(Const.Key.UPDATE_CHANNEL);
- suAccess = (ListPreference) findPreference(Const.Key.ROOT_ACCESS);
- autoRes = (ListPreference) findPreference(Const.Key.SU_AUTO_RESPONSE);
- requestTimeout = (ListPreference) findPreference(Const.Key.SU_REQUEST_TIMEOUT);
- suNotification = (ListPreference) findPreference(Const.Key.SU_NOTIFICATION);
- multiuserMode = (ListPreference) findPreference(Const.Key.SU_MULTIUSER_MODE);
- namespaceMode = (ListPreference) findPreference(Const.Key.SU_MNT_NS);
- SwitchPreference reauth = (SwitchPreference) findPreference(Const.Key.SU_REAUTH);
- SwitchPreference fingerprint = (SwitchPreference) findPreference(Const.Key.SU_FINGERPRINT);
-
- updateChannel.setOnPreferenceChangeListener((p, o) -> {
- String prev =String.valueOf(Data.updateChannel);
- int channel = Integer.parseInt((String) o);
- if (channel == Const.Value.CUSTOM_CHANNEL) {
- View v = LayoutInflater.from(requireActivity()).inflate(R.layout.custom_channel_dialog, null);
- EditText url = v.findViewById(R.id.custom_url);
- url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
- new AlertDialog.Builder(requireActivity())
- .setTitle(R.string.settings_update_custom)
- .setView(v)
- .setPositiveButton(R.string.ok, (d, i) ->
- mm.prefs.edit().putString(Const.Key.CUSTOM_CHANNEL,
- url.getText().toString()).apply())
- .setNegativeButton(R.string.close, (d, i) ->
- mm.prefs.edit().putString(Const.Key.UPDATE_CHANNEL, prev).apply())
- .setOnCancelListener(d ->
- mm.prefs.edit().putString(Const.Key.UPDATE_CHANNEL, prev).apply())
- .show();
- }
- return true;
- });
-
- setSummary();
-
- // Disable dangerous settings in secondary user
- if (Const.USER_ID > 0) {
- suCategory.removePreference(multiuserMode);
- }
-
- // Disable re-authentication option on Android O, it will not work
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- reauth.setEnabled(false);
- reauth.setChecked(false);
- reauth.setSummary(R.string.android_o_not_support);
- }
-
- // Disable fingerprint option if not possible
- if (!FingerprintHelper.canUseFingerprint()) {
- fingerprint.setEnabled(false);
- fingerprint.setChecked(false);
- fingerprint.setSummary(R.string.disable_fingerprint);
- }
-
- if (Data.magiskVersionCode >= Const.MAGISK_VER.MANAGER_HIDE) {
- if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
- hideManager.setOnPreferenceClickListener((pref) -> {
- PatchAPK.hideManager(requireActivity());
- return true;
- });
- generalCatagory.removePreference(restoreManager);
- } else {
- if (Download.checkNetworkStatus(mm)) {
- restoreManager.setOnPreferenceClickListener((pref) -> {
- Download.receive(
- requireActivity(), new DownloadReceiver() {
- @Override
- public void onDownloadDone(Context context, Uri uri) {
- Data.exportPrefs();
- Shell.su("cp " + uri.getPath() + " /data/local/tmp/manager.apk").exec();
- if (ShellUtils.fastCmdResult("pm install /data/local/tmp/manager.apk")) {
- Shell.su("rm -f /data/local/tmp/manager.apk").exec();
- RootUtils.uninstallPkg(context.getPackageName());
- return;
- }
- Shell.su("rm -f /data/local/tmp/manager.apk").exec();
- }
- },
- Data.managerLink,
- Utils.fmt("MagiskManager-v%s.apk", Data.remoteManagerVersionString)
- );
- return true;
- });
- } else {
- generalCatagory.removePreference(restoreManager);
- }
- generalCatagory.removePreference(hideManager);
- }
- } else {
- generalCatagory.removePreference(restoreManager);
- generalCatagory.removePreference(hideManager);
- }
-
- if (!Shell.rootAccess() || (Const.USER_ID > 0 &&
- Data.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
- prefScreen.removePreference(suCategory);
- }
-
- if (!Shell.rootAccess()) {
- prefScreen.removePreference(magiskCategory);
- generalCatagory.removePreference(hideManager);
- } else if (Data.magiskVersionCode < Const.MAGISK_VER.UNIFIED) {
- prefScreen.removePreference(magiskCategory);
- }
- }
-
- private void setLocalePreference(ListPreference lp) {
- CharSequence[] entries = new CharSequence[LocaleManager.locales.size() + 1];
- CharSequence[] entryValues = new CharSequence[LocaleManager.locales.size() + 1];
- entries[0] = LocaleManager.getString(LocaleManager.defaultLocale, R.string.system_default);
- entryValues[0] = "";
- int i = 1;
- for (Locale locale : LocaleManager.locales) {
- entries[i] = locale.getDisplayName(locale);
- entryValues[i++] = locale.toLanguageTag();
- }
- lp.setEntries(entries);
- lp.setEntryValues(entryValues);
- lp.setSummary(LocaleManager.locale.getDisplayName(LocaleManager.locale));
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mm.prefs.registerOnSharedPreferenceChangeListener(this);
- Topic.subscribe(this);
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- @Override
- public void onDestroyView() {
- mm.prefs.unregisterOnSharedPreferenceChangeListener(this);
- Topic.unsubscribe(this);
- super.onDestroyView();
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- switch (key) {
- case Const.Key.ROOT_ACCESS:
- case Const.Key.SU_MULTIUSER_MODE:
- case Const.Key.SU_MNT_NS:
- mm.mDB.setSettings(key, Utils.getPrefsInt(prefs, key));
- break;
- }
- Data.loadConfig();
- setSummary();
- switch (key) {
- case Const.Key.DARK_THEME:
- Topic.publish(false, Topic.RELOAD_ACTIVITY);
- break;
- case Const.Key.COREONLY:
- if (prefs.getBoolean(key, false)) {
- try {
- Const.MAGISK_DISABLE_FILE.createNewFile();
- } catch (IOException ignored) {}
- } else {
- Const.MAGISK_DISABLE_FILE.delete();
- }
- Utils.toast(R.string.settings_reboot_toast, Toast.LENGTH_LONG);
- break;
- case Const.Key.MAGISKHIDE:
- if (prefs.getBoolean(key, false)) {
- Shell.su("magiskhide --enable").submit();
- } else {
- Shell.su("magiskhide --disable").submit();
- }
- break;
- case Const.Key.HOSTS:
- if (prefs.getBoolean(key, false)) {
- Shell.su("cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE,
- "mount -o bind " + Const.MAGISK_HOST_FILE + " /system/etc/hosts")
- .submit();
- } else {
- Shell.su("umount -l /system/etc/hosts",
- "rm -f " + Const.MAGISK_HOST_FILE)
- .submit();
- }
- break;
- case Const.Key.LOCALE:
- LocaleManager.setLocale(mm);
- Topic.publish(false, Topic.RELOAD_ACTIVITY);
- break;
- case Const.Key.UPDATE_CHANNEL:
- case Const.Key.CUSTOM_CHANNEL:
- CheckUpdates.check();
- break;
- case Const.Key.CHECK_UPDATES:
- Utils.setupUpdateCheck();
- break;
- }
- }
-
- @Override
- public boolean onPreferenceTreeClick(Preference preference) {
- String key = preference.getKey();
- switch (key) {
- case Const.Key.SU_FINGERPRINT:
- boolean checked = ((SwitchPreference) preference).isChecked();
- ((SwitchPreference) preference).setChecked(!checked);
- CustomAlertDialog dialog = new CustomAlertDialog(requireActivity());
- CustomAlertDialog.ViewHolder vh = dialog.getViewHolder();
- Drawable fingerprint = getResources().getDrawable(R.drawable.ic_fingerprint);
- fingerprint.setBounds(0, 0, Utils.dpInPx(50), Utils.dpInPx(50));
- Resources.Theme theme = requireActivity().getTheme();
- TypedArray ta = theme.obtainStyledAttributes(new int[] {R.attr.imageColorTint});
- fingerprint.setTint(ta.getColor(0, Color.GRAY));
- ta.recycle();
- vh.messageView.setCompoundDrawables(null, null, null, fingerprint);
- vh.messageView.setCompoundDrawablePadding(Utils.dpInPx(20));
- vh.messageView.setGravity(Gravity.CENTER);
- try {
- FingerprintHelper helper = new FingerprintHelper() {
- @Override
- public void onAuthenticationError(int errorCode, CharSequence errString) {
- vh.messageView.setTextColor(Color.RED);
- vh.messageView.setText(errString);
- }
-
- @Override
- public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
- vh.messageView.setTextColor(Color.RED);
- vh.messageView.setText(helpString);
- }
-
- @Override
- public void onAuthenticationFailed() {
- vh.messageView.setTextColor(Color.RED);
- vh.messageView.setText(R.string.auth_fail);
- }
-
- @Override
- public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
- dialog.dismiss();
- ((SwitchPreference) preference).setChecked(checked);
- mm.mDB.setSettings(key, checked ? 1 : 0);
-
- }
- };
- dialog.setMessage(R.string.auth_fingerprint)
- .setNegativeButton(R.string.close, (d, w) -> helper.cancel())
- .setOnCancelListener(d -> helper.cancel())
- .show();
- helper.authenticate();
- } catch (Exception e) {
- e.printStackTrace();
- Utils.toast(R.string.auth_fail, Toast.LENGTH_SHORT);
- }
- break;
- }
- return true;
- }
-
- private void setSummary() {
- updateChannel.setSummary(getResources()
- .getStringArray(R.array.update_channel)[Data.updateChannel]);
- suAccess.setSummary(getResources()
- .getStringArray(R.array.su_access)[Data.suAccessState]);
- autoRes.setSummary(getResources()
- .getStringArray(R.array.auto_response)[Data.suResponseType]);
- suNotification.setSummary(getResources()
- .getStringArray(R.array.su_notification)[Data.suNotificationType]);
- requestTimeout.setSummary(
- getString(R.string.request_timeout_summary,
- mm.prefs.getString(Const.Key.SU_REQUEST_TIMEOUT, "10")));
- multiuserMode.setSummary(getResources()
- .getStringArray(R.array.multiuser_summary)[Data.multiuserMode]);
- namespaceMode.setSummary(getResources()
- .getStringArray(R.array.namespace_summary)[Data.suNamespaceMode]);
- }
-
- @Override
- public void onPublish(int topic, Object[] result) {
- setLocalePreference((ListPreference) findPreference(Const.Key.LOCALE));
- }
-
- @Override
- public int[] getSubscribedTopics() {
- return new int[] {Topic.LOCALE_FETCH_DONE};
- }
- }
-
-}
diff --git a/app/src/full/java/com/topjohnwu/magisk/SettingsFragment.java b/app/src/full/java/com/topjohnwu/magisk/SettingsFragment.java
new file mode 100644
index 000000000..789287169
--- /dev/null
+++ b/app/src/full/java/com/topjohnwu/magisk/SettingsFragment.java
@@ -0,0 +1,351 @@
+package com.topjohnwu.magisk;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.hardware.fingerprint.FingerprintManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceFragmentCompat;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.topjohnwu.magisk.asyncs.CheckUpdates;
+import com.topjohnwu.magisk.asyncs.PatchAPK;
+import com.topjohnwu.magisk.components.CustomAlertDialog;
+import com.topjohnwu.magisk.receivers.DownloadReceiver;
+import com.topjohnwu.magisk.utils.Download;
+import com.topjohnwu.magisk.utils.FingerprintHelper;
+import com.topjohnwu.magisk.utils.LocaleManager;
+import com.topjohnwu.magisk.utils.RootUtils;
+import com.topjohnwu.magisk.utils.Topic;
+import com.topjohnwu.magisk.utils.Utils;
+import com.topjohnwu.superuser.Shell;
+import com.topjohnwu.superuser.ShellUtils;
+
+import java.io.IOException;
+import java.util.Locale;
+
+public class SettingsFragment extends PreferenceFragmentCompat
+ implements SharedPreferences.OnSharedPreferenceChangeListener,
+ Topic.Subscriber, Topic.AutoSubscriber {
+
+ private PreferenceScreen prefScreen;
+
+ private ListPreference updateChannel, suAccess, autoRes, suNotification,
+ requestTimeout, multiuserMode, namespaceMode;
+ private MagiskManager mm;
+ private PreferenceCategory generalCatagory;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.app_settings, rootKey);
+ mm = Data.MM();
+ prefScreen = getPreferenceScreen();
+
+ generalCatagory = (PreferenceCategory) findPreference("general");
+ PreferenceCategory magiskCategory = (PreferenceCategory) findPreference("magisk");
+ PreferenceCategory suCategory = (PreferenceCategory) findPreference("superuser");
+ Preference hideManager = findPreference("hide");
+ Preference restoreManager = findPreference("restore");
+ findPreference("clear").setOnPreferenceClickListener((pref) -> {
+ mm.prefs.edit().remove(Const.Key.ETAG_KEY).apply();
+ mm.repoDB.clearRepo();
+ Utils.toast(R.string.repo_cache_cleared, Toast.LENGTH_SHORT);
+ return true;
+ });
+
+ updateChannel = (ListPreference) findPreference(Const.Key.UPDATE_CHANNEL);
+ suAccess = (ListPreference) findPreference(Const.Key.ROOT_ACCESS);
+ autoRes = (ListPreference) findPreference(Const.Key.SU_AUTO_RESPONSE);
+ requestTimeout = (ListPreference) findPreference(Const.Key.SU_REQUEST_TIMEOUT);
+ suNotification = (ListPreference) findPreference(Const.Key.SU_NOTIFICATION);
+ multiuserMode = (ListPreference) findPreference(Const.Key.SU_MULTIUSER_MODE);
+ namespaceMode = (ListPreference) findPreference(Const.Key.SU_MNT_NS);
+ SwitchPreference reauth = (SwitchPreference) findPreference(Const.Key.SU_REAUTH);
+ SwitchPreference fingerprint = (SwitchPreference) findPreference(Const.Key.SU_FINGERPRINT);
+
+ updateChannel.setOnPreferenceChangeListener((p, o) -> {
+ String prev =String.valueOf(Data.updateChannel);
+ int channel = Integer.parseInt((String) o);
+ if (channel == Const.Value.CUSTOM_CHANNEL) {
+ View v = LayoutInflater.from(requireActivity()).inflate(R.layout.custom_channel_dialog, null);
+ EditText url = v.findViewById(R.id.custom_url);
+ url.setText(mm.prefs.getString(Const.Key.CUSTOM_CHANNEL, ""));
+ new AlertDialog.Builder(requireActivity())
+ .setTitle(R.string.settings_update_custom)
+ .setView(v)
+ .setPositiveButton(R.string.ok, (d, i) ->
+ mm.prefs.edit().putString(Const.Key.CUSTOM_CHANNEL,
+ url.getText().toString()).apply())
+ .setNegativeButton(R.string.close, (d, i) ->
+ mm.prefs.edit().putString(Const.Key.UPDATE_CHANNEL, prev).apply())
+ .setOnCancelListener(d ->
+ mm.prefs.edit().putString(Const.Key.UPDATE_CHANNEL, prev).apply())
+ .show();
+ }
+ return true;
+ });
+
+ setSummary();
+
+ // Disable dangerous settings in secondary user
+ if (Const.USER_ID > 0) {
+ suCategory.removePreference(multiuserMode);
+ }
+
+ // Disable re-authentication option on Android O, it will not work
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ reauth.setEnabled(false);
+ reauth.setChecked(false);
+ reauth.setSummary(R.string.android_o_not_support);
+ }
+
+ // Disable fingerprint option if not possible
+ if (!FingerprintHelper.canUseFingerprint()) {
+ fingerprint.setEnabled(false);
+ fingerprint.setChecked(false);
+ fingerprint.setSummary(R.string.disable_fingerprint);
+ }
+
+ if (Data.magiskVersionCode >= Const.MAGISK_VER.MANAGER_HIDE) {
+ if (mm.getPackageName().equals(Const.ORIG_PKG_NAME)) {
+ hideManager.setOnPreferenceClickListener((pref) -> {
+ PatchAPK.hideManager(requireActivity());
+ return true;
+ });
+ generalCatagory.removePreference(restoreManager);
+ } else {
+ if (Download.checkNetworkStatus(mm)) {
+ restoreManager.setOnPreferenceClickListener((pref) -> {
+ Download.receive(
+ requireActivity(), new DownloadReceiver() {
+ @Override
+ public void onDownloadDone(Context context, Uri uri) {
+ Data.exportPrefs();
+ Shell.su("cp " + uri.getPath() + " /data/local/tmp/manager.apk").exec();
+ if (ShellUtils.fastCmdResult("pm install /data/local/tmp/manager.apk")) {
+ Shell.su("rm -f /data/local/tmp/manager.apk").exec();
+ RootUtils.uninstallPkg(context.getPackageName());
+ return;
+ }
+ Shell.su("rm -f /data/local/tmp/manager.apk").exec();
+ }
+ },
+ Data.managerLink,
+ Utils.fmt("MagiskManager-v%s.apk", Data.remoteManagerVersionString)
+ );
+ return true;
+ });
+ } else {
+ generalCatagory.removePreference(restoreManager);
+ }
+ generalCatagory.removePreference(hideManager);
+ }
+ } else {
+ generalCatagory.removePreference(restoreManager);
+ generalCatagory.removePreference(hideManager);
+ }
+
+ if (!Shell.rootAccess() || (Const.USER_ID > 0 &&
+ Data.multiuserMode == Const.Value.MULTIUSER_MODE_OWNER_MANAGED)) {
+ prefScreen.removePreference(suCategory);
+ }
+
+ if (!Shell.rootAccess()) {
+ prefScreen.removePreference(magiskCategory);
+ generalCatagory.removePreference(hideManager);
+ } else if (Data.magiskVersionCode < Const.MAGISK_VER.UNIFIED) {
+ prefScreen.removePreference(magiskCategory);
+ }
+ }
+
+ private void setLocalePreference(ListPreference lp) {
+ CharSequence[] entries = new CharSequence[LocaleManager.locales.size() + 1];
+ CharSequence[] entryValues = new CharSequence[LocaleManager.locales.size() + 1];
+ entries[0] = LocaleManager.getString(LocaleManager.defaultLocale, R.string.system_default);
+ entryValues[0] = "";
+ int i = 1;
+ for (Locale locale : LocaleManager.locales) {
+ entries[i] = locale.getDisplayName(locale);
+ entryValues[i++] = locale.toLanguageTag();
+ }
+ lp.setEntries(entries);
+ lp.setEntryValues(entryValues);
+ lp.setSummary(LocaleManager.locale.getDisplayName(LocaleManager.locale));
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ mm.prefs.registerOnSharedPreferenceChangeListener(this);
+ Topic.subscribe(this);
+ requireActivity().setTitle(R.string.settings);
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @Override
+ public void onDestroyView() {
+ mm.prefs.unregisterOnSharedPreferenceChangeListener(this);
+ Topic.unsubscribe(this);
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ switch (key) {
+ case Const.Key.ROOT_ACCESS:
+ case Const.Key.SU_MULTIUSER_MODE:
+ case Const.Key.SU_MNT_NS:
+ mm.mDB.setSettings(key, Utils.getPrefsInt(prefs, key));
+ break;
+ }
+ Data.loadConfig();
+ setSummary();
+ switch (key) {
+ case Const.Key.DARK_THEME:
+ Topic.publish(false, Topic.RELOAD_ACTIVITY);
+ break;
+ case Const.Key.COREONLY:
+ if (prefs.getBoolean(key, false)) {
+ try {
+ Const.MAGISK_DISABLE_FILE.createNewFile();
+ } catch (IOException ignored) {}
+ } else {
+ Const.MAGISK_DISABLE_FILE.delete();
+ }
+ Utils.toast(R.string.settings_reboot_toast, Toast.LENGTH_LONG);
+ break;
+ case Const.Key.MAGISKHIDE:
+ if (prefs.getBoolean(key, false)) {
+ Shell.su("magiskhide --enable").submit();
+ } else {
+ Shell.su("magiskhide --disable").submit();
+ }
+ break;
+ case Const.Key.HOSTS:
+ if (prefs.getBoolean(key, false)) {
+ Shell.su("cp -af /system/etc/hosts " + Const.MAGISK_HOST_FILE,
+ "mount -o bind " + Const.MAGISK_HOST_FILE + " /system/etc/hosts")
+ .submit();
+ } else {
+ Shell.su("umount -l /system/etc/hosts",
+ "rm -f " + Const.MAGISK_HOST_FILE)
+ .submit();
+ }
+ break;
+ case Const.Key.LOCALE:
+ LocaleManager.setLocale(mm);
+ Topic.publish(false, Topic.RELOAD_ACTIVITY);
+ break;
+ case Const.Key.UPDATE_CHANNEL:
+ case Const.Key.CUSTOM_CHANNEL:
+ CheckUpdates.check();
+ break;
+ case Const.Key.CHECK_UPDATES:
+ Utils.setupUpdateCheck();
+ break;
+ }
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(Preference preference) {
+ String key = preference.getKey();
+ switch (key) {
+ case Const.Key.SU_FINGERPRINT:
+ boolean checked = ((SwitchPreference) preference).isChecked();
+ ((SwitchPreference) preference).setChecked(!checked);
+ CustomAlertDialog dialog = new CustomAlertDialog(requireActivity());
+ CustomAlertDialog.ViewHolder vh = dialog.getViewHolder();
+ Drawable fingerprint = getResources().getDrawable(R.drawable.ic_fingerprint);
+ fingerprint.setBounds(0, 0, Utils.dpInPx(50), Utils.dpInPx(50));
+ Resources.Theme theme = requireActivity().getTheme();
+ TypedArray ta = theme.obtainStyledAttributes(new int[] {R.attr.imageColorTint});
+ fingerprint.setTint(ta.getColor(0, Color.GRAY));
+ ta.recycle();
+ vh.messageView.setCompoundDrawables(null, null, null, fingerprint);
+ vh.messageView.setCompoundDrawablePadding(Utils.dpInPx(20));
+ vh.messageView.setGravity(Gravity.CENTER);
+ try {
+ FingerprintHelper helper = new FingerprintHelper() {
+ @Override
+ public void onAuthenticationError(int errorCode, CharSequence errString) {
+ vh.messageView.setTextColor(Color.RED);
+ vh.messageView.setText(errString);
+ }
+
+ @Override
+ public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
+ vh.messageView.setTextColor(Color.RED);
+ vh.messageView.setText(helpString);
+ }
+
+ @Override
+ public void onAuthenticationFailed() {
+ vh.messageView.setTextColor(Color.RED);
+ vh.messageView.setText(R.string.auth_fail);
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+ dialog.dismiss();
+ ((SwitchPreference) preference).setChecked(checked);
+ mm.mDB.setSettings(key, checked ? 1 : 0);
+
+ }
+ };
+ dialog.setMessage(R.string.auth_fingerprint)
+ .setNegativeButton(R.string.close, (d, w) -> helper.cancel())
+ .setOnCancelListener(d -> helper.cancel())
+ .show();
+ helper.authenticate();
+ } catch (Exception e) {
+ e.printStackTrace();
+ Utils.toast(R.string.auth_fail, Toast.LENGTH_SHORT);
+ }
+ break;
+ }
+ return true;
+ }
+
+ private void setSummary() {
+ updateChannel.setSummary(getResources()
+ .getStringArray(R.array.update_channel)[Data.updateChannel]);
+ suAccess.setSummary(getResources()
+ .getStringArray(R.array.su_access)[Data.suAccessState]);
+ autoRes.setSummary(getResources()
+ .getStringArray(R.array.auto_response)[Data.suResponseType]);
+ suNotification.setSummary(getResources()
+ .getStringArray(R.array.su_notification)[Data.suNotificationType]);
+ requestTimeout.setSummary(
+ getString(R.string.request_timeout_summary,
+ mm.prefs.getString(Const.Key.SU_REQUEST_TIMEOUT, "10")));
+ multiuserMode.setSummary(getResources()
+ .getStringArray(R.array.multiuser_summary)[Data.multiuserMode]);
+ namespaceMode.setSummary(getResources()
+ .getStringArray(R.array.namespace_summary)[Data.suNamespaceMode]);
+ }
+
+ @Override
+ public void onPublish(int topic, Object[] result) {
+ setLocalePreference((ListPreference) findPreference(Const.Key.LOCALE));
+ }
+
+ @Override
+ public int[] getSubscribedTopics() {
+ return new int[] {Topic.LOCALE_FETCH_DONE};
+ }
+}
diff --git a/app/src/full/res/layout/activity_main.xml b/app/src/full/res/layout/activity_main.xml
index 9ac55384f..82154d459 100644
--- a/app/src/full/res/layout/activity_main.xml
+++ b/app/src/full/res/layout/activity_main.xml
@@ -15,6 +15,7 @@
android:orientation="vertical">
diff --git a/app/src/full/res/layout/fragment_log.xml b/app/src/full/res/layout/fragment_log.xml
index 370b3c64e..cb028035e 100644
--- a/app/src/full/res/layout/fragment_log.xml
+++ b/app/src/full/res/layout/fragment_log.xml
@@ -5,7 +5,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:layout_marginTop="?attr/actionBarSize"
tools:context="com.topjohnwu.magisk.LogFragment">
+ android:layout_height="wrap_content">
-
@@ -13,7 +13,6 @@
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="?attr/actionBarSize"
android:orientation="vertical">
diff --git a/app/src/full/res/layout/fragment_superuser.xml b/app/src/full/res/layout/fragment_superuser.xml
index 55a4dd234..1092c5b0f 100644
--- a/app/src/full/res/layout/fragment_superuser.xml
+++ b/app/src/full/res/layout/fragment_superuser.xml
@@ -2,7 +2,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
- android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent">
diff --git a/app/src/full/res/menu/drawer.xml b/app/src/full/res/menu/drawer.xml
index 14603a710..4d44c765a 100644
--- a/app/src/full/res/menu/drawer.xml
+++ b/app/src/full/res/menu/drawer.xml
@@ -46,8 +46,8 @@
android:id="@+id/log"
android:icon="@drawable/ic_bug_report"
android:title="@string/log" />
+
diff --git a/app/src/full/res/xml/app_settings.xml b/app/src/full/res/xml/app_settings.xml
index 975e7d58e..077b848c6 100644
--- a/app/src/full/res/xml/app_settings.xml
+++ b/app/src/full/res/xml/app_settings.xml
@@ -1,5 +1,4 @@