diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 011b846..236ef3b 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -22,6 +22,7 @@ import android.view.inputmethod.EditorInfo; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; +import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; @@ -116,12 +117,12 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe URL.setURLStreamHandlerFactory(cronetURLStreamHandlerFactory); } catch ( Error e) { - Log.e(TAG, "Failed to install Cronet URLStreamHandlerFactory", e); + Log.e(TAG, "Failed to install Cronet URLStreamHandlerFactory"); } urlFactoryInstalled = true; } catch ( Throwable t) { - Log.e(TAG, "Failed to install CronetURLStreamHandlerFactory", t); + Log.e(TAG, "Failed to install CronetURLStreamHandlerFactory - other"); } } if (doSetupRestarting) { @@ -129,7 +130,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe } BackgroundUpdateChecker.onMainActivityCreate(this); super.onCreate(savedInstanceState); - if (!MainApplication.getSharedPreferences().getBoolean("first_run", true)) { + if (!MainApplication.getSharedPreferences().getBoolean("first_time_user", true)) { this.setActionBarExtraMenuButton(R.drawable.ic_baseline_settings_24, v -> { IntentHelper.startActivity(this, SettingsActivity.class); return true; @@ -735,10 +736,10 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe @SuppressLint({"InflateParams", "RestrictedApi", "UnspecifiedImmutableFlag", "ApplySharedPref"}) private void checkShowInitialSetup() { if (BuildConfig.DEBUG) - Log.i("SetupWizard", "Do setup now"); + Log.i("SetupWizard", "Checking if we need to run setup"); // Check if this is the first launch SharedPreferences prefs = MainApplication.getSharedPreferences(); - boolean firstLaunch = prefs.getBoolean("first_launch", true); + boolean firstLaunch = prefs.getBoolean("first_time_user", true); if (BuildConfig.DEBUG) Log.i("SetupWizard", "First launch: " + firstLaunch); if (firstLaunch) { @@ -759,31 +760,72 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe // Repos are a little harder, as the enabled_repos build config is an arraylist ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_androidacy_repo))).setChecked(BuildConfig.ENABLED_REPOS.contains("androidacy_repo")); ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_magisk_alt_repo))).setChecked(BuildConfig.ENABLED_REPOS.contains("magisk_alt_repo")); + // On debug builds, log when a switch is toggled + if (BuildConfig.DEBUG) { + ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check))).setOnCheckedChangeListener((buttonView, isChecked) -> Log.i("SetupWizard", "Background Update Check: " + isChecked)); + ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting))).setOnCheckedChangeListener((buttonView, isChecked) -> Log.i("SetupWizard", "Crash Reporting: " + isChecked)); + ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_androidacy_repo))).setOnCheckedChangeListener((buttonView, isChecked) -> Log.i("SetupWizard", "Androidacy Repo: " + isChecked)); + ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_magisk_alt_repo))).setOnCheckedChangeListener((buttonView, isChecked) -> Log.i("SetupWizard", "Magisk Alt Repo: " + isChecked)); + } // Set up the buttons // Cancel button MaterialButton cancelButton = view.findViewById(R.id.setup_cancel); cancelButton.setText(R.string.cancel); cancelButton.setOnClickListener(v -> { // Set first launch to false and finish the activity - prefs.edit().putBoolean("first_launch", false).commit(); + prefs.edit().putBoolean("first_time_user", false).commit(); finish(); + startActivity(getIntent()); }); // Setup button MaterialButton setupButton = view.findViewById(R.id.setup_continue); - setupButton.setText(R.string.setup_button); setupButton.setOnClickListener(v -> { // Set first launch to false - prefs.edit().putBoolean("first_launch", false).commit(); + // get instance of editor + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("first_time_user", false); // Set the background update check pref - prefs.edit().putBoolean("pref_background_update_check", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check))).isChecked()).commit(); + editor.putBoolean("pref_background_update_check", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_background_update_check))).isChecked()); // Set the crash reporting pref - prefs.edit().putBoolean("pref_crash_reporting", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting))).isChecked()).commit(); + editor.putBoolean("pref_crash_reporting", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_crash_reporting))).isChecked()); // Set the repos // first pref_magisk_alt_repo_enabled then pref_androidacy_repo_enabled - prefs.edit().putBoolean("pref_magisk_alt_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_magisk_alt_repo))).isChecked()).commit(); - prefs.edit().putBoolean("pref_androidacy_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_androidacy_repo))).isChecked()).commit(); - // Finish the activity + editor.putBoolean("pref_magisk_alt_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_magisk_alt_repo))).isChecked()); + editor.putBoolean("pref_androidacy_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(view.findViewById(R.id.setup_androidacy_repo))).isChecked()); + // Loop through the setup_theme radio group and set the theme pref + RadioGroup themeRadioGroup = view.findViewById(R.id.setup_theme); + int selectedTheme = themeRadioGroup.getCheckedRadioButtonId(); + // system, light, dark, black, and transparent_light + if (selectedTheme == R.id.setup_theme_light) { + editor.putString("pref_theme", "light"); + } else if (selectedTheme == R.id.setup_theme_dark) { + editor.putString("pref_theme", "dark"); + } else if (selectedTheme == R.id.setup_theme_system) { + editor.putString("pref_theme", "system"); + } else if (selectedTheme == R.id.setup_theme_black) { + editor.putString("pref_theme", "black"); + } else if (selectedTheme == R.id.setup_theme_transparent_light) { + editor.putString("pref_theme", "transparent_light"); + } + // Commit the changes + editor.commit(); + // Sleep for 1 second to allow the user to see the changes + try { + Thread.sleep(500); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // Log the changes if debug + if (BuildConfig.DEBUG) { + Log.i("SetupWizard", "Background update check: " + prefs.getBoolean("pref_background_update_check", false)); + Log.i("SetupWizard", "Crash reporting: " + prefs.getBoolean("pref_crash_reporting", false)); + Log.i("SetupWizard", "Magisk Alt Repo: " + prefs.getBoolean("pref_magisk_alt_repo_enabled", false)); + Log.i("SetupWizard", "Androidacy Repo: " + prefs.getBoolean("pref_androidacy_repo_enabled", false)); + } + // Restart the activity + doSetupRestarting = true; finish(); + startActivity(getIntent()); }); } else { ensurePermissions(); 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 c97c345..76d4da8 100644 --- a/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java +++ b/app/src/main/java/com/fox2code/mmm/background/BackgroundUpdateChecker.java @@ -78,7 +78,7 @@ public class BackgroundUpdateChecker extends Worker { public static void onMainActivityCreate(Context context) { // Refuse to run if first_launch pref is not false - if (MainApplication.getSharedPreferences().getBoolean("first_launch", true)) + if (MainApplication.getSharedPreferences().getBoolean("first_time_user", true)) return; NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context); notificationManagerCompat.createNotificationChannel(new NotificationChannelCompat.Builder(NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_HIGH).setShowBadge(true).setName(context.getString(R.string.notification_update_pref)).build()); 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 d736b28..c354627 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java @@ -30,17 +30,16 @@ import java.util.Iterator; import java.util.List; public class RepoData extends XRepo { - private final Object populateLock = new Object(); public final String url; public final String id; public final File cacheRoot; public final SharedPreferences cachedPreferences; public final File metaDataCache; public final HashMap moduleHashMap; + private final Object populateLock = new Object(); public long lastUpdate; - protected String defaultName, defaultWebsite, - defaultSupport, defaultDonate, defaultSubmitModule; public String name, website, support, donate, submitModule; + protected String defaultName, defaultWebsite, defaultSupport, defaultDonate, defaultSubmitModule; private boolean forceHide, enabled; // Cache for speed public RepoData(String url, File cacheRoot, SharedPreferences cachedPreferences) { @@ -52,8 +51,7 @@ public class RepoData extends XRepo { this.moduleHashMap = new HashMap<>(); this.defaultName = url; // Set url as default name this.forceHide = AppUpdateManager.shouldForceHide(this.id); - this.enabled = (!this.forceHide) && MainApplication.getSharedPreferences() - .getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); + this.enabled = (!this.forceHide) && MainApplication.getSharedPreferences().getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); this.defaultWebsite = "https://" + Uri.parse(url).getHost() + "/"; if (!this.cacheRoot.isDirectory()) { boolean mkdirs = this.cacheRoot.mkdirs(); @@ -67,14 +65,14 @@ public class RepoData extends XRepo { this.lastUpdate = 0; // Don't allow time travel } try { - List modules = this.populate(new JSONObject( - new String(Files.read(this.metaDataCache), StandardCharsets.UTF_8))); + List modules = this.populate(new JSONObject(new String(Files.read(this.metaDataCache), StandardCharsets.UTF_8))); for (RepoModule repoModule : modules) { if (!this.tryLoadMetadata(repoModule)) { repoModule.moduleInfo.flags &= ~ModuleInfo.FLAG_METADATA_INVALID; } } - } catch (Exception e) { + } catch ( + Exception e) { boolean delete = this.metaDataCache.delete(); if (!delete) { throw new RuntimeException("Failed to delete invalid cache file"); @@ -84,6 +82,10 @@ public class RepoData extends XRepo { } } + private static boolean isNonNull(String str) { + return str != null && !str.isEmpty() && !"null".equals(str); + } + protected boolean prepare() throws NoSuchAlgorithmException { return true; } @@ -92,8 +94,7 @@ public class RepoData extends XRepo { List newModules = new ArrayList<>(); synchronized (this.populateLock) { String name = jsonObject.getString("name").trim(); - String nameForModules = name.endsWith(" (Official)") ? - name.substring(0, name.length() - 11) : name; + String nameForModules = name.endsWith(" (Official)") ? name.substring(0, name.length() - 11) : name; long lastUpdate = jsonObject.getLong("last_update"); for (RepoModule repoModule : this.moduleHashMap.values()) { repoModule.processed = false; @@ -104,8 +105,8 @@ public class RepoData extends XRepo { JSONObject module = array.getJSONObject(i); String moduleId = module.getString("id"); // Deny remote modules ids shorter than 3 chars or containing null char or space - if (moduleId.length() < 3 || moduleId.indexOf('\0') != -1 || - moduleId.indexOf(' ') != -1 || "ak3-helper".equals(moduleId)) continue; + if (moduleId.length() < 3 || moduleId.indexOf('\0') != -1 || moduleId.indexOf(' ') != -1 || "ak3-helper".equals(moduleId)) + continue; long moduleLastUpdate = module.getLong("last_update"); String moduleNotesUrl = module.getString("notes_url"); String modulePropsUrl = module.getString("prop_url"); @@ -119,8 +120,7 @@ public class RepoData extends XRepo { this.moduleHashMap.put(moduleId, repoModule); newModules.add(repoModule); } else { - if (repoModule.lastUpdated < moduleLastUpdate || - repoModule.moduleInfo.hasFlag(ModuleInfo.FLAG_METADATA_INVALID)) { + if (repoModule.lastUpdated < moduleLastUpdate || repoModule.moduleInfo.hasFlag(ModuleInfo.FLAG_METADATA_INVALID)) { newModules.add(repoModule); } } @@ -135,12 +135,16 @@ public class RepoData extends XRepo { try { repoModule.qualityValue = Integer.parseInt(moduleStars); repoModule.qualityText = R.string.module_stars; - } catch (NumberFormatException ignored) {} + } catch ( + NumberFormatException ignored) { + } } else if (!moduleDownloads.isEmpty()) { try { repoModule.qualityValue = Integer.parseInt(moduleDownloads); repoModule.qualityText = R.string.module_downloads; - } catch (NumberFormatException ignored) {} + } catch ( + NumberFormatException ignored) { + } } } // Remove no longer existing modules @@ -173,7 +177,7 @@ public class RepoData extends XRepo { return BuildConfig.ENABLED_REPOS.contains(this.id); } - public void storeMetadata(RepoModule repoModule,byte[] data) throws IOException { + public void storeMetadata(RepoModule repoModule, byte[] data) throws IOException { Files.write(new File(this.cacheRoot, repoModule.id + ".prop"), data); } @@ -182,14 +186,14 @@ public class RepoData extends XRepo { if (file.exists()) { try { ModuleInfo moduleInfo = repoModule.moduleInfo; - PropUtils.readProperties(moduleInfo, file.getAbsolutePath(), - repoModule.repoName + "/" + moduleInfo.name, false); + PropUtils.readProperties(moduleInfo, file.getAbsolutePath(), repoModule.repoName + "/" + moduleInfo.name, false); moduleInfo.flags &= ~ModuleInfo.FLAG_METADATA_INVALID; if (moduleInfo.version == null) { moduleInfo.version = "v" + moduleInfo.versionCode; } return true; - } catch (Exception ignored) { + } catch ( + Exception ignored) { boolean delete = file.delete(); if (!delete) { throw new RuntimeException("Failed to delete invalid metadata file"); @@ -202,6 +206,14 @@ public class RepoData extends XRepo { @Override public boolean isEnabled() { + SharedPreferences preferenceManager = MainApplication.getSharedPreferences(); + boolean enabled = preferenceManager.getBoolean("pref_" + this.id + "_enabled", this.isEnabledByDefault()); + if (this.enabled != enabled) { + if (BuildConfig.DEBUG) { + Log.d("NoodleDebug", "Repo " + this.id + " enable mismatch: " + this.enabled + " vs " + enabled); + } + this.enabled = enabled; + } return this.enabled; } @@ -209,11 +221,9 @@ public class RepoData extends XRepo { public void setEnabled(boolean enabled) { this.enabled = enabled && !this.forceHide; if (BuildConfig.DEBUG) { - Log.i("RepoData", - "Repo " + this.id + " enabled: " + this.enabled + " (forced: " + this.forceHide + ") with preferenceID: " + this.getPreferenceId()); + Log.i("RepoData", "Repo " + this.id + " enabled: " + this.enabled + " (forced: " + this.forceHide + ") with preferenceID: " + this.getPreferenceId()); } - MainApplication.getSharedPreferences().edit() - .putBoolean("pref_" + this.getPreferenceId() + "_enabled", enabled).apply(); + MainApplication.getSharedPreferences().edit().putBoolean("pref_" + this.getPreferenceId() + "_enabled", enabled).apply(); } public void updateEnabledState() { @@ -223,11 +233,9 @@ public class RepoData extends XRepo { } this.forceHide = AppUpdateManager.shouldForceHide(this.id); if (BuildConfig.DEBUG) { - Log.i("RepoData", - "Repo " + this.id + " update enabled: " + this.enabled + " (forced: " + this.forceHide + ") with preferenceID: " + this.getPreferenceId()); + Log.i("RepoData", "Repo " + this.id + " update enabled: " + this.enabled + " (forced: " + this.forceHide + ") with preferenceID: " + this.getPreferenceId()); } - this.enabled = (!this.forceHide) && MainApplication.getSharedPreferences() - .getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); + this.enabled = (!this.forceHide) && MainApplication.getSharedPreferences().getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); } public String getUrl() throws NoSuchAlgorithmException { @@ -238,10 +246,6 @@ public class RepoData extends XRepo { return this.id; } - private static boolean isNonNull(String str) { - return str != null && !str.isEmpty() && !"null".equals(str); - } - // Repo data info getters @NonNull @Override diff --git a/app/src/main/java/com/fox2code/mmm/utils/SentryMain.java b/app/src/main/java/com/fox2code/mmm/utils/SentryMain.java index 316d501..dc84c73 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/SentryMain.java +++ b/app/src/main/java/com/fox2code/mmm/utils/SentryMain.java @@ -27,7 +27,7 @@ public class SentryMain { public static void initialize(final MainApplication mainApplication) { // If first_launch pref is not false, refuse to initialize Sentry SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); - if (sharedPreferences.getBoolean("first_launch", true)) { + if (sharedPreferences.getBoolean("first_time_user", true)) { return; } Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { diff --git a/app/src/main/res/layout/setup_box.xml b/app/src/main/res/layout/setup_box.xml index e0ad932..e40f10a 100644 --- a/app/src/main/res/layout/setup_box.xml +++ b/app/src/main/res/layout/setup_box.xml @@ -1,5 +1,5 @@ - - - - + android:scrollbars="vertical"> @@ -25,19 +22,70 @@ android:id="@+id/setup_summary" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_below="@+id/setup_title" android:text="@string/setup_message" /> + android:layout_below="@id/setup_summary" + android:fillViewport="true" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> + + + + + + + + + + + + + + + + + + --> - - - - - - - - - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v26/themes.xml b/app/src/main/res/values-v26/themes.xml deleted file mode 100644 index 048aff5..0000000 --- a/app/src/main/res/values-v26/themes.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-v31/themes.xml b/app/src/main/res/values-v31/themes.xml index 3bf41aa..0527883 100644 --- a/app/src/main/res/values-v31/themes.xml +++ b/app/src/main/res/values-v31/themes.xml @@ -1,4 +1,4 @@ - + -