diff --git a/app/build.gradle b/app/build.gradle index ac345d1..320a299 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -285,6 +285,8 @@ sentry { configurations { implementation.exclude group: 'org.jetbrains', module: 'annotations' + // exclude chromium cronet-api + implementation.exclude group: 'org.chromium.net', module: 'cronet-api' } dependencies { @@ -296,7 +298,7 @@ dependencies { implementation 'androidx.emoji2:emoji2-views-helper:1.2.0' implementation 'androidx.preference:preference-ktx:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'androidx.recyclerview:recyclerview:1.2.1' + implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.webkit:webkit:1.6.0' implementation 'com.google.android.material:material:1.8.0' @@ -313,14 +315,18 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.10' implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:5.0.0-alpha.10' // Chromium cronet from androidacy - implementation 'org.chromium.net:cronet-embedded:108.5359.79' + implementation 'com.androidacy:cronet-common:111.0.5563.75' + implementation 'com.androidacy:cronet-native:111.0.5563.75' + implementation 'com.androidacy:cronet-api:111.0.5563.75' + // protobuf - fixes a crash on some devicesa + implementation 'com.google.protobuf:protobuf-javalite:3.22.2' implementation 'com.github.topjohnwu.libsu:io:5.0.1' implementation 'com.github.Fox2Code:RosettaX:1.0.9' implementation 'com.github.Fox2Code:AndroidANSI:1.0.1' // sentry - implementation platform('io.sentry:sentry-bom:6.14.0') + implementation platform('io.sentry:sentry-bom:6.15.0') implementation "io.sentry:sentry-android" implementation "io.sentry:sentry-android-timber" implementation "io.sentry:sentry-android-fragment" diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 028078d..8df378d 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -101,11 +101,18 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe @Override protected void onCreate(Bundle savedInstanceState) { this.initMode = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + // per process webview data dir + try { + WebView.setDataDirectorySuffix(FoxApplication.getProcessName()); + } catch (IllegalStateException e) { + Timber.d("Could not set webview data dir, possibly already set or webview already initialized"); + } + } // Ensure HTTP Cache directories are created Http.ensureCacheDirs(this); if (!urlFactoryInstalled) { - try { - HttpResponseCache cache = HttpResponseCache.getInstalled(); + try (HttpResponseCache cache = HttpResponseCache.getInstalled()) { if (cache == null) { File cacheDir = new File(getCacheDir(), "http"); //noinspection ResultOfMethodCallIgnored @@ -131,10 +138,6 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe } BackgroundUpdateChecker.onMainActivityCreate(this); super.onCreate(savedInstanceState); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - // per process webview data dir - WebView.setDataDirectorySuffix(FoxApplication.getProcessName()); - } if (!isOfficial) { Timber.w("You may be running an untrusted build."); // Show a toast to warn the user @@ -293,7 +296,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe // On every preferences change, log the change if debug is enabled if (BuildConfig.DEBUG) { // Log all preferences changes - MainApplication.getSharedPreferences().registerOnSharedPreferenceChangeListener((prefs, key) -> Timber.i("onSharedPreferenceChanged: " + key + " = " + prefs.getAll().get(key))); + MainApplication.getSharedPreferences("mmm").registerOnSharedPreferenceChangeListener((prefs, key) -> Timber.i("onSharedPreferenceChanged: " + key + " = " + prefs.getAll().get(key))); } Timber.i("Scanning for modules!"); @@ -716,7 +719,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe if (BuildConfig.DEBUG) Timber.i("Checking if we need to run setup"); // Check if this is the first launch using prefs and if doSetupRestarting was passed in the intent - SharedPreferences prefs = MainApplication.getSharedPreferences(); + SharedPreferences prefs = MainApplication.getSharedPreferences("mmm"); boolean firstLaunch = !Objects.equals(prefs.getString("last_shown_setup", null), "v1"); // First launch // this is intentionally separate from the above if statement, because it needs to be checked even if the first launch check is true due to some weird edge cases diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 564e84e..5392ced 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -20,6 +20,8 @@ import androidx.core.app.NotificationManagerCompat; import androidx.emoji2.text.DefaultEmojiCompatConfig; import androidx.emoji2.text.EmojiCompat; import androidx.emoji2.text.FontRequestEmojiCompatConfig; +import androidx.security.crypto.EncryptedSharedPreferences; +import androidx.security.crypto.MasterKey; import com.fox2code.foxcompat.app.FoxActivity; import com.fox2code.foxcompat.app.FoxApplication; @@ -34,6 +36,8 @@ import com.google.common.hash.Hashing; import com.topjohnwu.superuser.Shell; import java.io.File; +import java.io.IOException; +import java.security.GeneralSecurityException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; @@ -67,7 +71,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con private static long secret; private static Locale timeFormatLocale = Resources.getSystem().getConfiguration().getLocales().get(0); private static SimpleDateFormat timeFormat = new SimpleDateFormat(timeFormatString, timeFormatLocale); - private static SharedPreferences bootSharedPreferences; private static String relPackageName = BuildConfig.APPLICATION_ID; @SuppressLint("StaticFieldLeak") private static MainApplication INSTANCE; @@ -106,8 +109,21 @@ public class MainApplication extends FoxApplication implements androidx.work.Con intent.putExtra("secret", secret); } - public static SharedPreferences getSharedPreferences() { - return INSTANCE.getSharedPreferences("mmm", MODE_PRIVATE); + public static SharedPreferences getSharedPreferences(String name) { + // encryptedSharedPreferences is used + MasterKey mainKeyAlias; + try { + mainKeyAlias = new MasterKey.Builder(MainApplication.getINSTANCE().getApplicationContext()).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build(); + } catch (GeneralSecurityException | IOException e) { + throw new RuntimeException(e); + } + SharedPreferences mSharedPreferences; + try { + mSharedPreferences = EncryptedSharedPreferences.create(MainApplication.getINSTANCE().getApplicationContext(), name, mainKeyAlias, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM); + } catch (GeneralSecurityException | IOException e) { + throw new RuntimeException(e); + } + return mSharedPreferences; } // Is application wrapped, and therefore must reduce it's feature set. @@ -121,57 +137,57 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } public static boolean isShowcaseMode() { - return getSharedPreferences().getBoolean("pref_showcase_mode", false); + return getSharedPreferences("mmm").getBoolean("pref_showcase_mode", false); } public static boolean shouldPreventReboot() { - return getSharedPreferences().getBoolean("pref_prevent_reboot", true); + return getSharedPreferences("mmm").getBoolean("pref_prevent_reboot", true); } public static boolean isShowIncompatibleModules() { - return getSharedPreferences().getBoolean("pref_show_incompatible", false); + return getSharedPreferences("mmm").getBoolean("pref_show_incompatible", false); } public static boolean isForceDarkTerminal() { - return getSharedPreferences().getBoolean("pref_force_dark_terminal", false); + return getSharedPreferences("mmm").getBoolean("pref_force_dark_terminal", false); } public static boolean isTextWrapEnabled() { - return getSharedPreferences().getBoolean("pref_wrap_text", false); + return getSharedPreferences("mmm").getBoolean("pref_wrap_text", false); } public static boolean isDohEnabled() { - return getSharedPreferences().getBoolean("pref_dns_over_https", true); + return getSharedPreferences("mmm").getBoolean("pref_dns_over_https", true); } public static boolean isMonetEnabled() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && getSharedPreferences().getBoolean("pref_enable_monet", true); + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && getSharedPreferences("mmm").getBoolean("pref_enable_monet", true); } public static boolean isBlurEnabled() { - return getSharedPreferences().getBoolean("pref_enable_blur", false); + return getSharedPreferences("mmm").getBoolean("pref_enable_blur", false); } public static boolean isDeveloper() { if (BuildConfig.DEBUG) return true; - return getSharedPreferences().getBoolean("developer", false); + return getSharedPreferences("mmm").getBoolean("developer", false); } public static boolean isDisableLowQualityModuleFilter() { - return getSharedPreferences().getBoolean("pref_disable_low_quality_module_filter", false) && isDeveloper(); + return getSharedPreferences("mmm").getBoolean("pref_disable_low_quality_module_filter", false) && isDeveloper(); } public static boolean isUsingMagiskCommand() { - return InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND && getSharedPreferences().getBoolean("pref_use_magisk_install_command", false) && isDeveloper(); + return InstallerInitializer.peekMagiskVersion() >= Constants.MAGISK_VER_CODE_INSTALL_COMMAND && getSharedPreferences("mmm").getBoolean("pref_use_magisk_install_command", false) && isDeveloper(); } public static boolean isBackgroundUpdateCheckEnabled() { - return !wrapped && getSharedPreferences().getBoolean("pref_background_update_check", true); + return !wrapped && getSharedPreferences("mmm").getBoolean("pref_background_update_check", true); } public static boolean isAndroidacyTestMode() { - return isDeveloper() && getSharedPreferences().getBoolean("pref_androidacy_test_mode", false); + return isDeveloper() && getSharedPreferences("mmm").getBoolean("pref_androidacy_test_mode", false); } public static boolean isFirstBoot() { @@ -179,15 +195,15 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } public static void setHasGottenRootAccess(boolean bool) { - getSharedPreferences().edit().putBoolean("has_root_access", bool).apply(); + getSharedPreferences("mmm").edit().putBoolean("has_root_access", bool).apply(); } public static boolean isCrashReportingEnabled() { - return SentryMain.IS_SENTRY_INSTALLED && getSharedPreferences().getBoolean("pref_crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING); + return SentryMain.IS_SENTRY_INSTALLED && getSharedPreferences("mmm").getBoolean("pref_crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING); } public static SharedPreferences getBootSharedPreferences() { - return bootSharedPreferences; + return getSharedPreferences("mmm_boot"); } public static MainApplication getINSTANCE() { @@ -224,7 +240,7 @@ public class MainApplication extends FoxApplication implements androidx.work.Con @StyleRes int themeResId; String theme; boolean monet = isMonetEnabled(); - switch (theme = getSharedPreferences().getString("pref_theme", "system")) { + switch (theme = getSharedPreferences("mmm").getString("pref_theme", "system")) { default: Timber.w("Unknown theme id: %s", theme); case "system": @@ -324,6 +340,8 @@ public class MainApplication extends FoxApplication implements androidx.work.Con relPackageName = this.getPackageName(); Timber.d("Starting FoxMMM version " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + "), commit " + BuildConfig.COMMIT_HASH); super.onCreate(); + // Update SSL Ciphers if update is possible + GMSProviderInstaller.installIfNeeded(this); if (BuildConfig.DEBUG) { Timber.d("Initializing FoxMMM"); Timber.d("Started from background: %s", !isInForeground()); @@ -342,9 +360,9 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } catch ( PackageManager.NameNotFoundException ignored) { } - SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); + SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("mmm"); // We are only one process so it's ok to do this - SharedPreferences bootPrefs = MainApplication.bootSharedPreferences = MainApplication.getINSTANCE().getSharedPreferences("mmm_boot", Context.MODE_PRIVATE); + SharedPreferences bootPrefs = MainApplication.getSharedPreferences("mmm_boot"); long lastBoot = System.currentTimeMillis() - SystemClock.elapsedRealtime(); long lastBootPrefs = bootPrefs.getLong("last_boot", 0); if (lastBootPrefs == 0 || Math.abs(lastBoot - lastBootPrefs) > 100) { @@ -360,8 +378,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con // Force initialize language early. new LanguageSwitcher(this); this.updateTheme(); - // Update SSL Ciphers if update is possible - GMSProviderInstaller.installIfNeeded(this); // Update emoji config FontRequestEmojiCompatConfig fontRequestEmojiCompatConfig = DefaultEmojiCompatConfig.create(this); if (fontRequestEmojiCompatConfig != null) { diff --git a/app/src/main/java/com/fox2code/mmm/SetupActivity.java b/app/src/main/java/com/fox2code/mmm/SetupActivity.java index b6b5278..579b5d1 100644 --- a/app/src/main/java/com/fox2code/mmm/SetupActivity.java +++ b/app/src/main/java/com/fox2code/mmm/SetupActivity.java @@ -14,7 +14,6 @@ import android.util.Base64; import android.view.View; import android.view.WindowManager; -import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.fragment.app.FragmentActivity; @@ -59,7 +58,7 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { createFiles(); disableUpdateActivityForFdroidFlavor(); // Set theme - SharedPreferences prefs = MainApplication.getSharedPreferences(); + SharedPreferences prefs = MainApplication.getSharedPreferences("mmm"); switch (prefs.getString("theme", "system")) { case "light" -> setTheme(R.style.Theme_MagiskModuleManager_Monet_Light); case "dark" -> setTheme(R.style.Theme_MagiskModuleManager_Monet_Dark); @@ -215,7 +214,7 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { public Resources.Theme getTheme() { Resources.Theme theme = super.getTheme(); // Set the theme - SharedPreferences prefs = MainApplication.getSharedPreferences(); + SharedPreferences prefs = MainApplication.getSharedPreferences("mmm"); switch (prefs.getString("pref_theme", "system")) { case "light" -> theme.applyStyle(R.style.Theme_MagiskModuleManager_Monet_Light, true); case "dark" -> theme.applyStyle(R.style.Theme_MagiskModuleManager_Monet_Dark, true); @@ -244,51 +243,52 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { Timber.d("Creating Realm databases"); long startTime = System.currentTimeMillis(); // create encryption key - Timber.d("Creating encryption key"); + // Timber.d("Creating encryption key"); // create the realm database for ReposList // next, create the realm database for ReposList - RealmConfiguration config2 = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); - // get the instance - Realm.getInstanceAsync(config2, new Realm.Callback() { - @Override - public void onSuccess(@NonNull Realm realm1) { - // create androidacy_repo and magisk_alt_repo if they don't exist under ReposList - // each has id, name, donate, website, support, enabled, and lastUpdate and name - // create androidacy_repo - realm1.beginTransaction(); - if (realm1.where(ReposList.class).equalTo("id", "androidacy_repo").findFirst() == null) { - // cant use createObject because it crashes because reasons. use copyToRealm instead - ReposList androidacy_repo = realm1.createObject(ReposList.class, "androidacy_repo"); - androidacy_repo.setName("Androidacy Repo"); - androidacy_repo.setDonate(AndroidacyRepoData.getInstance().getDonate()); - androidacy_repo.setSupport(AndroidacyRepoData.getInstance().getSupport()); - androidacy_repo.setSubmitModule(AndroidacyRepoData.getInstance().getSubmitModule()); - androidacy_repo.setUrl(RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT); - androidacy_repo.setEnabled(true); - androidacy_repo.setLastUpdate(0); - androidacy_repo.setWebsite(RepoManager.ANDROIDACY_MAGISK_REPO_HOMEPAGE); - // now copy the data from the data class to the realm object using copyToRealmOrUpdate - realm1.insertOrUpdate(androidacy_repo); - } - // create magisk_alt_repo - if (realm1.where(ReposList.class).equalTo("id", "magisk_alt_repo").findFirst() == null) { - ReposList magisk_alt_repo = realm1.createObject(ReposList.class, "magisk_alt_repo"); - magisk_alt_repo.setName("Magisk Alt Repo"); - magisk_alt_repo.setDonate(null); - magisk_alt_repo.setWebsite(RepoManager.MAGISK_ALT_REPO_HOMEPAGE); - magisk_alt_repo.setSupport(null); - magisk_alt_repo.setEnabled(true); - magisk_alt_repo.setUrl(RepoManager.MAGISK_ALT_REPO); - magisk_alt_repo.setSubmitModule(RepoManager.MAGISK_ALT_REPO_HOMEPAGE + "/submission"); - magisk_alt_repo.setLastUpdate(0); - // commit the changes - realm1.insertOrUpdate(magisk_alt_repo); - } - realm1.commitTransaction(); + new Thread(() -> { + // create the realm database for ReposList + // create the realm configuration + RealmConfiguration config2 = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); + // get the instance + Realm realm1 = Realm.getInstance(config2); + // create androidacy_repo and magisk_alt_repo if they don't exist under ReposList + // each has id, name, donate, website, support, enabled, and lastUpdate and name + // create androidacy_repo + realm1.beginTransaction(); + if (realm1.where(ReposList.class).equalTo("id", "androidacy_repo").findFirst() == null) { + // cant use createObject because it crashes because reasons. use copyToRealm instead + ReposList androidacy_repo = realm1.createObject(ReposList.class, "androidacy_repo"); + androidacy_repo.setName("Androidacy Repo"); + androidacy_repo.setDonate(AndroidacyRepoData.getInstance().getDonate()); + androidacy_repo.setSupport(AndroidacyRepoData.getInstance().getSupport()); + androidacy_repo.setSubmitModule(AndroidacyRepoData.getInstance().getSubmitModule()); + androidacy_repo.setUrl(RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT); + androidacy_repo.setEnabled(true); + androidacy_repo.setLastUpdate(0); + androidacy_repo.setWebsite(RepoManager.ANDROIDACY_MAGISK_REPO_HOMEPAGE); + // now copy the data from the data class to the realm object using copyToRealmOrUpdate + realm1.insertOrUpdate(androidacy_repo); } - }); - long endTime = System.currentTimeMillis(); - Timber.d("Realm databases created in %d ms", endTime - startTime); + // create magisk_alt_repo + if (realm1.where(ReposList.class).equalTo("id", "magisk_alt_repo").findFirst() == null) { + ReposList magisk_alt_repo = realm1.createObject(ReposList.class, "magisk_alt_repo"); + magisk_alt_repo.setName("Magisk Alt Repo"); + magisk_alt_repo.setDonate(null); + magisk_alt_repo.setWebsite(RepoManager.MAGISK_ALT_REPO_HOMEPAGE); + magisk_alt_repo.setSupport(null); + magisk_alt_repo.setEnabled(true); + magisk_alt_repo.setUrl(RepoManager.MAGISK_ALT_REPO); + magisk_alt_repo.setSubmitModule(RepoManager.MAGISK_ALT_REPO_HOMEPAGE + "/submission"); + magisk_alt_repo.setLastUpdate(0); + // commit the changes + realm1.insertOrUpdate(magisk_alt_repo); + } + realm1.commitTransaction(); + realm1.close(); + long endTime = System.currentTimeMillis(); + Timber.d("Realm databases created in %d ms", endTime - startTime); + }).start(); } public void createFiles() { diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java index fa6cc27..64fe13d 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java @@ -44,7 +44,7 @@ import timber.log.Timber; @SuppressWarnings("KotlinInternalInJava") public final class AndroidacyRepoData extends RepoData { - public static String token = MainApplication.getINSTANCE().getSharedPreferences("androidacy", Context.MODE_PRIVATE).getString("pref_androidacy_api_token", null); + public static String token = MainApplication.getSharedPreferences("androidacy").getString("pref_androidacy_api_token", null); static { HttpUrl.Builder OK_HTTP_URL_BUILDER = new HttpUrl.Builder().scheme("https"); @@ -55,7 +55,7 @@ public final class AndroidacyRepoData extends RepoData { @SuppressWarnings("unused") public final String ClientID = BuildConfig.ANDROIDACY_CLIENT_ID; - public final SharedPreferences cachedPreferences = MainApplication.getINSTANCE().getSharedPreferences("androidacy", Context.MODE_PRIVATE); + public final SharedPreferences cachedPreferences = MainApplication.getSharedPreferences("androidacy"); private final boolean testMode; private final String host; public String[][] userInfo = new String[][]{{"role", null}, {"permissions", null}}; @@ -89,7 +89,7 @@ public final class AndroidacyRepoData extends RepoData { // limiting and fraud detection. public static String generateDeviceId() { // Try to get the device ID from the shared preferences - SharedPreferences sharedPreferences = MainApplication.getINSTANCE().getSharedPreferences("androidacy", Context.MODE_PRIVATE); + SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("androidacy"); String deviceIdPref = sharedPreferences.getString("device_id", null); if (deviceIdPref != null) { return deviceIdPref; @@ -182,7 +182,7 @@ public final class AndroidacyRepoData extends RepoData { protected boolean prepare() { // If ANDROIDACY_CLIENT_ID is not set or is empty, disable this repo and return if (Objects.equals(BuildConfig.ANDROIDACY_CLIENT_ID, "")) { - SharedPreferences.Editor editor = MainApplication.getSharedPreferences().edit(); + SharedPreferences.Editor editor = MainApplication.getSharedPreferences("mmm").edit(); editor.putBoolean("pref_androidacy_repo_enabled", false); editor.apply(); return false; diff --git a/app/src/main/java/com/fox2code/mmm/background/BackgroundBootListener.java b/app/src/main/java/com/fox2code/mmm/background/BackgroundBootListener.java index 4a69990..72fd05d 100644 --- a/app/src/main/java/com/fox2code/mmm/background/BackgroundBootListener.java +++ b/app/src/main/java/com/fox2code/mmm/background/BackgroundBootListener.java @@ -12,6 +12,8 @@ public class BackgroundBootListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!BOOT_COMPLETED.equals(intent.getAction())) return; + // clear boot shared prefs + MainApplication.getBootSharedPreferences().edit().clear().apply(); synchronized (BackgroundUpdateChecker.lock) { new Thread(() -> { BackgroundUpdateChecker.onMainActivityCreate(context); diff --git a/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java b/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java index ef34348..29aa246 100644 --- a/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java +++ b/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java @@ -60,7 +60,7 @@ public class BackgroundUpdateChecker extends Worker { static void doCheck(Context context) { // first, check if the user has enabled background update checking - if (!MainApplication.getSharedPreferences().getBoolean("pref_background_update_check", false)) { + if (!MainApplication.getSharedPreferences("mmm").getBoolean("pref_background_update_check", false)) { return; } if (MainApplication.getINSTANCE().isInForeground()) { @@ -68,7 +68,7 @@ public class BackgroundUpdateChecker extends Worker { return; } // next, check if user requires wifi - if (MainApplication.getSharedPreferences().getBoolean("pref_background_update_check_wifi", true)) { + if (MainApplication.getSharedPreferences("mmm").getBoolean("pref_background_update_check_wifi", true)) { // check if wifi is connected ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); Network networkInfo = connectivityManager.getActiveNetwork(); @@ -107,7 +107,7 @@ public class BackgroundUpdateChecker extends Worker { continue; // exclude all modules with id's stored in the pref pref_background_update_check_excludes try { - if (MainApplication.getSharedPreferences().getStringSet("pref_background_update_check_excludes", null).contains(localModuleInfo.id)) + if (MainApplication.getSharedPreferences("mmm").getStringSet("pref_background_update_check_excludes", null).contains(localModuleInfo.id)) continue; } catch ( Exception ignored) { @@ -127,7 +127,7 @@ public class BackgroundUpdateChecker extends Worker { } }); // check for app updates - if (MainApplication.getSharedPreferences().getBoolean("pref_background_update_check_app", false)) { + if (MainApplication.getSharedPreferences("mmm").getBoolean("pref_background_update_check_app", false)) { try { boolean shouldUpdate = AppUpdateManager.getAppUpdateManager().checkUpdate(true); if (shouldUpdate) { @@ -209,7 +209,7 @@ public class BackgroundUpdateChecker extends Worker { public static void onMainActivityCreate(Context context) { // Refuse to run if first_launch pref is not false - if (!Objects.equals(MainApplication.getSharedPreferences().getString("last_shown_setup", null), "v1")) + if (!Objects.equals(MainApplication.getSharedPreferences("mmm").getString("last_shown_setup", null), "v1")) return; // create notification channel group if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java b/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java index 21a8937..32d6db4 100644 --- a/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java +++ b/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java @@ -55,7 +55,7 @@ public final class ModuleManager extends SyncManager { protected void scanInternal(@NonNull UpdateListener updateListener) { // if last_shown_setup is not "v1", them=n refuse to continue - if (!MainApplication.getSharedPreferences().getString("last_shown_setup", "").equals("v1")) { + if (!MainApplication.getSharedPreferences("mmm").getString("last_shown_setup", "").equals("v1")) { return; } boolean firstScan = this.bootPrefs.getBoolean("mm_first_scan", true); diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java index f8fb66d..55ff6a9 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -148,7 +148,7 @@ public final class RepoManager extends SyncManager { @SuppressWarnings("StatementWithEmptyBody") private void populateDefaultCache(RepoData repoData) { // if last_shown_setup is not "v1", them=n refuse to continue - if (!MainApplication.getSharedPreferences().getString("last_shown_setup", "").equals("v1")) { + if (!MainApplication.getSharedPreferences("mmm").getString("last_shown_setup", "").equals("v1")) { return; } // make sure repodata is not null diff --git a/app/src/main/java/com/fox2code/mmm/settings/EncryptedPreferenceDataStore.java b/app/src/main/java/com/fox2code/mmm/settings/EncryptedPreferenceDataStore.java index 33c1f6e..cb38577 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/EncryptedPreferenceDataStore.java +++ b/app/src/main/java/com/fox2code/mmm/settings/EncryptedPreferenceDataStore.java @@ -22,7 +22,7 @@ public class EncryptedPreferenceDataStore extends PreferenceDataStore { private static EncryptedPreferenceDataStore mInstance; private SharedPreferences mSharedPreferences; - private EncryptedPreferenceDataStore(Context context) { + EncryptedPreferenceDataStore(Context context) { try { MasterKey mainKeyAlias; try { diff --git a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java index eb9775b..60dc385 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -194,6 +194,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { @SuppressWarnings("ConstantConditions") public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { PreferenceManager preferenceManager = getPreferenceManager(); + preferenceManager.setPreferenceDataStore(new EncryptedPreferenceDataStore(this.getContext())); preferenceManager.setSharedPreferencesName("mmm"); setPreferencesFromResource(R.xml.root_preferences, rootKey); applyMaterial3(getPreferenceScreen()); @@ -456,7 +457,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { // set the box to unchecked ((SwitchPreferenceCompat) backgroundUpdateCheck).setChecked(false); // ensure that the preference is false - MainApplication.getSharedPreferences().edit().putBoolean("pref_background_update_check", false).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("pref_background_update_check", false).apply(); new MaterialAlertDialogBuilder(this.requireContext()).setTitle(R.string.permission_notification_title).setMessage(R.string.permission_notification_message).setPositiveButton(R.string.ok, (dialog, which) -> { // Open the app settings Intent intent = new Intent(); @@ -493,7 +494,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { int i = 0; for (LocalModuleInfo localModuleInfo : localModuleInfos) { moduleNames[i] = localModuleInfo.name; - SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); + SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("mmm"); // get the stringset pref_background_update_check_excludes Set stringSet = sharedPreferences.getStringSet("pref_background_update_check_excludes", new HashSet<>()); // Stringset uses id, we show name @@ -503,7 +504,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } new MaterialAlertDialogBuilder(this.requireContext()).setTitle(R.string.background_update_check_excludes).setMultiChoiceItems(moduleNames, checkedItems, (dialog, which, isChecked) -> { // get the stringset pref_background_update_check_excludes - SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); + SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("mmm"); Set stringSet = new HashSet<>(sharedPreferences.getStringSet("pref_background_update_check_excludes", new HashSet<>())); // get id from name String id; @@ -591,11 +592,11 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { if (devModeStep == 2) { devModeStep = 0; if (MainApplication.isDeveloper() && !BuildConfig.DEBUG) { - MainApplication.getSharedPreferences().edit().putBoolean("developer", false).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("developer", false).apply(); Toast.makeText(getContext(), // Tell the user something changed R.string.dev_mode_disabled, Toast.LENGTH_SHORT).show(); } else { - MainApplication.getSharedPreferences().edit().putBoolean("developer", true).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("developer", true).apply(); Toast.makeText(getContext(), // Tell the user something changed R.string.dev_mode_enabled, Toast.LENGTH_SHORT).show(); } @@ -807,7 +808,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { // Use MaterialAlertDialogBuilder new MaterialAlertDialogBuilder(this.requireContext()).setTitle(R.string.warning).setCancelable(false).setMessage(R.string.androidacy_test_mode_warning).setPositiveButton(android.R.string.ok, (dialog, which) -> { // User clicked OK button - MainApplication.getSharedPreferences().edit().putBoolean("androidacy_test_mode", true).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("androidacy_test_mode", true).apply(); // Check the switch Intent mStartActivity = new Intent(requireContext(), MainActivity.class); mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); @@ -825,10 +826,10 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { SwitchPreferenceCompat switchPreferenceCompat = (SwitchPreferenceCompat) androidacyTestMode; switchPreferenceCompat.setChecked(false); // There's probably a better way to do this than duplicate code but I'm too lazy to figure it out - MainApplication.getSharedPreferences().edit().putBoolean("androidacy_test_mode", false).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("androidacy_test_mode", false).apply(); }).show(); } else { - MainApplication.getSharedPreferences().edit().putBoolean("androidacy_test_mode", false).apply(); + MainApplication.getSharedPreferences("mmm").edit().putBoolean("androidacy_test_mode", false).apply(); // Show dialog to restart app with ok button new MaterialAlertDialogBuilder(this.requireContext()).setTitle(R.string.warning).setCancelable(false).setMessage(R.string.androidacy_test_mode_disable_warning).setNeutralButton(android.R.string.ok, (dialog, which) -> { // User clicked OK button diff --git a/app/src/main/java/com/fox2code/mmm/utils/sentry/SentryMain.java b/app/src/main/java/com/fox2code/mmm/utils/sentry/SentryMain.java index 5a59610..dfd349c 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/sentry/SentryMain.java +++ b/app/src/main/java/com/fox2code/mmm/utils/sentry/SentryMain.java @@ -28,7 +28,7 @@ public class SentryMain { @SuppressLint({"RestrictedApi", "UnspecifiedImmutableFlag"}) public static void initialize(final MainApplication mainApplication) { // If first_launch pref is not false, refuse to initialize Sentry - SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); + SharedPreferences sharedPreferences = MainApplication.getSharedPreferences("sentry"); if (!Objects.equals(sharedPreferences.getString("last_shown_setup", null), "v1")) { return; } @@ -81,7 +81,7 @@ public class SentryMain { // With this callback, you can modify the event or, when returning null, also discard the event. options.setBeforeSend((event, hint) -> { // Save lastEventId to private shared preferences - SharedPreferences sentryPrefs = MainApplication.getINSTANCE().getSharedPreferences("sentry", Context.MODE_PRIVATE); + SharedPreferences sentryPrefs = MainApplication.getSharedPreferences("sentry"); String lastEventId = Objects.requireNonNull(event.getEventId()).toString(); SharedPreferences.Editor editor = sentryPrefs.edit(); editor.putString("lastEventId", lastEventId); diff --git a/build.gradle b/build.gradle index 755e465..0bfc934 100644 --- a/build.gradle +++ b/build.gradle @@ -7,9 +7,6 @@ buildscript { maven { url 'https://jitpack.io' } - maven { - url 'https://oss.sonatype.org/content/repositories/snapshots/' - } } project.ext.latestAboutLibsRelease = "10.5.2" project.ext.sentryConfigFile = new File(rootDir, "sentry.properties").getAbsoluteFile() @@ -24,12 +21,11 @@ buildscript { classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10" classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${latestAboutLibsRelease}" - classpath 'io.sentry:sentry-android:6.14.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files //noinspection GradleDependency - classpath "io.realm:realm-gradle-plugin:10.13.3-transformer-api-SNAPSHOT" + classpath "io.realm:realm-gradle-plugin:10.13.2-transformer-api" } } diff --git a/settings.gradle b/settings.gradle index 8af392b..865356f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -6,9 +6,6 @@ dependencyResolutionManagement { maven { url 'https://jitpack.io' } - maven { - url 'https://oss.sonatype.org/content/repositories/snapshots/' - } } } rootProject.name = "MagiskModuleManager"