diff --git a/README.md b/README.md index 1b5ea4e..933d8f4 100644 --- a/README.md +++ b/README.md @@ -5,19 +5,19 @@ Important news -I have health problems that made me work slow on everything. -I don't like sharing my health problmes but it has been to much recently for me to keep it for myself. +I have health problems that made me work slow on everything. I don't like sharing my health problmes +but it has been to much recently for me to keep it for myself. -This has been too much for me recently, so my moderators (same that on telegram) +This has been too much for me recently, so my moderators (same that on telegram) will be handling the project for me for a while. -I had theses problems even before I started FoxMMM, the only reason no one noticed is because -I can work or go to any school because of how much pain and exhaustion I feel everyday. +I had theses problems even before I started FoxMMM, the only reason no one noticed is because I can +work or go to any school because of how much pain and exhaustion I feel everyday. The only two thing that helped me reduce the pain is making code and playing with firends. -Even tho I'm very slow at doing anything, the only thing that made me look like I was working -on this project at a normal speed like someone that work is because 75% of my time was on this project. +Even tho I'm very slow at doing anything, the only thing that made me look like I was working on +this project at a normal speed like someone that work is because 75% of my time was on this project. There was also some times I couldn't work on this projects for multiple days because of my health, sometimes I was forcing myself to change one line of code from this project because doing nothing @@ -25,33 +25,33 @@ was more painful that trying something while in pain. Spending time with my friend and working on this project was a sort of pain killer for me. -Even tho I received money from my parent and the governement for my health problems, -I didn't know what to do with it cause anything I could have bought had no use for me -because my extreme pain made me unable to use anything. (Even video games) - -My health issues also prevented me to do any project of greater complexcity that this, -and without community support I would have been physically unable to continue this project. +Even tho I received money from my parent and the governement for my health problems, I didn't know +what to do with it cause anything I could have bought had no use for me because my extreme pain made +me unable to use anything. (Even video games) +My health issues also prevented me to do any project of greater complexcity that this, and without +community support I would have been physically unable to continue this project. There was clues of my health problems, right on this project, and theses are the following: + - My commit time of day being random proving I have no jobs. - Me not commiting for entire week, or having only commited one line in a week. - Me taking too much time to publish release after I did the relase commit. - Me missing obvious bugs and being able to do simple task properly (Well maybe this last one is harder to proove via commit history) -But sine many peoples are faking health issues for clout, if any data-scientist want -to do an analysis to proove what it would make my day, and I would be happy to give money -if someone does that because I don't know what do to with my money at this point. +But sine many peoples are faking health issues for clout, if any data-scientist want to do an +analysis to proove what it would make my day, and I would be happy to give money if someone does +that because I don't know what do to with my money at this point. -This is really sickening peoples need to give proof for their mental/health -issues because some peoples fake having thoses issues for clout. +This is really sickening peoples need to give proof for their mental/health issues because some +peoples fake having thoses issues for clout. -If you want to use my health problems for coult, I don't care as long as you are respectful, -at least you won't be hurting peoples with mental/health issues by faking having thoses issues. +If you want to use my health problems for coult, I don't care as long as you are respectful, at +least you won't be hurting peoples with mental/health issues by faking having thoses issues. -I'll probably delete this section once my health would be gotten better, or at -least good enough for me to not be stuck on my bed at least once a day because of pain. +I'll probably delete this section once my health would be gotten better, or at least good enough for +me to not be stuck on my bed at least once a day because of pain. @@ -68,9 +68,10 @@ Main activity: [](screenshot-dark.jpg) [](screenshot-light.jpg) -## What is this? +## What is this? -The official Magisk has dropped support to download online modules, so I made Fox's Magisk Module Manager to help you download and install Magisk modules. +The official Magisk has dropped support to download online modules, so I made Fox's Magisk Module +Manager to help you download and install Magisk modules. **This app is not officially supported by Magisk or its developers** @@ -80,11 +81,13 @@ The official Magisk has dropped support to download online modules, so I made Fo ## Requirements Minimum: + - Android 5.0+ - Magisk 19.0+ - An internet connection Recommended: + - Android 6.0+ - Magisk 21.2+ - An internet connection @@ -93,17 +96,18 @@ Note: This app may require the use of a VPN in countries with a state wide firew ## For users -To install the app go to [releases](https://github.com/Fox2Code/FoxMagiskModuleManager/releases), +To install the app go to [releases](https://github.com/Fox2Code/FoxMagiskModuleManager/releases), and download and install the latest `.apk` on your device. ## Repositories Available - -The app currently use these two repos as module sources, each with their own benefits and drawback: +The app currently use these two repos as module sources, each with their own benefits and +drawbacks: (Note: Each module repo can be disabled in the settings of the app) (NoteĀ²: I do not own or actively monitor any of the repos or modules, **download at your own risk**) -#### [https://github.com/Magisk-Modules-Alt-Repo](https://github.com/Magisk-Modules-Alt-Repo) +#### [https://github.com/Magisk-Modules-Alt-Repo](https://github.com/Magisk-Modules-Alt-Repo) + - Accepting new modules [here](https://github.com/Magisk-Modules-Alt-Repo/submission) - Less restrictive than the original repo - Officially supported by Fox's mmm @@ -113,22 +117,25 @@ Support: [![GitHub issues](https://img.shields.io/github/issues/Magisk-Modules-Alt-Repo/submission)](https://github.com/Magisk-Modules-Alt-Repo/submission/issues) #### [https://www.androidacy.com/modules-repo/](https://www.androidacy.com/modules-repo/) + - Accepting new modules [here](https://www.androidacy.com/module-repository-applications/) - Modules downloadable easily outside the app - Officially supported by Fox's mmm -- Contains ads to help cover server costs +- May show ads to help cover infrastrcture costs. + - [Read more](https://www.androidacycom/doing-it-alone-the-what-the-how-and-the-why/) + | [Privacy policy](https://www.androidacy.com/privacy/) - Added features like module reviews, automatic VirusTotal scans, and more Support: [![Telegram Group](https://img.shields.io/endpoint?color=neon&style=flat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fandroidacy_discussions)](https://telegram.dog/androidacy_discussions) -If a module is in multiple repos, the manager will just pick the most up to date version -of the module, if a module is in multiple repos it will just use first registered repo. +If a module is in multiple repos, the manager will just pick the most up to date version of the +module, if a module is in multiple repos it will just use first registered repo. -Note: If you or a friend uploaded a module and it doesn't appear in your module -list you can disable the low quality filter in the app settings. -Go to the [developer documentation](DEVELOPERS.md) for more info. +Note: If you or a friend uploaded a module and it doesn't appear in your module list you can disable +the low quality filter in the app settings. +Go to the [developer documentation](docs/DEVELOPERS.md) for more info. ## For developers @@ -142,14 +149,15 @@ And if you want to be event fancier you can setup `config` to your own config ap It also add new ways to control the installer ui via a new `#!` command system It allow module developers to have a more customizable install experience -For more information please check the [developer documentation](DEVELOPERS.md) +For more information please check the [developer documentation](docs/DEVELOPERS.md) ## For translators We use Weblate for translations: https://translate.nift4.org/engage/foxmmm/ (Make sure to check your spam folder when registering) -If you do not want to register on the self-hosted Weblate instance, you can do a pull request on GitHub: +If you do not want to register on the self-hosted Weblate instance, you can do a pull request on +GitHub: See [`app/src/main/res/values/strings.xml`](https://github.com/Fox2Code/FoxMagiskModuleManager/blob/master/app/src/main/res/values/strings.xml) and [`app/src/main/res/values/arrays.xml`](https://github.com/Fox2Code/FoxMagiskModuleManager/blob/master/app/src/main/res/values/arrays.xml) @@ -159,46 +167,39 @@ If your language is right to left don't forget to set `lang_support_rtl` to `tru Translators are not expected to have any previous coding experience. ## License -See [LICENSE](LICENCE). Library licenses can be found in the licenses section of the app. - -Cronet is licensed under the Apache License, Version 2.0. Static libraries are licensed under -the BSD license. See [LICENSE](https://chromium.googlesource.com/chromium/src/+/master/LICENSE) -for more information. Libraries were built using the microg build script which can be found [here](https://github.com/microg/cronet-build). - -## I want to add my own repo - -To add you own repo to Fox's mmm it need to follow theses conditions: -- The module repo or at least one of it's owners must be known. -- Modules in the repo must be monitored, and malicious modules must be removed. -- Module repo must have a valid, working, automatically or frequently updated `modules.json` - ([Example](https://github.com/Magisk-Modules-Alt-Repo/json/blob/main/modules.json)) - -In addition of these initial condition the repo must follow these rules: -- Repos must process and take-down off their repo module where it's removal was requested - by their original author, even if their licences legally allow their distributions. -- Repos may collect and store "mixed anonymous data" without user permission - (Anonymous means no personal data, usernames, email, or IP addresses) - (Mixed means users data must be split and not that separate data is not linkable together) -- Temporary storage of IPs address without user consent is allowed for rate limiting, GeoIP, - security reason, and must not be used for any other purpose without user explicit consent. - (GeoIP is the process of getting the country of an IP address) -- Repos may not collect and/or distribute any personal data without informing users that they do so and offering a way to opt out -- Modules owners must be aware that their modules are being hosted on the repository - (This rule doesn't apply for modules from `Magisk-Modules-Repo` last updated before 2022) -- Modules owners must be aware of any change made of the distributed version of their modules. - -Please note Androidacy has their Module Repository Policies outlined [on their website](https://www.androidacy.com/module-requirements/?utm_source=foxmmm-readme&utm_medium=web). Please refer to that document for the latest changes regarding their Repository. - -If all of these conditions are met you can open an issue for review. -(And don't forget to include a link to the `modules.json`) - -If an existing repo is not respecting theses rules please open an issue. -If a repo is repeatedly violating these rule will be removed from the app. -Last update of theses rules are: 4 May 2022 - -Please note that these rules does not apply retroactively. -If your post an issue about rules violation they must violate both the version of -the rules at the moment of the incident and the latest version of the rules. -(This paragraph doesn't apply for license violation, legal requests, or illegal behaviour.) - -In addition, we advise you to contact the repo host beforehand to attempt to resolve any issues. This helps avoid unnecessary conflict, and most of the time will get your issue solved quickly! + +Fox's Magisk Manager, the icon, and names are copyright +2021-present [Fox2Code](https://github.com/Fox2Code). The Androidacy name, logo, integration, and +later portions of the code are copyright +2022-present [Androidacy](https://www.androidacy.com/?utm_source=fox-repo&utm_medium=web). See +[LICENSE](LICENCE) for details. Library licenses can be found in the licenses section of the app. + +Modules are not covered by this license, please check the license of each module before using it. + +Some third party backend services may be proprietary, please check their terms of service before +using them. + +## Disclaimer + +In no event shall the developer be liable for any special, direct, indirect, consequential, or +incidental damages or any damages whatsoever, whether in an action of contract, negligence or other +tort, arising out of or in connection with the use of the app or the contents of the app. The +developer reserves the right to make additions, deletions, or modification to the contents on the +app at any time without prior notice. + +This app is not affiliated with Magisk or its developers, nor with any of the module repos or +developers of the modules. + +## Add your own repos + +See [the documentation](docs/add-repo.md) + +## Issues with a repo + +If you have a problem with a repo, please contact the repo owner **first**. If you are unable to +reach them or they are not willing to help, you can contact us as a last resort. + +Default repo owners: + +- Androidacy: [Telegram](https://telegram.dog/androidacy_discussions) +- Magisk-Modules-Alt-Repo: [Telegram](https://github.com/Magisk-Modules-Alt-Repo/submission/issues) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 22a55de..5b06804 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ plugins { android { namespace "com.fox2code.mmm" compileSdk 33 - buildToolsVersion '30.0.3' + buildToolsVersion '33.0.0' signingConfigs { release { // Everything comes from local.properties @@ -111,8 +111,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_11 + targetCompatibility JavaVersion.VERSION_11 } lint { disable 'MissingTranslation' @@ -121,7 +121,7 @@ android { } aboutLibraries { - additionalLicenses = ["LGPL_3_0_only"] + additionalLicenses = ["LGPL_3_0_only", "Apache_2_0"] } // "true" is not allowed inside this block, use "hasSentryConfig" instead. @@ -190,10 +190,6 @@ configurations { implementation.exclude group: 'org.jetbrains', module: 'annotations' if (!hasSentryConfig) { implementation.exclude group: 'io.sentry', module: 'sentry-android' - implementation.exclude group: 'io.sentry', module: 'sentry-android-fragment' - implementation.exclude group: 'io.sentry', module: 'sentry-android-okhttp' - implementation.exclude group: 'io.sentry', module: 'sentry-android-core' - implementation.exclude group: 'io.sentry', module: 'sentry-android-ndk' } } @@ -230,11 +226,7 @@ dependencies { if (hasSentryConfig) { // Error reporting - defaultImplementation 'io.sentry:sentry-android:6.9.2' - defaultImplementation 'io.sentry:sentry-android-fragment:6.9.2' - defaultImplementation 'io.sentry:sentry-android-okhttp:6.9.2' - defaultImplementation 'io.sentry:sentry-android-core:6.9.2' - defaultImplementation 'io.sentry:sentry-android-ndk:6.9.2' + implementation 'io.sentry:sentry-android:6.9.2' } // Markdown @@ -243,7 +235,6 @@ dependencies { implementation "io.noties.markwon:image:4.6.2" implementation "io.noties.markwon:syntax-highlight:4.6.2" implementation 'com.google.net.cronet:cronet-okhttp:0.1.0' - // Ignore all org.chromium.net dependencies annotationProcessor "io.noties:prism4j-bundler:2.0.0" implementation "com.caverock:androidsvg:1.4" diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index de05278..4f80a54 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -309,7 +309,6 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe this.updateBlurState(); this.moduleViewListBuilder.setQuery(null); Log.i(TAG, "Item After"); - noodleDebugState = MainApplication.isDeveloper(); this.moduleViewListBuilder.refreshNotificationsUI(this.moduleViewAdapter); InstallerInitializer.tryGetMagiskPathAsync(new InstallerInitializer.Callback() { @Override diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index ef2f8ac..f4e1fb9 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -2,7 +2,6 @@ package com.fox2code.mmm; import android.annotation.SuppressLint; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -50,7 +49,6 @@ import io.noties.prism4j.annotations.PrismBundle; @PrismBundle(includeAll = true, grammarLocatorClassName = ".Prism4jGrammarLocator") public class MainApplication extends FoxApplication implements androidx.work.Configuration.Provider { - private static final String TAG = "MainApplication"; private static final String timeFormatString = "dd MMM yyyy"; // Example: 13 july 2001 private static final Shell.Builder shellBuilder; private static final long secret; @@ -69,8 +67,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con secret = new Random().nextLong(); } - // Provides the Context for the base application - public Context FoxApplication = this; @StyleRes private int managerThemeResId = R.style.Theme_MagiskModuleManager; private FoxThemeWrapper markwonThemeContext; @@ -143,7 +139,8 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } public static boolean isDeveloper() { - return BuildConfig.DEBUG || getSharedPreferences().getBoolean("developer", false); + if (BuildConfig.DEBUG) return true; + return getSharedPreferences().getBoolean("developer", false); } public static boolean isDisableLowQualityModuleFilter() { @@ -166,10 +163,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con return firstBoot; } - public static boolean hasGottenRootAccess() { - return getSharedPreferences().getBoolean("has_root_access", false); - } - public static void setHasGottenRootAccess(boolean bool) { getSharedPreferences().edit().putBoolean("has_root_access", bool).apply(); } @@ -205,10 +198,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con return this.markwon = markwon; } - public FoxThemeWrapper getMarkwonThemeContext() { - return this.markwonThemeContext; - } - @NonNull @Override public androidx.work.Configuration getWorkManagerConfiguration() { @@ -285,11 +274,6 @@ public class MainApplication extends FoxApplication implements androidx.work.Con if (INSTANCE == null) INSTANCE = this; relPackageName = this.getPackageName(); super.onCreate(); - /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - DynamicColors.applyToActivitiesIfAvailable(this, - new DynamicColorsOptions.Builder().setPrecondition( - (activity, theme) -> isMonetEnabled()).build()); - }*/ SharedPreferences sharedPreferences = MainApplication.getSharedPreferences(); // We are only one process so it's ok to do this SharedPreferences bootPrefs = MainApplication.bootSharedPreferences = this.getSharedPreferences("mmm_boot", MODE_PRIVATE); @@ -332,6 +316,10 @@ public class MainApplication extends FoxApplication implements androidx.work.Con } } + private Intent getIntent() { + return this.getPackageManager().getLaunchIntentForPackage(this.getPackageName()); + } + @Override public void onCreateFoxActivity(FoxActivity compatActivity) { super.onCreateFoxActivity(compatActivity); diff --git a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java index e26387b..7a16cb6 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyActivity.java @@ -179,8 +179,8 @@ public final class AndroidacyActivity extends FoxActivity { // Don't open non Androidacy urls inside WebView if (request.isForMainFrame() && !AndroidacyUtil.isAndroidacyLink(request.getUrl())) { if (downloadMode || backOnResume) return true; - Log.i(TAG, "Exiting WebView " + // hideToken in case isAndroidacyLink fail. - AndroidacyUtil.hideToken(request.getUrl().toString())); + Log.i(TAG, + "Exiting WebView " + AndroidacyUtil.hideToken(request.getUrl().toString())); IntentHelper.openUri(view.getContext(), request.getUrl().toString()); 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 17ea670..26aa6c6 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoData.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoData.java @@ -2,6 +2,7 @@ package com.fox2code.mmm.repo; import android.content.SharedPreferences; import android.net.Uri; +import android.util.Log; import androidx.annotation.NonNull; @@ -51,7 +52,7 @@ public class RepoData extends XRepo { this.defaultName = url; // Set url as default name this.forceHide = AppUpdateManager.shouldForceHide(this.id); this.enabled = (!this.forceHide) && MainApplication.getSharedPreferences() - .getBoolean("pref_" + this.id + "_enabled", this.isEnabledByDefault()); + .getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); this.defaultWebsite = "https://" + Uri.parse(url).getHost() + "/"; if (!this.cacheRoot.isDirectory()) { boolean mkdirs = this.cacheRoot.mkdirs(); @@ -206,14 +207,22 @@ public class RepoData extends XRepo { @Override public void setEnabled(boolean enabled) { this.enabled = enabled && !this.forceHide; + if (BuildConfig.DEBUG) { + Log.d("RepoData", + "Repo " + this.id + " enabled: " + this.enabled + " (forced: " + this.forceHide + ") with preferenceID: " + this.getPreferenceId()); + } MainApplication.getSharedPreferences().edit() .putBoolean("pref_" + this.getPreferenceId() + "_enabled", enabled).apply(); } public void updateEnabledState() { this.forceHide = AppUpdateManager.shouldForceHide(this.id); + if (BuildConfig.DEBUG) { + Log.d("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", this.isEnabledByDefault()); + .getBoolean("pref_" + this.getPreferenceId() + "_enabled", true); } public String getUrl() throws NoSuchAlgorithmException { 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 586fc38..c2479c8 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -138,7 +138,7 @@ public final class RepoManager extends SyncManager { case ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT: return "androidacy_repo"; default: - return "repo_" + Hashes.hashSha1( + return "repo_" + Hashes.hashSha256( url.getBytes(StandardCharsets.UTF_8)); } } @@ -223,26 +223,26 @@ public final class RepoManager extends SyncManager { RepoUpdater[] repoUpdaters = new RepoUpdater[repoDatas.length]; int moduleToUpdate = 0; for (int i = 0; i < repoDatas.length; i++) { - if (BuildConfig.DEBUG) Log.d("NoodleDebug", repoDatas[i].getName()); + if (BuildConfig.DEBUG) Log.d("RepoManager", "Fetching: " + repoDatas[i].getName()); moduleToUpdate += (repoUpdaters[i] = new RepoUpdater(repoDatas[i])).fetchIndex(); updateListener.update(STEP1 / repoDatas.length * (i + 1)); } - if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Updating meta-data"); + if (BuildConfig.DEBUG) Log.d("RepoManag3er", "Updating meta-data"); int updatedModules = 0; boolean allowLowQualityModules = MainApplication.isDisableLowQualityModuleFilter(); for (int i = 0; i < repoUpdaters.length; i++) { // Check if the repo is enabled if (!repoUpdaters[i].repoData.isEnabled()) { - if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Skipping disabled repo: " + repoUpdaters[i].repoData.getName()); + if (BuildConfig.DEBUG) Log.d("RepoManager", + "Skipping disabled repo: " + repoUpdaters[i].repoData.getName()); continue; } List repoModules = repoUpdaters[i].toUpdate(); RepoData repoData = repoDatas[i]; - if (BuildConfig.DEBUG) Log.d("NoodleDebug", repoData.getName()); - if (BuildConfig.DEBUG) Log.d(TAG, "Registering " + repoData.getName()); + if (BuildConfig.DEBUG) Log.d("RepoManager", "Registering " + repoData.getName()); for (RepoModule repoModule : repoModules) { - if (BuildConfig.DEBUG) Log.d("NoodleDebug", repoModule.id); + if (BuildConfig.DEBUG) Log.d("RepoManager", "Fetching module: " + repoModule.id); try { if (repoModule.propUrl != null && !repoModule.propUrl.isEmpty()) { @@ -280,7 +280,7 @@ public final class RepoManager extends SyncManager { } } } - if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Finishing update"); + if (BuildConfig.DEBUG) Log.d("RepoManager", "Finishing update"); this.hasInternet = false; // Check if we have internet connection // Attempt to contact connectivitycheck.gstatic.com/generate_204 @@ -304,11 +304,12 @@ public final class RepoManager extends SyncManager { for (int i = 0; i < repoDatas.length; i++) { // If repo is not enabled, skip if (!repoDatas[i].isEnabled()) { - if (BuildConfig.DEBUG) Log.d("NoodleDebug", + if (BuildConfig.DEBUG) Log.d("RepoManager", "Skipping " + repoDatas[i].getName() + " because it's disabled"); continue; } - if (BuildConfig.DEBUG) Log.d("NoodleDebug", repoUpdaters[i].repoData.getName()); + if (BuildConfig.DEBUG) Log.d("RepoManager", + "Finishing: " + repoUpdaters[i].repoData.getName()); this.repoLastSuccess = repoUpdaters[i].finish(); if (!this.repoLastSuccess) { Log.e(TAG, "Failed to update " + repoUpdaters[i].repoData.getName()); 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 44355e7..a904edd 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -324,6 +324,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { if (!SentryMain.IS_SENTRY_INSTALLED || !BuildConfig.DEBUG || InstallerInitializer.peekMagiskPath() == null) { // Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app + Log.d(TAG, String.format("Sentry installed: %s, debug: %s, magisk path: %s", + SentryMain.IS_SENTRY_INSTALLED, BuildConfig.DEBUG, InstallerInitializer.peekMagiskPath())); Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false); } else { findPreference("pref_crash").setOnPreferenceClickListener(preference -> { @@ -864,12 +866,20 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { preference.setTitle(repoData.getName()); preference = findPreference(preferenceName + "_enabled"); if (preference != null) { - ((TwoStatePreference) preference).setChecked(repoData.isEnabled()); - preference.setTitle(repoData.isEnabled() ? R.string.repo_enabled : R.string.repo_disabled); - preference.setOnPreferenceChangeListener((p, newValue) -> { - p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled); - return true; - }); + // Handle custom repo separately + if (repoData instanceof CustomRepoData) { + preference.setTitle(R.string.custom_repo_always_on); + // Disable the preference + preference.setEnabled(false); + return; + } else { + ((TwoStatePreference) preference).setChecked(repoData.isEnabled()); + preference.setTitle(repoData.isEnabled() ? R.string.repo_enabled : R.string.repo_disabled); + preference.setOnPreferenceChangeListener((p, newValue) -> { + p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled); + return true; + }); + } } preference = findPreference(preferenceName + "_website"); String homepage = repoData.getWebsite(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b8bf95..95c9762 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -203,4 +203,5 @@ Blur is not compatible with transparent themes. You are setting a transparent theme Transparent themes may have some inconsistencies and may not work on all ROMs. In additon, monet and blur will be disabled. You can change back at any time. + Custom repos are always on until you remove them. diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index 3e13f30..d85af87 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -90,12 +90,16 @@ + + app:switchTextOn="@string/custom_repo_always_on" /> + app:switchTextOn="@string/custom_repo_always_on" />/> + app:switchTextOn="@string/custom_repo_always_on" /> + app:switchTextOn="@string/custom_repo_always_on" /> + app:switchTextOn="@string/custom_repo_always_on" /> + + diff --git a/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java b/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java index 185904a..d5d0cb9 100644 --- a/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java +++ b/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java @@ -1,5 +1,8 @@ package com.fox2code.mmm.sentry; +import static io.sentry.TypeCheckHint.SENTRY_TYPE_CHECK_HINT; + +import android.annotation.SuppressLint; import android.net.Uri; import android.util.Log; @@ -7,23 +10,17 @@ import com.fox2code.mmm.BuildConfig; import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.androidacy.AndroidacyUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import java.io.IOException; import java.io.Writer; -import io.sentry.Breadcrumb; -import io.sentry.Hint; import io.sentry.JsonObjectWriter; import io.sentry.NoOpLogger; import io.sentry.Sentry; -import io.sentry.SentryOptions; -import io.sentry.TypeCheckHint; +import io.sentry.UserFeedback; import io.sentry.android.core.SentryAndroid; import io.sentry.android.fragment.FragmentLifecycleIntegration; -import io.sentry.android.okhttp.SentryOkHttpInterceptor; import io.sentry.hints.DiskFlushNotification; +import io.sentry.protocol.SentryId; public class SentryMain { public static final boolean IS_SENTRY_INSTALLED = true; @@ -33,6 +30,7 @@ public class SentryMain { * Initialize Sentry * Sentry is used for crash reporting and performance monitoring. The SDK is explcitly configured not to send PII, and server side scrubbing of sensitive data is enabled (which also removes IP addresses) */ + @SuppressLint("RestrictedApi") public static void initialize(final MainApplication mainApplication) { SentryAndroid.init(mainApplication, options -> { // If crash reporting is disabled, stop here. @@ -40,6 +38,12 @@ public class SentryMain { options.setDsn(""); } else { options.addIntegration(new FragmentLifecycleIntegration(mainApplication, true, true)); + options.setCollectAdditionalContext(true); + options.setAttachThreads(true); + options.setAttachStacktrace(true); + options.setEnableNdk(true); + // Intercept okhttp requests to add sentry headers + options.addInAppInclude("com.fox2code.mmm"); // Sentry sends ABSOLUTELY NO Personally Identifiable Information (PII) by default. // Already set to false by default, just set it again to make peoples feel safer. options.setSendDefaultPii(false); @@ -86,27 +90,36 @@ public class SentryMain { Log.i(TAG, stringBuilder.toString()); } if (MainApplication.isCrashReportingEnabled()) { + // Get user feedback + SentryId sentryId = event.getEventId(); + if (sentryId != null) { + UserFeedback userFeedback = new UserFeedback(sentryId); + userFeedback.setName("Anonymous"); + userFeedback.setEmail("test@test.com"); + userFeedback.setComments("No comments"); + Sentry.captureUserFeedback(userFeedback); + } return event; } else { // We need to do this to avoid crash delay on crash when the event is dropped DiskFlushNotification diskFlushNotification = hint.getAs( - TypeCheckHint.SENTRY_TYPE_CHECK_HINT, DiskFlushNotification.class); + SENTRY_TYPE_CHECK_HINT, DiskFlushNotification.class); if (diskFlushNotification != null) diskFlushNotification.markFlushed(); return null; } }); + // Filter breadrcrumb content from crash report. + options.setBeforeBreadcrumb((breadcrumb, hint) -> { + String url = (String) breadcrumb.getData("url"); + if (url == null || url.isEmpty()) return breadcrumb; + if ("cloudflare-dns.com".equals(Uri.parse(url).getHost())) + return null; + if (AndroidacyUtil.isAndroidacyLink(url)) { + breadcrumb.setData("url", AndroidacyUtil.hideToken(url)); + } + return breadcrumb; + }); } - // Filter breadrcrumb content from crash report. - options.setBeforeBreadcrumb((breadcrumb, hint) -> { - String url = (String) breadcrumb.getData("url"); - if (url == null || url.isEmpty()) return breadcrumb; - if ("cloudflare-dns.com".equals(Uri.parse(url).getHost())) - return null; - if (AndroidacyUtil.isAndroidacyLink(url)) { - breadcrumb.setData("url", AndroidacyUtil.hideToken(url)); - } - return breadcrumb; - }); }); } diff --git a/DEVELOPERS.md b/docs/DEVELOPERS.md similarity index 98% rename from DEVELOPERS.md rename to docs/DEVELOPERS.md index a54d800..51f7c2d 100644 --- a/DEVELOPERS.md +++ b/docs/DEVELOPERS.md @@ -100,7 +100,7 @@ NoteĀ²: For `minMagisk`, `XX.Y` is parsed as `XXY00`, so you can just put the Ma (For example `- Hello world` will be transformed to `[*] Hello world`, do not apply to modules installed from storage) Note: Fox's Mmm use fallback -[here](app/src/main/java/com/fox2code/mmm/utils/PropUtils.java#L36) +[here](../app/src/main/java/com/fox2code/mmm/utils/PropUtils.java#L36) for some modules Theses values are only used if not defined in the `module.prop` files So the original module maker can still override them @@ -173,7 +173,7 @@ mmm_exec hideLoading mmm_exec setSupportLink https://github.com/Fox2Code/FoxMagiskModuleManager ``` -[You may look at the examples modules and their codes.](examples) +[You may look at the examples modules and their codes.](../examples) ## Developer mode diff --git a/gradle.properties b/gradle.properties index 5e3f284..dec073f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,7 +16,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:Reserv # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true +# android.enableJetifier=true # Fox builds props mods org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 776e521..9f536c0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sun Jun 05 10:40:53 EDT 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME +zipStoreBase=GRADLE_USER_HOME \ No newline at end of file