From b5389d597ca99dc82bbcddd2fa27f5920967350b Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Tue, 24 Jan 2023 14:50:41 -0500 Subject: [PATCH] [insert awesome commit message here] Signed-off-by: androidacy-user --- .../java/com/fox2code/mmm/CrashHandler.java | 16 +++++ .../com/fox2code/mmm/MainApplication.java | 68 ++++--------------- .../java/com/fox2code/mmm/SetupActivity.java | 9 +-- .../mmm/androidacy/AndroidacyRepoData.java | 4 ++ .../java/com/fox2code/mmm/repo/RepoData.java | 15 ++-- .../com/fox2code/mmm/repo/RepoManager.java | 2 +- .../com/fox2code/mmm/repo/RepoUpdater.java | 6 +- .../mmm/settings/SettingsActivity.java | 48 +++++++++++-- .../res/layout/activity_crash_handler.xml | 15 +++- app/src/main/res/values/strings.xml | 6 +- 10 files changed, 108 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/CrashHandler.java b/app/src/main/java/com/fox2code/mmm/CrashHandler.java index 9f97de8..ad4c9c4 100644 --- a/app/src/main/java/com/fox2code/mmm/CrashHandler.java +++ b/app/src/main/java/com/fox2code/mmm/CrashHandler.java @@ -9,6 +9,7 @@ import android.widget.EditText; import android.widget.Toast; import com.fox2code.foxcompat.app.FoxActivity; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textview.MaterialTextView; import org.json.JSONException; @@ -151,6 +152,21 @@ public class CrashHandler extends FoxActivity { startActivity(getPackageManager().getLaunchIntentForPackage(getPackageName())); }); } + // handle reset button + findViewById(R.id.reset).setOnClickListener(v -> { + // show a confirmation material dialog + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); + builder.setTitle(R.string.reset_app); + builder.setMessage(R.string.reset_app_confirmation); + builder.setPositiveButton(R.string.reset, (dialog, which) -> { + // reset the app + MainApplication.getINSTANCE().resetApp(); + }); + builder.setNegativeButton(R.string.cancel, (dialog, which) -> { + // do nothing + }); + builder.show(); + }); } public void copyCrashDetails(View view) { diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 6223d15..49d2447 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -447,65 +447,27 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } } - public void clearAppData() { - // Clear app data - try { - // Clearing app data - // We have to manually delete the files and directories - // because the cache directory is not cleared by the following method - File cacheDir; - cacheDir = this.getDataDir(); - if (cacheDir != null && cacheDir.isDirectory()) { - String[] children = cacheDir.list(); - if (children != null) { - for (String s : children) { - if (BuildConfig.DEBUG) - Timber.w("Deleting %s", s); - if (!s.equals("lib")) { - if (!new File(cacheDir, s).delete()) { - if (BuildConfig.DEBUG) - Timber.w("Failed to delete %s", s); - } - } - } - } - } - if (BuildConfig.DEBUG) - Timber.w("Deleting cache dir"); - this.deleteSharedPreferences("mmm_boot"); - this.deleteSharedPreferences("mmm"); - this.deleteSharedPreferences("sentry"); - this.deleteSharedPreferences("androidacy"); - if (BuildConfig.DEBUG) - Timber.w("Deleting shared prefs"); - this.getPackageManager().clearPackagePreferredActivities(this.getPackageName()); - if (BuildConfig.DEBUG) - Timber.w("Done clearing app data"); - } catch ( - Exception e) { - Timber.e(e); - } + @SuppressLint("RestrictedApi") + // view is nullable because it's called from xml + public void resetApp() { + // cant show a dialog because android is throwing a fit so heres hoping anybody who calls this method is otherwise confirming that the user wants to reset the app + Timber.w("Resetting app..."); + // recursively delete the app's data + ((ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE)).clearApplicationUserData(); } public boolean isInForeground() { // determine if the app is in the foreground ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); - if (activityManager != null) { - List appProcesses = activityManager.getRunningAppProcesses(); - if (appProcesses != null) { - for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { - if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - for (String activeProcess : appProcess.pkgList) { - if (activeProcess.equals(this.getPackageName())) { - return true; - } - } - return false; - } - } + List appProcesses = activityManager.getRunningAppProcesses(); + if (appProcesses == null) { + return false; + } + final String packageName = this.getPackageName(); + for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { + if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) { + return true; } - } else { - Timber.e("Failed to get activity manager"); } return false; } diff --git a/app/src/main/java/com/fox2code/mmm/SetupActivity.java b/app/src/main/java/com/fox2code/mmm/SetupActivity.java index 00465ea..7e751ab 100644 --- a/app/src/main/java/com/fox2code/mmm/SetupActivity.java +++ b/app/src/main/java/com/fox2code/mmm/SetupActivity.java @@ -74,10 +74,7 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { ActivitySetupBinding binding = ActivitySetupBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); - // Show setup box. Put the setup_box in the main activity layout - View view = binding.setupBox; - // Make the setup_box linear layout the sole child of the root_container constraint layout - setContentView(view); + View view = binding.getRoot(); ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check))).setChecked(BuildConfig.ENABLE_AUTO_UPDATER); ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting))).setChecked(BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING); // assert that both switches match the build config on debug builds @@ -276,13 +273,11 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { Timber.d("Creating Realm databases"); // create the realm database for ReposList // next, create the realm database for ReposList - RealmConfiguration config2 = new RealmConfiguration.Builder().name("ReposList.realm").directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); + 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) { - // drop the database if it exists - realm1.executeTransactionAsync(realm2 -> realm2.delete(ReposList.class)); // 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 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 5e26e90..7723415 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java @@ -41,6 +41,7 @@ import timber.log.Timber; @SuppressWarnings("KotlinInternalInJava") public final class AndroidacyRepoData extends RepoData { + public String[][] userInfo = new String[][]{{"role", null}, {"permissions", null}}; public static String token = MainApplication.getINSTANCE().getSharedPreferences("androidacy", 0).getString("pref_androidacy_api_token", null); @@ -140,6 +141,9 @@ public final class AndroidacyRepoData extends RepoData { byte[] resp = Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token + "&device_id=" + deviceId, false); JSONObject jsonObject = new JSONObject(new String(resp)); memberLevel = jsonObject.getString("role"); + JSONArray memberPermissions = jsonObject.getJSONArray("permissions"); + // set role and permissions on userInfo property + userInfo = new String[][]{{"role", memberLevel}, {"permissions", String.valueOf(memberPermissions)}}; String status = jsonObject.getString("status"); if (status.equals("success")) { return true; diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java index 8d2eaeb..e022222 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java @@ -105,14 +105,16 @@ public class RepoData extends XRepo { this.defaultName = url; // Set url as default name this.forceHide = AppUpdateManager.shouldForceHide(this.id); // this.enable is set from the database - RealmConfiguration realmConfiguration = new RealmConfiguration.Builder() - .name("ReposList.realm") - .schemaVersion(1) - .allowQueriesOnUiThread(true) - .allowWritesOnUiThread(true) - .build(); + RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm = Realm.getInstance(realmConfiguration); ReposList reposList = realm.where(ReposList.class).equalTo("id", this.id).findFirst(); + if (BuildConfig.DEBUG) { + if (reposList == null) { + Timber.d("RepoData for %s not found in database", this.id); + } else { + Timber.d("RepoData for %s found in database", this.id); + } + } Timber.d("RepoData: " + this.id + ". record in database: " + (reposList != null ? reposList.toString() : "none")); this.enabled = (!this.forceHide && reposList != null && reposList.isEnabled()); this.defaultWebsite = "https://" + Uri.parse(url).getHost() + "/"; @@ -140,6 +142,7 @@ public class RepoData extends XRepo { Timber.w("Failed to load repo metadata from database: " + e.getMessage() + ". If this is a first time run, this is normal."); } } + realm.close(); } private static boolean isNonNull(String str) { 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 8ab4c88..b284328 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -409,7 +409,7 @@ public final class RepoManager extends SyncManager { private AndroidacyRepoData addAndroidacyRepoData() { // cache dir is actually under app data - File cacheRoot = new File(this.mainApplication.getDataDir(), "repos/androidacy_repo"); + File cacheRoot = this.mainApplication.getDataDirWithPath("realms/repos/androidacy_repo"); SharedPreferences sharedPreferences = this.mainApplication.getSharedPreferences("mmm_androidacy_repo", Context.MODE_PRIVATE); AndroidacyRepoData repoData = new AndroidacyRepoData(cacheRoot, sharedPreferences, MainApplication.isAndroidacyTestMode()); this.repoData.put(ANDROIDACY_MAGISK_REPO_ENDPOINT, repoData); diff --git a/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java b/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java index acd9cec..47cdd8d 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java @@ -54,11 +54,7 @@ public class RepoUpdater { Realm realm = Realm.getInstance(realmConfiguration); RealmResults results = realm.where(ModuleListCache.class).equalTo("repoId", this.repoData.id).findAll(); // reposlist realm - RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder() - .name("ReposList.realm") - .schemaVersion(1) - .modules(new ReposList()) - .build(); + RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm2 = Realm.getInstance(realmConfiguration2); ReposList reposList = realm2.where(ReposList.class).equalTo("id", this.repoData.id).findFirst(); this.toUpdate = Collections.emptyList(); 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 c9b03ed..7402683 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -86,6 +86,7 @@ import java.util.Random; import io.realm.Realm; import io.realm.RealmConfiguration; +import io.realm.RealmResults; import timber.log.Timber; public class SettingsActivity extends FoxActivity implements LanguageActivity { @@ -383,9 +384,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { // Clear app data new MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.clear_data_dialogue_title).setMessage(R.string.clear_data_dialogue_message).setPositiveButton(R.string.yes, (dialog, which) -> { // Clear app data - MainApplication.getINSTANCE().clearAppData(); - // Restart app - ProcessHelper.restartApplicationProcess(requireContext()); + MainApplication.getINSTANCE().resetApp(); }).setNegativeButton(R.string.no, (dialog, which) -> { }).show(); return true; @@ -787,9 +786,32 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm = Realm.getInstance(realmConfiguration); ReposList repoRealmResults = realm.where(ReposList.class).equalTo("id", "androidacy_repo").findFirst(); - assert repoRealmResults != null; + if (repoRealmResults == null) { + // log the entries in the realm db and throw an illegal state exception + RealmResults reposListRealmResults = realm.where(ReposList.class).findAll(); + if (reposListRealmResults.isEmpty()) { + throw new IllegalStateException("Realm db is empty"); + } + for (ReposList reposList2 : reposListRealmResults) { + Timber.d("Realm db entry: %s %s %s", reposList2.getId(), reposList2.getName(), reposList2.isEnabled()); + } + throw new IllegalStateException("Androidacy repo not found in realm db"); + } boolean androidacyRepoEnabledPref = repoRealmResults.isEnabled(); if (androidacyRepoEnabledPref) { + // get user role from AndroidacyRepoData.userInfo + String[][] userInfo = AndroidacyRepoData.getInstance().userInfo; + if (userInfo != null) { + String userRole = userInfo[0][1]; + if (!Objects.equals(userRole, "Guest")) { + // Disable the pref_androidacy_repo_api_token preference + LongClickablePreference prefAndroidacyRepoApiD = Objects.requireNonNull(findPreference("pref_androidacy_repo_donate")); + prefAndroidacyRepoApiD.setEnabled(false); + prefAndroidacyRepoApiD.setSummary(R.string.upgraded_summary); + prefAndroidacyRepoApiD.setTitle(R.string.upgraded); + prefAndroidacyRepoApiD.setIcon(R.drawable.baseline_check_24); + } + } String[] originalApiKeyRef = new String[]{MainApplication.getINSTANCE().getSharedPreferences("androidacy", 0).getString("pref_androidacy_api_token", "")}; // Get the dummy pref_androidacy_repo_api_token preference with id pref_androidacy_repo_api_token // we have to use the id because the key is different @@ -913,7 +935,16 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { @SuppressLint("RestrictedApi") public void updateCustomRepoList(boolean initial) { - final SharedPreferences sharedPreferences = Objects.requireNonNull(this.getPreferenceManager().getSharedPreferences()); + RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); + Realm realm = Realm.getInstance(realmConfiguration); + // get all repos that are not built-in + int CUSTOM_REPO_ENTRIES = 0; + RealmResults customRepoDataDB = realm.where(ReposList.class).findAll(); + for (ReposList repo : customRepoDataDB) { + if (!repo.getId().equals("androidacy") && !repo.getId().equals("magisk_alt_repo")) { + CUSTOM_REPO_ENTRIES++; + } + } final CustomRepoManager customRepoManager = RepoManager.getINSTANCE().getCustomRepoManager(); for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) { CustomRepoData repoData = customRepoManager.getRepo(i); @@ -924,7 +955,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { continue; final int index = i; preference.setOnPreferenceClickListener(preference1 -> { - sharedPreferences.edit().remove("pref_custom_repo_" + index + "_enabled").apply(); + realm.beginTransaction(); + Objects.requireNonNull(realm.where(ReposList.class).equalTo("id", repoData.id).findFirst()).deleteFromRealm(); + realm.commitTransaction(); customRepoManager.removeRepo(index); updateCustomRepoList(false); return true; @@ -939,6 +972,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { preference = findPreference("pref_custom_add_repo_button"); if (preference == null) return; + int finalCUSTOM_REPO_ENTRIES = CUSTOM_REPO_ENTRIES; preference.setOnPreferenceClickListener(preference1 -> { final Context context = this.requireContext(); MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); @@ -984,7 +1018,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { input.addTextChangedListener(new TextWatcherAdapter() { @Override 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() < finalCUSTOM_REPO_ENTRIES); } }); positiveButton.setEnabled(false); diff --git a/app/src/main/res/layout/activity_crash_handler.xml b/app/src/main/res/layout/activity_crash_handler.xml index cd71453..ae7adde 100644 --- a/app/src/main/res/layout/activity_crash_handler.xml +++ b/app/src/main/res/layout/activity_crash_handler.xml @@ -138,7 +138,20 @@ android:text="@string/restart" /> - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 644c4f0..c1b6df1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -107,7 +107,7 @@ Show low-quality modules Some modules do not declare their metadata properly, causing visual glitches, - and/or indicating poor module quality.\nTurn this off at your own risk! + and/or indicating poor module quality.\nTurn this on at your own risk! DNS over HTTPS @@ -313,4 +313,8 @@ Copied stacktrace to clipboard! Stacktrace:\n%1$s It looks like crash reporting is disabled. Please enable it to submit feedback. + Reset the app + You\'re pretty awesome! Looks like you\'ve already upgraded your subscription and are supporting Androidacy. + Premium active + If you keep seeing this screen, resetting the app might help. This will clear app data but will not effect installed modules.This will completely remove all app data and close the app. Modules will not be uninstalled.ResetThis is going to completely wipe app data, but will not effect modules.