Fix Error reporting and update libraries.

pull/195/head
Fox2Code 2 years ago
parent bcc988a555
commit df166d7747

@ -83,8 +83,6 @@ configurations {
} }
dependencies { dependencies {
// Error reporting
implementation 'io.sentry:sentry-android:6.4.0'
// UI // UI
implementation 'androidx.appcompat:appcompat:1.5.0' implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.emoji2:emoji2:1.2.0' implementation 'androidx.emoji2:emoji2:1.2.0'
@ -100,16 +98,20 @@ dependencies {
implementation "dev.rikka.rikkax.insets:insets:1.3.0" implementation "dev.rikka.rikkax.insets:insets:1.3.0"
implementation 'com.github.Dimezis:BlurView:version-1.6.6' implementation 'com.github.Dimezis:BlurView:version-1.6.6'
implementation 'com.github.KieronQuinn:MonetCompat:0.4.1' implementation 'com.github.KieronQuinn:MonetCompat:0.4.1'
implementation 'com.github.Fox2Code:FoxCompat:0.1.0' implementation 'com.github.Fox2Code:FoxCompat:0.1.2'
// Utils // Utils
implementation 'androidx.work:work-runtime:2.7.1' implementation 'androidx.work:work-runtime:2.7.1'
implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.3' implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:4.9.3'
implementation 'com.squareup.okhttp3:okhttp-brotli:4.9.3' implementation 'com.squareup.okhttp3:okhttp-brotli:4.9.3'
implementation 'com.github.topjohnwu.libsu:io:5.0.1' implementation 'com.github.topjohnwu.libsu:io:5.0.1'
implementation 'com.github.Fox2Code:RosettaX:1.0.8' implementation 'com.github.Fox2Code:RosettaX:1.0.9'
implementation 'com.github.Fox2Code:AndroidANSI:1.0.1' implementation 'com.github.Fox2Code:AndroidANSI:1.0.1'
// Error reporting
implementation 'io.sentry:sentry-android:6.4.0'
implementation 'io.sentry:sentry-android-fragment:6.4.0'
// Markdown // Markdown
implementation "io.noties.markwon:core:4.6.2" implementation "io.noties.markwon:core:4.6.2"
implementation "io.noties.markwon:html:4.6.2" implementation "io.noties.markwon:html:4.6.2"

@ -74,23 +74,23 @@
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"> tools:ignore="LockedOrientationActivity">
<intent-filter> <!-- <intent-filter>
<action android:name="${applicationId}.intent.action.INSTALL_MODULE_INTERNAL" /> <action android:name="${applicationId}.intent.action.INSTALL_MODULE_INTERNAL" />
</intent-filter> </intent-filter> -->
</activity> </activity>
<activity <activity
android:name=".markdown.MarkdownActivity" android:name=".markdown.MarkdownActivity"
android:exported="false" android:exported="false"
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:theme="@style/Theme.MagiskModuleManager"></activity> android:theme="@style/Theme.MagiskModuleManager" />
<activity <activity
android:name=".androidacy.AndroidacyActivity" android:name=".androidacy.AndroidacyActivity"
android:exported="false" android:exported="false"
android:parentActivityName=".MainActivity" android:parentActivityName=".MainActivity"
android:theme="@style/Theme.MagiskModuleManager"> android:theme="@style/Theme.MagiskModuleManager">
<intent-filter> <!-- <intent-filter>
<action android:name="${applicationId}.intent.action.OPEN_ANDROIDACY_INTERNAL" /> <action android:name="${applicationId}.intent.action.OPEN_ANDROIDACY_INTERNAL" />
</intent-filter> </intent-filter> -->
</activity> </activity>
<activity <activity
android:name="com.mikepenz.aboutlibraries.ui.LibsActivity" android:name="com.mikepenz.aboutlibraries.ui.LibsActivity"

@ -9,6 +9,8 @@ import android.content.res.Resources;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build; import android.os.Build;
import android.os.SystemClock; import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.Os;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.util.Log; import android.util.Log;
@ -21,6 +23,7 @@ import androidx.emoji2.text.FontRequestEmojiCompatConfig;
import com.fox2code.foxcompat.FoxActivity; import com.fox2code.foxcompat.FoxActivity;
import com.fox2code.foxcompat.FoxApplication; import com.fox2code.foxcompat.FoxApplication;
import com.fox2code.foxcompat.FoxThemeWrapper; import com.fox2code.foxcompat.FoxThemeWrapper;
import com.fox2code.foxcompat.internal.FoxProcessExt;
import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.installer.InstallerInitializer;
import com.fox2code.mmm.utils.GMSProviderInstaller; import com.fox2code.mmm.utils.GMSProviderInstaller;
import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.Http;
@ -46,7 +49,10 @@ import io.noties.prism4j.Prism4j;
import io.noties.prism4j.annotations.PrismBundle; import io.noties.prism4j.annotations.PrismBundle;
import io.sentry.JsonObjectWriter; import io.sentry.JsonObjectWriter;
import io.sentry.NoOpLogger; import io.sentry.NoOpLogger;
import io.sentry.TypeCheckHint;
import io.sentry.UncaughtExceptionHandlerIntegration;
import io.sentry.android.core.SentryAndroid; import io.sentry.android.core.SentryAndroid;
import io.sentry.hints.DiskFlushNotification;
@PrismBundle( @PrismBundle(
includeAll = true, includeAll = true,
@ -62,7 +68,10 @@ public class MainApplication extends FoxApplication
new SimpleDateFormat(timeFormatString, timeFormatLocale); new SimpleDateFormat(timeFormatString, timeFormatLocale);
private static final Shell.Builder shellBuilder; private static final Shell.Builder shellBuilder;
private static final long secret; private static final long secret;
@SuppressLint("RestrictedApi") // Use FoxProcess wrapper helper.
private static final boolean wrapped = !FoxProcessExt.isRootLoader();
private static SharedPreferences bootSharedPreferences; private static SharedPreferences bootSharedPreferences;
private static String relPackageName = BuildConfig.APPLICATION_ID;
private static MainApplication INSTANCE; private static MainApplication INSTANCE;
private static boolean firstBoot; private static boolean firstBoot;
@ -88,13 +97,20 @@ public class MainApplication extends FoxApplication
ComponentName componentName = intent.getComponent(); ComponentName componentName = intent.getComponent();
String packageName = componentName != null ? String packageName = componentName != null ?
componentName.getPackageName() : intent.getPackage(); componentName.getPackageName() : intent.getPackage();
if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(packageName)) { if (!BuildConfig.APPLICATION_ID.equalsIgnoreCase(packageName) &&
!relPackageName.equals(packageName)) {
// Code safeguard, we should never reach here. // Code safeguard, we should never reach here.
throw new IllegalArgumentException("Can't add secret to outbound Intent"); throw new IllegalArgumentException("Can't add secret to outbound Intent");
} }
intent.putExtra("secret", secret); intent.putExtra("secret", secret);
} }
// Is application wrapped, and therefore must reduce it's feature set.
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isWrapped() {
return wrapped;
}
public static boolean checkSecret(Intent intent) { public static boolean checkSecret(Intent intent) {
return intent != null && intent.getLongExtra("secret", ~secret) == secret; return intent != null && intent.getLongExtra("secret", ~secret) == secret;
} }
@ -154,7 +170,7 @@ public class MainApplication extends FoxApplication
} }
public static boolean isBackgroundUpdateCheckEnabled() { public static boolean isBackgroundUpdateCheckEnabled() {
return getSharedPreferences().getBoolean("pref_background_update_check", true); return !wrapped && getSharedPreferences().getBoolean("pref_background_update_check", true);
} }
public static boolean isAndroidacyTestMode() { public static boolean isAndroidacyTestMode() {
@ -175,8 +191,8 @@ public class MainApplication extends FoxApplication
} }
public static boolean isCrashReportingEnabled() { public static boolean isCrashReportingEnabled() {
return getSharedPreferences().getBoolean( return getSharedPreferences().getBoolean("pref_crash_reporting",
"crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING); BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING && !BuildConfig.DEBUG);
} }
public static SharedPreferences getBootSharedPreferences() { public static SharedPreferences getBootSharedPreferences() {
@ -310,6 +326,7 @@ public class MainApplication extends FoxApplication
@Override @Override
public void onCreate() { public void onCreate() {
if (INSTANCE == null) INSTANCE = this; if (INSTANCE == null) INSTANCE = this;
relPackageName = this.getPackageName();
super.onCreate(); super.onCreate();
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
DynamicColors.applyToActivitiesIfAvailable(this, DynamicColors.applyToActivitiesIfAvailable(this,
@ -352,6 +369,7 @@ public class MainApplication extends FoxApplication
Log.d("MainApplication", "Emoji compat loaded!"); Log.d("MainApplication", "Emoji compat loaded!");
}, "Emoji compat init.").start(); }, "Emoji compat init.").start();
} }
SentryAndroid.init(this, options -> { SentryAndroid.init(this, options -> {
// Note: Sentry library only take a screenshot of Fox Magisk Module Manager. // Note: Sentry library only take a screenshot of Fox Magisk Module Manager.
// The screen shot doesn't and cannot contain other applications (if in multi windows) // The screen shot doesn't and cannot contain other applications (if in multi windows)
@ -361,6 +379,8 @@ public class MainApplication extends FoxApplication
// it's a serious bug and a security issue you should report to Google // it's a serious bug and a security issue you should report to Google
// Google bug bounties on Android are huge, so you can also get rich by doing that. // Google bug bounties on Android are huge, so you can also get rich by doing that.
options.setAttachScreenshot(true); options.setAttachScreenshot(true);
// User interaction tracing is not needed to get context of crash
options.setEnableUserInteractionTracing(false);
// Add a callback that will be used before the event is sent to Sentry. // Add a callback that will be used before the event is sent to Sentry.
// With this callback, you can modify the event or, when returning null, also discard the event. // With this callback, you can modify the event or, when returning null, also discard the event.
options.setBeforeSend((event, hint) -> { options.setBeforeSend((event, hint) -> {
@ -373,6 +393,11 @@ public class MainApplication extends FoxApplication
stringBuilder.append(cbuf); stringBuilder.append(cbuf);
} }
@Override
public void write(String str) {
stringBuilder.append(str);
}
@Override @Override
public void write(char[] chars, int i, int i1) { public void write(char[] chars, int i, int i1) {
stringBuilder.append(chars, i, i1); stringBuilder.append(chars, i, i1);
@ -399,6 +424,10 @@ public class MainApplication extends FoxApplication
return event; return event;
} else { } else {
Log.i(TAG, "Blocked sentry report according to user preference"); Log.i(TAG, "Blocked sentry report according to user preference");
// We need to do this to avoid crash delay on crash when the event is dropped
DiskFlushNotification diskFlushNotification = hint.getAs(
TypeCheckHint.SENTRY_TYPE_CHECK_HINT, DiskFlushNotification.class);
if (diskFlushNotification != null) diskFlushNotification.markFlushed();
return null; return null;
} }
}); });

@ -2,6 +2,7 @@ package com.fox2code.mmm.settings;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.AlarmManager; import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -32,6 +33,7 @@ import androidx.preference.TwoStatePreference;
import com.fox2code.foxcompat.FoxActivity; import com.fox2code.foxcompat.FoxActivity;
import com.fox2code.foxcompat.FoxDisplay; import com.fox2code.foxcompat.FoxDisplay;
import com.fox2code.foxcompat.FoxViewCompat; import com.fox2code.foxcompat.FoxViewCompat;
import com.fox2code.foxcompat.internal.FoxProcessExt;
import com.fox2code.mmm.AppUpdateManager; import com.fox2code.mmm.AppUpdateManager;
import com.fox2code.mmm.BuildConfig; import com.fox2code.mmm.BuildConfig;
import com.fox2code.mmm.Constants; import com.fox2code.mmm.Constants;
@ -67,6 +69,7 @@ import java.util.Random;
public class SettingsActivity extends FoxActivity implements LanguageActivity { public class SettingsActivity extends FoxActivity implements LanguageActivity {
private static final int LANGUAGE_SUPPORT_LEVEL = 1; private static final int LANGUAGE_SUPPORT_LEVEL = 1;
private static final String TAG = "SettingsActivity"; private static final String TAG = "SettingsActivity";
private static boolean devModeStepFirstBootIgnore = false;
private static int devModeStep = 0; private static int devModeStep = 0;
@Override @Override
@ -88,7 +91,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
Intent mStartActivity = new Intent(this, MainActivity.class); Intent mStartActivity = new Intent(this, MainActivity.class);
mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
int mPendingIntentId = 123456; int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId,
mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0); // Exit app process System.exit(0); // Exit app process
@ -115,14 +119,15 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
themePreference.setSummaryProvider(p -> themePreference.getEntry()); themePreference.setSummaryProvider(p -> themePreference.getEntry());
themePreference.setOnPreferenceClickListener(p -> { themePreference.setOnPreferenceClickListener(p -> {
// You need to reboot your device at least once to be able to access dev-mode // You need to reboot your device at least once to be able to access dev-mode
if (!MainApplication.isFirstBoot()) devModeStep = 1; if (devModeStepFirstBootIgnore || !MainApplication.isFirstBoot()) devModeStep = 1;
return false; return false;
}); });
themePreference.setOnPreferenceChangeListener((preference, newValue) -> { themePreference.setOnPreferenceChangeListener((preference, newValue) -> {
devModeStep = 0; devModeStep = 0;
UiThreadHandler.handler.postDelayed(() -> { UiThreadHandler.handler.postDelayed(() -> {
MainApplication.getINSTANCE().updateTheme(); MainApplication.getINSTANCE().updateTheme();
FoxActivity.getFoxActivity(this).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId()); FoxActivity.getFoxActivity(this).setThemeRecreate(
MainApplication.getINSTANCE().getManagerThemeResId());
}, 1); }, 1);
return true; return true;
}); });
@ -130,8 +135,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting"); TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting");
crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled()); crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled());
crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> { crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> {
devModeStepFirstBootIgnore = true;
devModeStep = 0; devModeStep = 0;
getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", (boolean) newValue).apply();
return true; return true;
}); });
Preference enableBlur = findPreference("pref_enable_blur"); Preference enableBlur = findPreference("pref_enable_blur");
@ -204,12 +209,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
if (!MainApplication.isDeveloper()) { if (!MainApplication.isDeveloper()) {
findPreference("pref_disable_low_quality_module_filter").setVisible(false); findPreference("pref_disable_low_quality_module_filter").setVisible(false);
}
if (!BuildConfig.DEBUG || InstallerInitializer.peekMagiskPath() == null) {
// Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app // Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app
Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false); Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false);
} else { } else {
findPreference("pref_crash").setOnPreferenceClickListener(preference -> { findPreference("pref_crash").setOnPreferenceClickListener(preference -> {
// Hard crash the app // Hard crash the app
throw new RuntimeException("This is a test crash"); throw new Error("This is a test crash");
}); });
} }
if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) { if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) {
@ -217,12 +224,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
} }
Preference debugNotification = findPreference("pref_background_update_check_debug"); Preference debugNotification = findPreference("pref_background_update_check_debug");
debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled()); debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled());
debugNotification.setVisible(MainApplication.isDeveloper()); debugNotification.setVisible(MainApplication.isDeveloper() && !MainApplication.isWrapped());
debugNotification.setOnPreferenceClickListener(preference -> { debugNotification.setOnPreferenceClickListener(preference -> {
BackgroundUpdateChecker.postNotification(this.requireContext(), new Random().nextInt(4) + 2); BackgroundUpdateChecker.postNotification(this.requireContext(), new Random().nextInt(4) + 2);
return true; return true;
}); });
findPreference("pref_background_update_check").setOnPreferenceChangeListener((preference, newValue) -> { Preference backgroundUpdateCheck = findPreference("pref_background_update_check");
backgroundUpdateCheck.setVisible(!MainApplication.isWrapped());
backgroundUpdateCheck.setOnPreferenceChangeListener((preference, newValue) -> {
boolean enabled = Boolean.parseBoolean(String.valueOf(newValue)); boolean enabled = Boolean.parseBoolean(String.valueOf(newValue));
debugNotification.setEnabled(enabled); debugNotification.setEnabled(enabled);
if (!enabled) { if (!enabled) {
@ -276,11 +285,26 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
openFragment(libsBuilder.supportFragment(), R.string.licenses); openFragment(libsBuilder.supportFragment(), R.string.licenses);
return true; return true;
}); });
findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID + " v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"); findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID +
" v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")" +
getRepackageState()); // State may not be "I am just running from myself as myself"
} }
private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) { @SuppressLint("RestrictedApi")
return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit(); private String getRepackageState() {
Application initialApplication = null;
try {
initialApplication = FoxProcessExt.getInitialApplication();
} catch (Throwable ignored) {}
String realPackageName;
if (initialApplication != null) {
realPackageName = initialApplication.getPackageName();
} else {
realPackageName = this.requireContext().getPackageName();
}
if (BuildConfig.APPLICATION_ID.equals(realPackageName)) return "";
return "\n" + this.getString(FoxProcessExt.isRootLoader() ?
R.string.repackaged_as : R.string.wrapped_from) + realPackageName;
} }
private void openFragment(Fragment fragment, @StringRes int title) { private void openFragment(Fragment fragment, @StringRes int title) {
@ -300,7 +324,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
private int currentLanguageLevel() { private int currentLanguageLevel() {
int declaredLanguageLevel = this.getResources().getInteger(R.integer.language_support_level); int declaredLanguageLevel = this.getResources().getInteger(R.integer.language_support_level);
if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) return declaredLanguageLevel; if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) return declaredLanguageLevel;
if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") && this.getResources().getString(R.string.notification_update_pref).equals("Background modules update check") && this.getResources().getString(R.string.notification_update_desc).equals("May increase battery usage")) { if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") &&
this.getResources().getString(R.string.notification_update_pref).equals("Background modules update check") &&
this.getResources().getString(R.string.notification_update_desc).equals("May increase battery usage")) {
return 0; return 0;
} }
return LANGUAGE_SUPPORT_LEVEL; return LANGUAGE_SUPPORT_LEVEL;
@ -310,7 +336,6 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
public static class RepoFragment extends PreferenceFragmentCompat { public static class RepoFragment extends PreferenceFragmentCompat {
private static final int CUSTOM_REPO_ENTRIES = 5; private static final int CUSTOM_REPO_ENTRIES = 5;
@SuppressLint("RestrictedApi")
@Override @Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
getPreferenceManager().setSharedPreferencesName("mmm"); getPreferenceManager().setSharedPreferencesName("mmm");
@ -319,19 +344,24 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
setRepoData(RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT); setRepoData(RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT);
setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB); setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB);
updateCustomRepoList(true); updateCustomRepoList(true);
onCreatePreferencesAndroidacy();
}
@SuppressLint("RestrictedApi")
public void onCreatePreferencesAndroidacy() {
Preference androidacyTestMode = Objects.requireNonNull(findPreference("pref_androidacy_test_mode"));
if (!MainApplication.isDeveloper()) { if (!MainApplication.isDeveloper()) {
Objects.requireNonNull((Preference) findPreference("pref_androidacy_test_mode")).setVisible(false); androidacyTestMode.setVisible(false);
} else { } else {
// Show a warning if user tries to enable test mode // Show a warning if user tries to enable test mode
Objects.requireNonNull((SwitchPreferenceCompat) findPreference("pref_androidacy_test_mode")).setOnPreferenceChangeListener((preference, newValue) -> { androidacyTestMode.setOnPreferenceChangeListener((preference, newValue) -> {
if (Boolean.parseBoolean(String.valueOf(newValue))) { if (Boolean.parseBoolean(String.valueOf(newValue))) {
new AlertDialog.Builder(this.requireContext()) new AlertDialog.Builder(this.requireContext())
.setTitle(R.string.warning) .setTitle(R.string.warning)
.setMessage(R.string.androidacy_test_mode_warning) .setMessage(R.string.androidacy_test_mode_warning)
.setPositiveButton(android.R.string.ok, (dialog, which) -> { .setPositiveButton(android.R.string.ok, (dialog, which) -> {
// Do nothing // Do nothing
}) }).show();
.show();
} }
return true; return true;
}); });
@ -423,7 +453,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
} }
Preference preference = findPreference("pref_custom_add_repo"); Preference preference = findPreference("pref_custom_add_repo");
if (preference == null) return; if (preference == null) return;
preference.setVisible(customRepoManager.canAddRepo() && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES); preference.setVisible(customRepoManager.canAddRepo() &&
customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
if (initial) { // Custom repo add button part. if (initial) { // Custom repo add button part.
preference = findPreference("pref_custom_add_repo_button"); preference = findPreference("pref_custom_add_repo_button");
if (preference == null) return; if (preference == null) return;
@ -470,7 +501,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
input.addTextChangedListener(new TextWatcherAdapter() { input.addTextChangedListener(new TextWatcherAdapter() {
@Override @Override
public void onTextChanged(@NonNull CharSequence charSequence, int i, int i1, int i2) { public void onTextChanged(@NonNull CharSequence charSequence, int i, int i1, int i2) {
positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES); positiveButton.setEnabled(customRepoManager.canAddRepo(charSequence.toString()) &&
customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES);
} }
}); });
positiveButton.setEnabled(false); positiveButton.setEnabled(false);

@ -134,7 +134,7 @@
<string name="restore_module_list">Restore modules</string> <string name="restore_module_list">Restore modules</string>
<string name="require_internet">This operation require an internet connection</string> <string name="require_internet">This operation require an internet connection</string>
<string name="androidacy_test_mode_pref">Androidacy test mode</string> <string name="androidacy_test_mode_pref">Androidacy test mode</string>
<string name="androidacy_test_mode_desc">Use staging Androidacy Endpoint instead of release endpoint. (Require app process restart)</string> <string name="androidacy_test_mode_desc">Use staging Androidacy endpoint instead of release endpoint. (Require app process restart)</string>
<!-- Background Notification translation --> <!-- Background Notification translation -->
<string name="notification_update_title">Found %i module updates</string> <string name="notification_update_title">Found %i module updates</string>
@ -168,4 +168,6 @@
<string name="warning">Warning!</string> <string name="warning">Warning!</string>
<string name="androidacy_test_mode_warning">You are setting the app to use a non-production endpoint for Androidacy. This may result in app instability and failure to load the online repo. Do NOT report bugs if you have this switch on. Change will take effect on app restart.</string> <string name="androidacy_test_mode_warning">You are setting the app to use a non-production endpoint for Androidacy. This may result in app instability and failure to load the online repo. Do NOT report bugs if you have this switch on. Change will take effect on app restart.</string>
<string name="crash">Crash the app for testing</string> <string name="crash">Crash the app for testing</string>
<string name="repackaged_as">Repackaged as:</string>
<string name="wrapped_from">Wrapped from:</string>
</resources> </resources>

Loading…
Cancel
Save