switch to non-transitive r classes

and more

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/299/head
androidacy-user 1 year ago
parent 1349327a29
commit 99c3cd2ede

@ -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);

@ -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();
}

@ -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) {

@ -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

@ -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;
}

@ -315,8 +315,8 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
if (drawable == null) {
this.cardView.setBackground(this.background);
}
int backgroundAttr = R.attr.colorBackgroundFloating;
int foregroundAttr = R.attr.colorOnBackground;
int backgroundAttr = androidx.appcompat.R.attr.colorBackgroundFloating;
int foregroundAttr = com.google.android.material.R.attr.colorOnBackground;
if (type == ModuleHolder.Type.NOTIFICATION) {
foregroundAttr = moduleHolder.notificationType.foregroundAttr;
backgroundAttr = moduleHolder.notificationType.backgroundAttr;
@ -352,7 +352,7 @@ public final class ModuleViewAdapter extends RecyclerView.Adapter<ModuleViewAdap
} else {
Resources.Theme theme = this.titleText.getContext().getTheme();
TypedValue value = new TypedValue();
theme.resolveAttribute(R.attr.colorOnBackground, value, true);
theme.resolveAttribute(com.google.android.material.R.attr.colorOnBackground, value, true);
this.buttonAction.setColorFilter(value.data);
this.titleText.setTextColor(value.data);
this.cardView.setBackground(null);

@ -4,10 +4,14 @@ import android.content.SharedPreferences;
import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.utils.io.PropUtils;
import com.fox2code.mmm.utils.io.net.Http;
import com.fox2code.mmm.utils.realm.ReposList;
import org.json.JSONObject;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import timber.log.Timber;
public class CustomRepoManager {
public static final int MAX_CUSTOM_REPOS = 5;
@ -82,6 +86,59 @@ public class CustomRepoManager {
int i = 0;
while (customRepos[i] != null) i++;
customRepos[i] = repo;
// fetch that sweet sweet json
byte[] json;
try {
json = Http.doHttpGet(repo, false);
} catch (Exception e) {
Timber.e(e, "Failed to fetch json from repo");
return null;
}
// get website, support, donate, submitModule. all optional. name is required.
// parse json
JSONObject jsonObject;
try {
jsonObject = new JSONObject(new String(json));
} catch (Exception e) {
Timber.e(e, "Failed to parse json from repo");
return null;
}
// get name
String name;
try {
name = jsonObject.getString("name");
} catch (Exception e) {
Timber.e(e, "Failed to get name from json");
return null;
}
// get website
String website;
try {
website = jsonObject.getString("website");
} catch (Exception e) {
website = null;
}
// get support
String support;
try {
support = jsonObject.getString("support");
} catch (Exception e) {
support = null;
}
// get donate
String donate;
try {
donate = jsonObject.getString("donate");
} catch (Exception e) {
donate = null;
}
// get submitModule
String submitModule;
try {
submitModule = jsonObject.getString("submitModule");
} catch (Exception e) {
submitModule = null;
}
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);
if (realm.isInTransaction()) {
@ -94,6 +151,12 @@ public class CustomRepoManager {
reposList = realm.createObject(ReposList.class, "repo_" + i);
}
reposList.setUrl(repo);
reposList.setName(name);
reposList.setWebsite(website);
reposList.setSupport(support);
reposList.setDonate(donate);
reposList.setSubmitModule(submitModule);
reposList.setEnabled(true);
realm.commitTransaction();
customReposCount++;
this.dirty = true;

@ -35,13 +35,13 @@ import io.realm.RealmResults;
import timber.log.Timber;
public class RepoData extends XRepo {
public final JSONObject supportedProperties = new JSONObject();
private final Object populateLock = new Object();
public String url;
public String id;
public File cacheRoot;
public SharedPreferences cachedPreferences;
public HashMap<String, RepoModule> 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;
}
}

@ -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()) {

@ -43,6 +43,15 @@
android:text="@string/setup_message"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
<!-- inform user that to finish setup, they need to scroll down -->
<com.google.android.material.textview.MaterialTextView
android:id="@+id/setup_scroll_down"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:text="@string/setup_scroll_down"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
<!-- Theme radio select. Options are system, light, dark, black, transparent_light -->
<!-- Button to trigger theme selection, half width, and in container with language -->

@ -13,6 +13,7 @@
<item
android:id="@+id/setup_finish"
android:checked="false"
android:enabled="false"
android:icon="@drawable/baseline_check_24"
android:title="@string/finish"
app:showAsAction="ifRoom" />

@ -393,4 +393,5 @@
<string name="setup_crash_reporting_pii">Send additional info in crash reports.</string>
<string name="setup_crash_reporting_pii_summary"> This may include device identifiers and IP addresses. No data will be used for any other purpose besides analyzing crashes and improving performance.</string>
<string name="error_creating_cookie_database">Error accessing WebView. Functionality may be impacted.</string>
<string name="setup_scroll_down">To enable the finish button, please scroll down and view all the options.</string>
</resources>

@ -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

Loading…
Cancel
Save