From 99c3cd2edeaffaa4a568e5b8599c6cc44dfa1c97 Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Tue, 4 Apr 2023 18:12:32 -0400 Subject: [PATCH] switch to non-transitive r classes and more Signed-off-by: androidacy-user --- .../java/com/fox2code/mmm/MainActivity.java | 4 +- .../com/fox2code/mmm/MainApplication.java | 17 +++-- .../com/fox2code/mmm/NotificationType.java | 12 ++-- .../java/com/fox2code/mmm/SetupActivity.java | 9 ++- .../mmm/androidacy/AndroidacyWebAPI.java | 4 +- .../mmm/module/ModuleViewAdapter.java | 6 +- .../fox2code/mmm/repo/CustomRepoManager.java | 63 +++++++++++++++++++ .../java/com/fox2code/mmm/repo/RepoData.java | 21 +++---- .../fox2code/mmm/utils/sentry/SentryMain.java | 14 +++-- app/src/main/res/layout/activity_setup.xml | 9 +++ app/src/main/res/menu/setup_bottom_nav.xml | 1 + app/src/main/res/values/strings.xml | 1 + gradle.properties | 4 +- 13 files changed, 122 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index 439aac7..aae099c 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -357,8 +357,8 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe private void cardIconifyUpdate() { boolean iconified = this.searchView.isIconified(); - int backgroundAttr = iconified ? MainApplication.isMonetEnabled() ? R.attr.colorSecondaryContainer : // Monet is special... - R.attr.colorSecondary : R.attr.colorPrimarySurface; + int backgroundAttr = iconified ? MainApplication.isMonetEnabled() ? com.google.android.material.R.attr.colorSecondaryContainer : // Monet is special... + com.google.android.material.R.attr.colorSecondary : com.google.android.material.R.attr.colorPrimarySurface; Resources.Theme theme = this.searchCard.getContext().getTheme(); TypedValue value = new TypedValue(); theme.resolveAttribute(backgroundAttr, value, true); diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index df6bc0a..4157d3d 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -296,19 +296,18 @@ public class MainApplication extends FoxApplication implements androidx.work.Con @SuppressLint("NonConstantResourceId") public boolean isLightTheme() { - return switch (this.managerThemeResId) { - case R.style.Theme_MagiskModuleManager, R.style.Theme_MagiskModuleManager_Monet -> - (this.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES; - case R.style.Theme_MagiskModuleManager_Monet_Light, R.style.Theme_MagiskModuleManager_Light -> - true; - case R.style.Theme_MagiskModuleManager_Monet_Dark, R.style.Theme_MagiskModuleManager_Dark, R.style.Theme_MagiskModuleManager_Monet_Black, R.style.Theme_MagiskModuleManager_Black -> - false; - default -> super.isLightTheme(); + return switch (getPreferences("mmm").getString("pref_theme", "system")) { + case "system" -> this.isSystemLightTheme(); + case "dark", "black" -> false; + default -> true; }; } + private boolean isSystemLightTheme() { + return (this.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES; + } + @SuppressWarnings("unused") - @SuppressLint("NonConstantResourceId") public boolean isDarkTheme() { return !this.isLightTheme(); } diff --git a/app/src/main/java/com/fox2code/mmm/NotificationType.java b/app/src/main/java/com/fox2code/mmm/NotificationType.java index db5af0b..83ab7a7 100644 --- a/app/src/main/java/com/fox2code/mmm/NotificationType.java +++ b/app/src/main/java/com/fox2code/mmm/NotificationType.java @@ -29,14 +29,14 @@ interface NotificationTypeCst { } public enum NotificationType implements NotificationTypeCst { - DEBUG(R.string.debug_build, R.drawable.ic_baseline_bug_report_24, R.attr.colorSecondary, R.attr.colorOnSecondary) { + DEBUG(R.string.debug_build, R.drawable.ic_baseline_bug_report_24, com.google.android.material.R.attr.colorSecondary, com.google.android.material.R.attr.colorOnSecondary) { @Override public boolean shouldRemove() { return !BuildConfig.DEBUG; } }, SHOWCASE_MODE(R.string.showcase_mode, R.drawable.ic_baseline_lock_24, - R.attr.colorPrimary, R.attr.colorOnPrimary) { + androidx.appcompat.R.attr.colorPrimary, com.google.android.material.R.attr.colorOnPrimary) { @Override public boolean shouldRemove() { return !MainApplication.isShowcaseMode(); @@ -98,7 +98,7 @@ public enum NotificationType implements NotificationTypeCst { } }, UPDATE_AVAILABLE(R.string.app_update_available, R.drawable.ic_baseline_system_update_24, - R.attr.colorPrimary, R.attr.colorOnPrimary, v -> IntentHelper.openUrl(v.getContext(), + androidx.appcompat.R.attr.colorPrimary, com.google.android.material.R.attr.colorOnPrimary, v -> IntentHelper.openUrl(v.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/releases"), false) { @Override public boolean shouldRemove() { @@ -106,7 +106,7 @@ public enum NotificationType implements NotificationTypeCst { } }, INSTALL_FROM_STORAGE(R.string.install_from_storage, R.drawable.ic_baseline_storage_24, - R.attr.colorBackgroundFloating, R.attr.colorOnBackground, v -> { + androidx.appcompat.R.attr.colorBackgroundFloating, com.google.android.material.R.attr.colorOnBackground, v -> { FoxActivity compatActivity = FoxActivity.getFoxActivity(v); final File module = new File(compatActivity.getCacheDir(), "installer" + File.separator + "module.zip"); @@ -197,11 +197,11 @@ public enum NotificationType implements NotificationTypeCst { public final boolean special; NotificationType(@StringRes int textId, int iconId) { - this(textId, iconId, R.attr.colorError, R.attr.colorOnPrimary); + this(textId, iconId, androidx.appcompat.R.attr.colorError, com.google.android.material.R.attr.colorOnPrimary); } NotificationType(@StringRes int textId, int iconId, View.OnClickListener onClickListener) { - this(textId, iconId, R.attr.colorError, R.attr.colorOnPrimary, onClickListener); + this(textId, iconId, androidx.appcompat.R.attr.colorError, com.google.android.material.R.attr.colorOnPrimary, onClickListener); } NotificationType(@StringRes int textId, int iconId, int backgroundAttr, int foregroundAttr) { diff --git a/app/src/main/java/com/fox2code/mmm/SetupActivity.java b/app/src/main/java/com/fox2code/mmm/SetupActivity.java index df194ca..624581d 100644 --- a/app/src/main/java/com/fox2code/mmm/SetupActivity.java +++ b/app/src/main/java/com/fox2code/mmm/SetupActivity.java @@ -69,7 +69,6 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { case "transparent_light" -> setTheme(R.style.Theme_MagiskModuleManager_Transparent_Light); } - ActivitySetupBinding binding = ActivitySetupBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); View view = binding.getRoot(); @@ -159,6 +158,12 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { // Set up the buttons // Setup button BottomNavigationItemView setupButton = view.findViewById(R.id.setup_finish); + // enable finish button when user scrolls to the bottom + findViewById(R.id.setupNestedScrollView).setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { + if (scrollY > oldScrollY) { + setupButton.setEnabled(true); + } + }); setupButton.setOnClickListener(v -> { Timber.i("Setup button clicked"); // get instance of editor @@ -224,6 +229,8 @@ public class SetupActivity extends FoxActivity implements LanguageActivity { }); // Cancel button BottomNavigationItemView cancelButton = view.findViewById(R.id.cancel_setup); + // unselect the cancel button because it's selected by default + cancelButton.setSelected(false); cancelButton.setOnClickListener(v -> { Timber.i("Cancel button clicked"); // close the app diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java index 5d05b61..3847219 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyWebAPI.java @@ -465,7 +465,7 @@ public class AndroidacyWebAPI { public int getAccentColor() { Resources.Theme theme = this.activity.getTheme(); TypedValue typedValue = new TypedValue(); - theme.resolveAttribute(R.attr.colorPrimary, typedValue, true); + theme.resolveAttribute(androidx.appcompat.R.attr.colorPrimary, typedValue, true); if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) { return typedValue.data; } @@ -488,7 +488,7 @@ public class AndroidacyWebAPI { public int getBackgroundColor() { Resources.Theme theme = this.activity.getTheme(); TypedValue typedValue = new TypedValue(); - theme.resolveAttribute(R.attr.backgroundColor, typedValue, true); + theme.resolveAttribute(com.google.android.material.R.attr.backgroundColor, typedValue, true); if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) { return typedValue.data; } diff --git a/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java index b117dff..064d47d 100644 --- a/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java +++ b/app/src/main/java/com/fox2code/mmm/module/ModuleViewAdapter.java @@ -315,8 +315,8 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter moduleHashMap; - public final JSONObject supportedProperties = new JSONObject(); - private final Object populateLock = new Object(); public JSONObject metaDataCache; public long lastUpdate; public String name, website, support, donate, submitModule; @@ -108,12 +108,10 @@ public class RepoData extends XRepo { RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getExistingKey()).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); - } + 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()); @@ -208,7 +206,7 @@ public class RepoData extends XRepo { repoModule.propUrl = modulePropsUrl; repoModule.zipUrl = moduleZipUrl; repoModule.checksum = moduleChecksum; - // safety check must be overriden per repo. only androidacy repo has this flag currently + // safety check must be overridden per repo. only androidacy repo has this flag currently // repoModule.safe = module.optBoolean("safe", false); if (!moduleStars.isEmpty()) { try { @@ -315,13 +313,11 @@ public class RepoData extends XRepo { // reposlist realm RealmConfiguration realmConfiguration2 = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getExistingKey()).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build(); Realm realm2 = Realm.getInstance(realmConfiguration2); - boolean dbEnabled; + boolean dbEnabled = false; try { dbEnabled = Objects.requireNonNull(realm2.where(ReposList.class).equalTo("id", this.id).findFirst()).isEnabled(); } catch (Exception e) { Timber.e(e, "Error while updating enabled state for repo %s", this.id); - // for now, throw an exception - throw e; } this.enabled = (!this.forceHide) && dbEnabled; } @@ -390,6 +386,7 @@ public class RepoData extends XRepo { return diffMinutes > (BuildConfig.DEBUG ? 15 : 20); } else { Timber.d("Repo " + this.id + " should update could not find repo in database"); + Timber.d("This is probably an error, please report this to the developer"); return true; } } 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 f1e7611..7facc2d 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 @@ -16,6 +16,7 @@ import io.sentry.Sentry; import io.sentry.android.core.SentryAndroid; import io.sentry.android.fragment.FragmentLifecycleIntegration; import io.sentry.android.timber.SentryTimberIntegration; +import timber.log.Timber; public class SentryMain { public static final boolean IS_SENTRY_INSTALLED = true; @@ -27,16 +28,12 @@ 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.getPreferences("sentry"); - if (!Objects.equals(sharedPreferences.getString("last_shown_setup", null), "v1")) { - return; - } Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { SharedPreferences.Editor editor = MainApplication.getINSTANCE().getSharedPreferences("sentry", Context.MODE_PRIVATE).edit(); editor.putString("lastExitReason", "crash"); editor.putLong("lastExitTime", System.currentTimeMillis()); editor.apply(); + Timber.e(throwable, "Uncaught exception"); // open crash handler and exit Intent intent = new Intent(mainApplication, CrashHandler.class); // pass the entire exception to the crash handler @@ -47,10 +44,17 @@ public class SentryMain { intent.putExtra("lastEventId", String.valueOf(Sentry.getLastEventId())); intent.putExtra("crashReportingEnabled", isSentryEnabled()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + Timber.e("Starting crash handler"); mainApplication.startActivity(intent); + Timber.e("Exiting"); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(10); }); + // If first_launch pref is not false, refuse to initialize Sentry + SharedPreferences sharedPreferences = MainApplication.getPreferences("sentry"); + if (!Objects.equals(MainApplication.getPreferences("mmm").getString("last_shown_setup", null), "v1")) { + return; + } SentryAndroid.init(mainApplication, options -> { // If crash reporting is disabled, stop here. if (!MainApplication.isCrashReportingEnabled()) { diff --git a/app/src/main/res/layout/activity_setup.xml b/app/src/main/res/layout/activity_setup.xml index ce6c9cf..0f94d09 100644 --- a/app/src/main/res/layout/activity_setup.xml +++ b/app/src/main/res/layout/activity_setup.xml @@ -43,6 +43,15 @@ android:text="@string/setup_message" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" /> + + + diff --git a/app/src/main/res/menu/setup_bottom_nav.xml b/app/src/main/res/menu/setup_bottom_nav.xml index 6bdd1af..7a08dee 100644 --- a/app/src/main/res/menu/setup_bottom_nav.xml +++ b/app/src/main/res/menu/setup_bottom_nav.xml @@ -13,6 +13,7 @@ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2bf4f0b..29ea016 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -393,4 +393,5 @@ Send additional info in crash reports. This may include device identifiers and IP addresses. No data will be used for any other purpose besides analyzing crashes and improving performance. Error accessing WebView. Functionality may be impacted. + To enable the finish button, please scroll down and view all the options. diff --git a/gradle.properties b/gradle.properties index 1f83605..7abf153 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:ReservedCodeCacheSize=512m +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:ReservedCodeCacheSize=768m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects @@ -23,5 +23,3 @@ org.gradle.parallel=true android.enableR8.fullMode=true org.gradle.unsafe.configuration-cache=true android.defaults.buildfeatures.buildconfig=true -android.nonTransitiveRClass=false -android.nonFinalResIds=false