From 9c2d361a1c912a15dc937315b55bc29de8e0fe77 Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Wed, 24 Aug 2022 11:39:00 -0400 Subject: [PATCH 01/10] Update androidacy APIs Signed-off-by: androidacy-user --- README.md | 8 +-- app/build.gradle | 23 +++--- app/src/main/AndroidManifest.xml | 66 +++++++++++------ .../java/com/fox2code/mmm/MainActivity.java | 14 ++++ .../mmm/androidacy/AndroidacyRepoData.java | 70 +++++-------------- .../mmm/settings/SettingsActivity.java | 24 ++++++- app/src/main/res/values-cs/strings.xml | 1 + app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-es-rMX/strings.xml | 2 +- app/src/main/res/values-et/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-id/strings.xml | 1 + app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-nb-rNO/strings.xml | 2 +- app/src/main/res/values-night-v31/strings.xml | 4 ++ app/src/main/res/values-night/strings.xml | 4 ++ app/src/main/res/values-pl/strings.xml | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-sk/strings.xml | 1 + app/src/main/res/values-tr/strings.xml | 2 +- app/src/main/res/values-v23/strings.xml | 4 ++ app/src/main/res/values-v31/strings.xml | 4 ++ app/src/main/res/values-vi/strings.xml | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/root_preferences.xml | 9 +++ build.gradle | 4 +- 32 files changed, 161 insertions(+), 110 deletions(-) create mode 100644 app/src/main/res/values-night-v31/strings.xml create mode 100644 app/src/main/res/values-night/strings.xml create mode 100644 app/src/main/res/values-v23/strings.xml create mode 100644 app/src/main/res/values-v31/strings.xml diff --git a/README.md b/README.md index f2ec466..6540557 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ ## Fox Module contest -[NoStorageRestrict](https://github.com/Magisk-Modules-Alt-Repo/NoStorageRestrict) -by [@DanGLES3](https://github.com/DanGLES3) won via vote in community telegram server. +[NoStorageRestrict](https://github.com/Magisk-Modules-Alt-Repo/NoStorageRestrict) by [@DanGLES3](https://github.com/DanGLES3) won via vote in community telegram server. Module description: Removes the restriction when selecting folders (Downloads/Android) through the file manager on Android 11 and higher @@ -19,12 +18,11 @@ Main activity: ## What is this? -The official Magisk is dropping support to download online modules... -So I made my own app to do that! :3 +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** -**The modules shown in this app are not affiliated with this app** +**The modules shown in this app are not affiliated with this app or Magisk** (Please contact repo owners instead) ## Requirements diff --git a/app/build.gradle b/app/build.gradle index 2362ae3..d5465a1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'com.mikepenz.aboutlibraries.plugin' + id "io.sentry.android.gradle" version "3.1.4" } android { @@ -10,8 +11,8 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 33 - versionCode 53 - versionName "0.6.1" + versionCode 54 + versionName "0.7.0-dev" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -35,9 +36,9 @@ android { dimension "type" buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true" buildConfigField( - "java.util.List", - "ENABLED_REPOS", - "java.util.Arrays.asList(\"magisk_alt_repo\", \"dg_magisk_repo\", \"androidacy_repo\")", + "java.util.List", + "ENABLED_REPOS", + "java.util.Arrays.asList(\"magisk_alt_repo\", \"dg_magisk_repo\", \"androidacy_repo\")", ) } @@ -53,9 +54,9 @@ android { // Repo with ads or tracking feature are disabled by default for the // F-Droid flavor. buildConfigField( - "java.util.List", - "ENABLED_REPOS", - "java.util.Arrays.asList(\"magisk_alt_repo\")", + "java.util.List", + "ENABLED_REPOS", + "java.util.Arrays.asList(\"magisk_alt_repo\")", ) } } @@ -75,7 +76,7 @@ aboutLibraries { } configurations { - implementation.exclude group: 'org.jetbrains' , module: 'annotations' + implementation.exclude group: 'org.jetbrains', module: 'annotations' } dependencies { @@ -89,7 +90,7 @@ dependencies { implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.webkit:webkit:1.4.0' implementation 'com.google.android.material:material:1.6.1' - implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}" + implementation 'com.mikepenz:aboutlibraries:10.4.1-a01' implementation "dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0" implementation "dev.rikka.rikkax.insets:insets:1.3.0" implementation 'com.github.Dimezis:BlurView:version-1.6.6' @@ -113,7 +114,7 @@ dependencies { implementation "com.caverock:androidsvg:1.4" // Test - testImplementation 'junit:junit:4.+' + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6da80b2..49205b5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,9 @@ tools:ignore="QueryAllPackagesPermission"> - + @@ -16,36 +18,39 @@ - - + + + android:label="@string/title_activity_settings" + android:parentActivityName=".MainActivity"> @@ -53,8 +58,8 @@ + android:label="@string/app_name_short" + android:launchMode="singleTask"> @@ -62,10 +67,10 @@ @@ -73,30 +78,45 @@ - + android:parentActivityName=".MainActivity" + android:theme="@style/Theme.MagiskModuleManager"> - + + - - + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index ed9bd2e..d89c8ed 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -37,6 +37,7 @@ import com.google.android.material.progressindicator.LinearProgressIndicator; import eightbitlab.com.blurview.BlurView; import eightbitlab.com.blurview.RenderScriptBlur; +import io.sentry.android.core.SentryAndroid; public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRefreshListener, SearchView.OnQueryTextListener, SearchView.OnCloseListener, @@ -73,6 +74,19 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe @Override protected void onCreate(Bundle savedInstanceState) { + SentryAndroid.init(this, options -> { + // Add a callback that will be used before the event is sent to Sentry. + // With this callback, you can modify the event or, when returning null, also discard the event. + options.setBeforeSend((event, hint) -> { + // Check saved preferences to see if the user has opted out of crash reporting. + // If the user has opted out, return null. + if (SettingsActivity.getCrashReporting(this)) { + return event; + } else { + return null; + } + }); + }); this.initMode = true; BackgroundUpdateChecker.onMainActivityCreate(this); super.onCreate(savedInstanceState); 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 6f068eb..0a77530 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java @@ -21,24 +21,23 @@ import org.json.JSONObject; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; -import okhttp3.Cookie; import okhttp3.HttpUrl; @SuppressWarnings("KotlinInternalInJava") public final class AndroidacyRepoData extends RepoData { private static final String TAG = "AndroidacyRepoData"; - private static final HttpUrl OK_HTTP_URL; + static { HttpUrl.Builder OK_HTTP_URL_BUILDER = new HttpUrl.Builder().scheme("https"); // Using HttpUrl.Builder.host(String) crash the app OK_HTTP_URL_BUILDER.setHost$okhttp(".androidacy.com"); - OK_HTTP_URL = OK_HTTP_URL_BUILDER.build(); + OK_HTTP_URL_BUILDER.build(); } + // Avoid spamming requests to Androidacy private long androidacyBlockade = 0; private String token = null; @@ -60,26 +59,10 @@ public final class AndroidacyRepoData extends RepoData { this.defaultSupport = "https://t.me/androidacy_discussions"; this.defaultDonate = "https://www.androidacy.com/membership-join/?utm_source=foxmmm&utm-medium=app&utm_campaign=fox-inapp"; this.defaultSubmitModule = "https://www.androidacy.com/module-repository-applications/"; - this.host = testMode ? "staging-api.androidacy.com" : "api.androidacy.com"; + this.host = testMode ? "staging-api.androidacy.com" : "production-api.androidacy.com"; this.testMode = testMode; } - private static String getCookies() { - if (Http.hasWebView()) { - return CookieManager.getInstance().getCookie("https://.androidacy.com/"); - } else { - Iterator cookies = Http.getCookieJar() - .loadForRequest(OK_HTTP_URL).iterator(); - if (!cookies.hasNext()) return ""; - StringBuilder stringBuilder = new StringBuilder(); - while (true) { - stringBuilder.append(cookies.next().toString()); - if (!cookies.hasNext()) return stringBuilder.toString(); - stringBuilder.append(","); - } - } - } - public static AndroidacyRepoData getInstance() { return RepoManager.getINSTANCE().getAndroidacyRepoData(); } @@ -91,14 +74,8 @@ public final class AndroidacyRepoData extends RepoData { long time = System.currentTimeMillis(); if (this.androidacyBlockade > time) return false; this.androidacyBlockade = time + 30_000L; - String cookies = AndroidacyRepoData.getCookies(); - int start = cookies == null ? -1 : cookies.indexOf("USER=") + 5; - String token = null; - if (start != -1) { - int end = cookies.indexOf(";", start); - if (end != -1) - token = cookies.substring(start, end); - } + // Get token from androidacy_token shared preference + String token = this.cachedPreferences.getString("androidacy_token", null); if (token != null) { try { Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, true); @@ -110,14 +87,10 @@ public final class AndroidacyRepoData extends RepoData { return false; } Log.w(TAG, "Invalid token, resetting..."); - if (Http.hasWebView()) { - CookieManager.getInstance().setCookie("https://.androidacy.com/", - "USER=; expires=Thu, 01 Jan 1970 00:00:00 GMT;" + - " path=/; secure; domain=.androidacy.com"); - } else { - Http.getCookieJar().saveFromResponse( - OK_HTTP_URL, Collections.emptyList()); - } + // Remove saved preference + SharedPreferences.Editor editor = this.cachedPreferences.edit(); + editor.remove("androidacy_token"); + editor.apply(); this.token = token = null; } } @@ -126,22 +99,16 @@ public final class AndroidacyRepoData extends RepoData { Log.i(TAG, "Refreshing token..."); token = new String(Http.doHttpPost( "https://" + this.host + "/auth/register", - "",true), StandardCharsets.UTF_8); - if (Http.hasWebView()) { - CookieManager.getInstance().setCookie("https://.androidacy.com/", - "USER=" + token + "; expires=Fri, 31 Dec 9999 23:59:59 GMT;" + - " path=/; secure; domain=.androidacy.com"); - } else { - Http.getCookieJar().saveFromResponse(OK_HTTP_URL, - Collections.singletonList(Cookie.parse(OK_HTTP_URL, - "USER=" + token + "; expires=Fri, 31 Dec 9999 23:59:59 GMT;" + - " path=/; secure; domain=.androidacy.com"))); - } + "foxmmm=true", true), StandardCharsets.UTF_8); + // Save token to shared preference + SharedPreferences.Editor editor = this.cachedPreferences.edit(); + editor.putString("androidacy_token", token); + editor.apply(); } catch (Exception e) { if ("Received error code: 419".equals(e.getMessage()) || "Received error code: 429".equals(e.getMessage()) || "Received error code: 503".equals(e.getMessage()) - ) { + ) { Log.e(TAG, "We are being rate limited!", e); this.androidacyBlockade = time + 3_600_000L; } @@ -194,7 +161,7 @@ public final class AndroidacyRepoData extends RepoData { jsonObject.optString("zipUrl", "")); repoModule.notesUrl = filterURL( jsonObject.optString("notesUrl", "")); - if (repoModule.zipUrl == null) { + if (repoModule.zipUrl == null) { repoModule.zipUrl = // Fallback url in case the API doesn't have zipUrl "https://" + this.host + "/magisk/info/" + moduleId; } @@ -264,7 +231,8 @@ public final class AndroidacyRepoData extends RepoData { } @Override - public void storeMetadata(RepoModule repoModule, byte[] data) {} + public void storeMetadata(RepoModule repoModule, byte[] data) { + } @Override public boolean tryLoadMetadata(RepoModule repoModule) { 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 3f767f0..304ed05 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -17,6 +17,7 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentTransaction; import androidx.preference.ListPreference; import androidx.preference.Preference; @@ -61,6 +62,11 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { private static final String TAG = "SettingsActivity"; private static int devModeStep = 0; + public static boolean getCrashReporting(MainActivity mainActivity) { + return mainActivity.getPreferences(Context.MODE_PRIVATE) + .getBoolean("crash_reporting", true); + } + @Override protected void onCreate(Bundle savedInstanceState) { devModeStep = 0; @@ -124,6 +130,16 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { }, 1); return true; }); + // Crash reporting + TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting"); + crashReportingPreference.setChecked(getCrashReporting( + (MainActivity) requireActivity())); + crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> { + devModeStep = 0; + getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", + (boolean) newValue).apply(); + return true; + }); Preference enableBlur = findPreference("pref_enable_blur"); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { enableBlur.setSummary(R.string.require_android_6); @@ -277,6 +293,10 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { BuildConfig.VERSION_CODE + ")"); } + private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) { + return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit(); + } + private void openFragment(Fragment fragment, @StringRes int title) { FoxActivity compatActivity = getFoxActivity(this); compatActivity.setOnBackPressedCallback(this); @@ -384,9 +404,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } catch (IOException|JSONException e) { Log.e(TAG, "Failed to preload repo values", e); } - UiThreadHandler.handler.post(() -> { - updateCustomRepoList(false); - }); + UiThreadHandler.handler.post(() -> updateCustomRepoList(false)); } }.start(); } diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 646f642..4f11bdc 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -92,4 +92,5 @@ Povolit rozostření Repozitář povolen Repozitář zakázán + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 5a0b88a..cdb56aa 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -94,7 +94,6 @@ Repo hinzufügen Repo entfernen Eigene URL - Das Androidacy-Repo enthält Anzeigen und Tracker. Backup Modules Module wiederherstellen Dieser Vorgang erfordert eine Internetverbindung @@ -103,4 +102,5 @@ Beschreibung Deinstallieren Konfig + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 75b93ef..520c77d 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -124,7 +124,6 @@ Προσθήκη αποθετηρίου Αφαίρεση αποθετηρίου Προσαρμοσμένη διεύθυνση url - Το αποθετήριο Androidacy έχει διαφημίσεις και ιχνηλάτες. Εφεδρικά modules Επαναφορά module Αυτή η λειτουργία απαιτεί σύνδεση στο Διαδίκτυο @@ -144,4 +143,5 @@ Ορισμένες μεταφράσεις για την τρέχουσα γλώσσα δεν είναι ενημερωμένες, παρακαλούμε να συνεισφέρετε στις μεταφράσεις εφαρμογών στο GitHub Μεταφράστηκε απο Tha_14 + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 7de0d58..43ef05e 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -124,8 +124,8 @@ Añadir Repositorio Eliminar Repositorio URL Personalizado - El repositorio Androidacy tiene anuncios y trackers. Hacer copia de seguridad de los módulos Restaurar módulos Esta operación requiere una conexión a Internet. + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index efce5aa..ca51e6b 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -87,4 +87,5 @@ Hoidla lubatud Hoidla keelatud + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 88f5e11..87eab18 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -124,8 +124,8 @@ Ajouter dépôt Supprimer dépôt URL personnalisée - Le dépôt Androidacy utilise des publicités et des pisteurs. Sauvegarder les modules Restaurer les modules Cette opération requière une connexion internet + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 3815c05..83931fb 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -93,4 +93,5 @@ Aktifkan blur Repo diaktifkan Repo dinonaktifkan + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 367addf..32c54cd 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -127,7 +127,6 @@ Aggiungi Repository Rimuovi Repository Url personalizzato - La repository di Androidacy contiene pubblicità e tracker. Salva moduli Ripristina moduli Questa operazione richiede una connessione ad internet @@ -149,4 +148,5 @@ Traduzione di tugaia56 + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 39f4e9a..923042a 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -40,4 +40,5 @@ ソースコード 開発者モードが有効です Force English language + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 37b3d3e..521a3f9 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -94,5 +94,5 @@ Tilsløring Pakkebrønn på Pakkebrønn av - Androidacy-pakkebrønnen har reklame og sporere. + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-night-v31/strings.xml b/app/src/main/res/values-night-v31/strings.xml new file mode 100644 index 0000000..56b553c --- /dev/null +++ b/app/src/main/res/values-night-v31/strings.xml @@ -0,0 +1,4 @@ + + + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + \ No newline at end of file diff --git a/app/src/main/res/values-night/strings.xml b/app/src/main/res/values-night/strings.xml new file mode 100644 index 0000000..56b553c --- /dev/null +++ b/app/src/main/res/values-night/strings.xml @@ -0,0 +1,4 @@ + + + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 659a1d7..73f8383 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -124,7 +124,6 @@ Dodaj repozytorium Usuń repozytorium Niestandardowy URL - Repo Androidacy korzysta z reklam i trackerów. Kopia zapasowa modułów Przywracanie modułów Ta operacja wymaga połączenia internetowego @@ -147,4 +146,5 @@ prosimy o rozważenie uzupełnienia tłumaczeń aplikacji na GitHubie. Tłumaczenie: Daviteusz + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 3e13142..1977166 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -127,7 +127,6 @@ Adicionar Repositório Remover Repositórios URL Customizado - O Repositórios Androidacy possui anuncios e rastreadores. Fazer backup dos modulos Restaurar modulos Essa operação requer uma conexão com a internet @@ -149,4 +148,5 @@ Algumas traduções para sua lingua atual não esta em dia, por favor considere contribuir para as traduções do app no Github Traduzido por mi007d e DanGLES3 + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 2172cb1..9ee1fc3 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -119,7 +119,6 @@ Adăugare depozit Eliminare depozit URL personalizat - Depozitul Androidacy utilizează reclame și instrumente de urmărire. Rezervare module Restabilire module Această operațiune necesită o conexiune la Internet @@ -138,4 +137,5 @@ nu sunt actualizate, vă rugăm să luați în considerare contribuția la traducerea aplicației pe GitHub Tradus de Fox2Code + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 143cc46..5ab9ad7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -120,8 +120,8 @@ Добавить репо Убрать репо Свой URL - Репо Androidacy содержит рекламу и трекеры. Резервное копирование модулей Восстановить модули Для этого действия потребуется подключение к Интернету + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 70f7e4a..1ffe0c4 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -92,4 +92,5 @@ Povoliť rozostrenia Repozitár povolený Repozitár zakázaný + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 947ec9f..c8790fd 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -127,7 +127,6 @@ Repo ekle Repo\'yu kaldır Özel url - Androidacy repo\'da reklamlar ve takipçiler vardır. Modülleri yedekle Modülleri geri yükle Bu işlem bir internet bağlantısı gerektirir @@ -147,4 +146,5 @@ Şimdiki dil için bazı çeviriler güncel değil, lütfen GitHub\'daki uygulama çevirilerine katkıda bulunmayı düşünün Alprnn357 tarafından çevrildi + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-v23/strings.xml b/app/src/main/res/values-v23/strings.xml new file mode 100644 index 0000000..56b553c --- /dev/null +++ b/app/src/main/res/values-v23/strings.xml @@ -0,0 +1,4 @@ + + + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + \ No newline at end of file diff --git a/app/src/main/res/values-v31/strings.xml b/app/src/main/res/values-v31/strings.xml new file mode 100644 index 0000000..56b553c --- /dev/null +++ b/app/src/main/res/values-v31/strings.xml @@ -0,0 +1,4 @@ + + + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index c560c0b..997aaee 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -119,8 +119,8 @@ Thêm kho Gỡ kho Url tuỳ chỉnh - Kho Androidacy có các quảng cáo và trình theo dõi. Sao lưu mô-đun Khôi phục mô-đun Quá trình này yêu cầu kết nối internet + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 936a911..0fa7ca6 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -129,7 +129,6 @@ 添加库 移除库 自定义网址 - Androidacy repo具有广告和跟踪器. 备份模块 还原模块 此操作需要互联网连接 @@ -150,4 +149,5 @@ 请考虑为 GitHub 上的应用程序翻译做出贡献 由ender-zhao翻译 + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 0d080eb..21979bb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -120,7 +120,6 @@ 新增倉庫 移除倉庫 自定義網址 - Androidacy repo 內建廣告和跟蹤器. 備份模組 還原模組 需要網路連線 @@ -140,4 +139,5 @@ 如果您使用的當前語言沒有及時更新,請考慮在 GitHub 上的為翻譯做出貢獻。 由 OrStudio.tw(@crcky5322) 提供美妙的翻譯 + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2dbccca..7074e48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -129,7 +129,7 @@ Add Repo Remove Repo Custom url - The Androidacy repo has ads and trackers. + This repository may display some non-intrusive advertising to cover server and development costs. Backup modules Restore modules This operation require an internet connection @@ -152,4 +152,6 @@ not up-to-date, please consider contributing to the app translations on GitHub Translated by Fox2Code + Automatically report bugs and performance to the developers + If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index 5325cb9..eec6891 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -115,6 +115,15 @@ app:title="@string/prevent_reboot_pref" app:summary="@string/prevent_reboot_desc" app:singleLineTitle="false" /> + + + Date: Wed, 24 Aug 2022 21:42:51 +0200 Subject: [PATCH 02/10] Fix and improve previous commit & Update libraries --- app/build.gradle | 11 +++- .../java/com/fox2code/mmm/MainActivity.java | 13 ---- .../com/fox2code/mmm/MainApplication.java | 62 +++++++++++++++++++ .../mmm/settings/SettingsActivity.java | 8 +-- build.gradle | 2 +- 5 files changed, 72 insertions(+), 24 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d5465a1..a85e10c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,7 +12,7 @@ android { minSdk 21 targetSdk 33 versionCode 54 - versionName "0.7.0-dev" + versionName "0.6.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -35,6 +35,7 @@ android { "default" { dimension "type" buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true" + buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "true" buildConfigField( "java.util.List", "ENABLED_REPOS", @@ -51,6 +52,9 @@ android { // with our keys, so the APK wouldn't install anyways). buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "false" + // Respect privacy paranoiac nature of F-Droid builds + buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "false" + // Repo with ads or tracking feature are disabled by default for the // F-Droid flavor. buildConfigField( @@ -88,9 +92,10 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.webkit:webkit:1.4.0' + implementation 'androidx.webkit:webkit:1.5.0' implementation 'com.google.android.material:material:1.6.1' - implementation 'com.mikepenz:aboutlibraries:10.4.1-a01' + // Update root build.gradle instead. + implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}" implementation "dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0" implementation "dev.rikka.rikkax.insets:insets:1.3.0" implementation 'com.github.Dimezis:BlurView:version-1.6.6' diff --git a/app/src/main/java/com/fox2code/mmm/MainActivity.java b/app/src/main/java/com/fox2code/mmm/MainActivity.java index d89c8ed..8084b52 100644 --- a/app/src/main/java/com/fox2code/mmm/MainActivity.java +++ b/app/src/main/java/com/fox2code/mmm/MainActivity.java @@ -74,19 +74,6 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe @Override protected void onCreate(Bundle savedInstanceState) { - SentryAndroid.init(this, options -> { - // Add a callback that will be used before the event is sent to Sentry. - // With this callback, you can modify the event or, when returning null, also discard the event. - options.setBeforeSend((event, hint) -> { - // Check saved preferences to see if the user has opted out of crash reporting. - // If the user has opted out, return null. - if (SettingsActivity.getCrashReporting(this)) { - return event; - } else { - return null; - } - }); - }); this.initMode = true; BackgroundUpdateChecker.onMainActivityCreate(this); super.onCreate(savedInstanceState); diff --git a/app/src/main/java/com/fox2code/mmm/MainApplication.java b/app/src/main/java/com/fox2code/mmm/MainApplication.java index 16cf224..9f4b278 100644 --- a/app/src/main/java/com/fox2code/mmm/MainApplication.java +++ b/app/src/main/java/com/fox2code/mmm/MainApplication.java @@ -27,6 +27,8 @@ import com.fox2code.mmm.utils.Http; import com.fox2code.rosettax.LanguageSwitcher; import com.topjohnwu.superuser.Shell; +import java.io.IOException; +import java.io.Writer; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -42,6 +44,9 @@ import io.noties.markwon.syntax.Prism4jThemeDefault; import io.noties.markwon.syntax.SyntaxHighlightPlugin; import io.noties.prism4j.Prism4j; import io.noties.prism4j.annotations.PrismBundle; +import io.sentry.JsonObjectWriter; +import io.sentry.NoOpLogger; +import io.sentry.android.core.SentryAndroid; @PrismBundle( includeAll = true, @@ -49,6 +54,7 @@ import io.noties.prism4j.annotations.PrismBundle; ) 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 Locale timeFormatLocale = Resources.getSystem().getConfiguration().locale; @@ -168,6 +174,11 @@ public class MainApplication extends FoxApplication getSharedPreferences().edit().putBoolean("has_root_access", bool).apply(); } + public static boolean isCrashReportingEnabled() { + return getSharedPreferences().getBoolean( + "crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING); + } + public static SharedPreferences getBootSharedPreferences() { return bootSharedPreferences; } @@ -341,6 +352,57 @@ public class MainApplication extends FoxApplication Log.d("MainApplication", "Emoji compat loaded!"); }, "Emoji compat init.").start(); } + SentryAndroid.init(this, options -> { + // Note: Sentry library only take a screenshot of Fox Magisk Module Manager. + // The screen shot doesn't and cannot contain other applications (if in multi windows) + // status bar and notifications (even if notification shade is pulled down) + + // In the possibility you find this library sending anything listed above, + // it's a serious bug and a security issue you should report to Google + // Google bug bounties on Android are huge, so you can also get rich by doing that. + options.setAttachScreenshot(true); + // Add a callback that will be used before the event is sent to Sentry. + // With this callback, you can modify the event or, when returning null, also discard the event. + options.setBeforeSend((event, hint) -> { + if (BuildConfig.DEBUG) { // Debug sentry events for debug. + StringBuilder stringBuilder = new StringBuilder("Sentry report debug: "); + try { + event.serialize(new JsonObjectWriter(new Writer() { + @Override + public void write(char[] cbuf) { + stringBuilder.append(cbuf); + } + + @Override + public void write(char[] chars, int i, int i1) { + stringBuilder.append(chars, i, i1); + } + + @Override + public void write(String str, int off, int len) { + stringBuilder.append(str, off, len); + } + + @Override + public void flush() {} + + @Override + public void close() {} + }, 4), NoOpLogger.getInstance()); + } catch (IOException ignored) {} + Log.i(TAG, stringBuilder.toString()); + } + // Check saved preferences to see if the user has opted out of crash reporting. + // If the user has opted out, return null. + if (isCrashReportingEnabled()) { + Log.i(TAG, "Relayed sentry report according to user preference"); + return event; + } else { + Log.i(TAG, "Blocked sentry report according to user preference"); + return null; + } + }); + }); } @Override 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 304ed05..d92c519 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -62,11 +62,6 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { private static final String TAG = "SettingsActivity"; private static int devModeStep = 0; - public static boolean getCrashReporting(MainActivity mainActivity) { - return mainActivity.getPreferences(Context.MODE_PRIVATE) - .getBoolean("crash_reporting", true); - } - @Override protected void onCreate(Bundle savedInstanceState) { devModeStep = 0; @@ -132,8 +127,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { }); // Crash reporting TwoStatePreference crashReportingPreference = findPreference("pref_crash_reporting"); - crashReportingPreference.setChecked(getCrashReporting( - (MainActivity) requireActivity())); + crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled()); crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> { devModeStep = 0; getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", diff --git a/build.gradle b/build.gradle index bd74ad2..c4ee15e 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { project.ext.latestAboutLibsRelease = "10.4.1-a01" dependencies { classpath 'com.android.tools.build:gradle:7.2.2' - classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:10.4.1-a01" + classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${latestAboutLibsRelease}" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files From cf9fe3d51f5b581e823499df3f99d3a2e50ac094 Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Wed, 24 Aug 2022 21:21:06 -0400 Subject: [PATCH 03/10] Add custom API key support Signed-off-by: androidacy-user --- .../fox2code/mmm/androidacy/AndroidacyRepoData.java | 12 ++++++++---- .../main/java/com/fox2code/mmm/repo/RepoManager.java | 2 +- .../com/fox2code/mmm/settings/SettingsActivity.java | 6 ++++++ app/src/main/res/values-cs/strings.xml | 1 + app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values-el/strings.xml | 1 + app/src/main/res/values-es-rMX/strings.xml | 1 + app/src/main/res/values-et/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-id/strings.xml | 1 + app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-nb-rNO/strings.xml | 1 + app/src/main/res/values-night-v31/strings.xml | 1 + app/src/main/res/values-night/strings.xml | 1 + app/src/main/res/values-pl/strings.xml | 1 + app/src/main/res/values-pt-rBR/strings.xml | 1 + app/src/main/res/values-ro/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-sk/strings.xml | 1 + app/src/main/res/values-tr/strings.xml | 1 + app/src/main/res/values-v23/strings.xml | 1 + app/src/main/res/values-v31/strings.xml | 1 + app/src/main/res/values-vi/strings.xml | 1 + app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/repo_preferences.xml | 7 +++++++ 28 files changed, 47 insertions(+), 5 deletions(-) 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 0a77530..8d205a7 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java @@ -74,8 +74,8 @@ public final class AndroidacyRepoData extends RepoData { long time = System.currentTimeMillis(); if (this.androidacyBlockade > time) return false; this.androidacyBlockade = time + 30_000L; - // Get token from androidacy_token shared preference - String token = this.cachedPreferences.getString("androidacy_token", null); + // Get token from androidacy_api_token shared preference + String token = this.cachedPreferences.getString("androidacy_api_token", null); if (token != null) { try { Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, true); @@ -89,7 +89,7 @@ public final class AndroidacyRepoData extends RepoData { Log.w(TAG, "Invalid token, resetting..."); // Remove saved preference SharedPreferences.Editor editor = this.cachedPreferences.edit(); - editor.remove("androidacy_token"); + editor.remove("androidacy_api_token"); editor.apply(); this.token = token = null; } @@ -97,12 +97,16 @@ public final class AndroidacyRepoData extends RepoData { if (token == null) { try { Log.i(TAG, "Refreshing token..."); + // POST request to https://production-api.androidacy.com/auth/register token = new String(Http.doHttpPost( "https://" + this.host + "/auth/register", "foxmmm=true", true), StandardCharsets.UTF_8); + // Parse token + JSONObject jsonObject = new JSONObject(token); + token = jsonObject.getString("token"); // Save token to shared preference SharedPreferences.Editor editor = this.cachedPreferences.edit(); - editor.putString("androidacy_token", token); + editor.putString("androidacy_api_token", token); editor.apply(); } catch (Exception e) { if ("Received error code: 419".equals(e.getMessage()) || 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 3fc42a6..26b85bd 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -36,7 +36,7 @@ public final class RepoManager { "https://cdn.jsdelivr.net/gh/Magisk-Modules-Alt-Repo/json@main/modules.json"; public static final String ANDROIDACY_MAGISK_REPO_ENDPOINT = - "https://api.androidacy.com/magisk/repo"; + "https://production-api.androidacy.com/magisk/repo"; public static final String ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT = "https://staging-api.androidacy.com/magisk/repo"; public static final String ANDROIDACY_MAGISK_REPO_HOMEPAGE = 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 d92c519..f2e0400 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -270,6 +270,12 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { "https://github.com/Fox2Code/FoxMagiskModuleManager"); return true; }); + // Add a listener to pref_androidacy_repo_api_key to update the api key in shared preferences + findPreference("pref_androidacy_repo_api_key").setOnPreferenceChangeListener((preference, newValue) -> { + MainApplication.getSharedPreferences().edit() + .putString("androidacy_api_token", String.valueOf(newValue)).apply(); + return true; + }); findPreference("pref_support").setOnPreferenceClickListener(p -> { devModeStep = 0; IntentHelper.openUrl(p.getContext(), "https://t.me/Fox2Code_Chat"); diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 4f11bdc..741e0e2 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -93,4 +93,5 @@ Repozitář povolen Repozitář zakázán If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cdb56aa..c0e3ed8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -103,4 +103,5 @@ Deinstallieren Konfig If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 520c77d..5c26ca9 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -144,4 +144,5 @@ Μεταφράστηκε απο Tha_14 If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 43ef05e..e8ef531 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -128,4 +128,5 @@ Restaurar módulos Esta operación requiere una conexión a Internet. If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index ca51e6b..33720c9 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -88,4 +88,5 @@ Hoidla lubatud Hoidla keelatud If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 87eab18..205d017 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -128,4 +128,5 @@ Restaurer les modules Cette opération requière une connexion internet If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 83931fb..dbef5f2 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -94,4 +94,5 @@ Repo diaktifkan Repo dinonaktifkan If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 32c54cd..1725d8c 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -149,4 +149,5 @@ Traduzione di tugaia56 If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 923042a..78cb62a 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -41,4 +41,5 @@ 開発者モードが有効です Force English language If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 521a3f9..048de70 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -95,4 +95,5 @@ Pakkebrønn på Pakkebrønn av If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-night-v31/strings.xml b/app/src/main/res/values-night-v31/strings.xml index 56b553c..1258a33 100644 --- a/app/src/main/res/values-night-v31/strings.xml +++ b/app/src/main/res/values-night-v31/strings.xml @@ -1,4 +1,5 @@ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key \ No newline at end of file diff --git a/app/src/main/res/values-night/strings.xml b/app/src/main/res/values-night/strings.xml index 56b553c..1258a33 100644 --- a/app/src/main/res/values-night/strings.xml +++ b/app/src/main/res/values-night/strings.xml @@ -1,4 +1,5 @@ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 73f8383..7e9b6fd 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -147,4 +147,5 @@ Tłumaczenie: Daviteusz If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 1977166..594810b 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -149,4 +149,5 @@ Traduzido por mi007d e DanGLES3 If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 9ee1fc3..33d5330 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -138,4 +138,5 @@ Tradus de Fox2Code If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5ab9ad7..560cd61 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -124,4 +124,5 @@ Восстановить модули Для этого действия потребуется подключение к Интернету If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 1ffe0c4..41c29ec 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -93,4 +93,5 @@ Repozitár povolený Repozitár zakázaný If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index c8790fd..547460b 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -147,4 +147,5 @@ Alprnn357 tarafından çevrildi If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-v23/strings.xml b/app/src/main/res/values-v23/strings.xml index 56b553c..1258a33 100644 --- a/app/src/main/res/values-v23/strings.xml +++ b/app/src/main/res/values-v23/strings.xml @@ -1,4 +1,5 @@ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key \ No newline at end of file diff --git a/app/src/main/res/values-v31/strings.xml b/app/src/main/res/values-v31/strings.xml index 56b553c..1258a33 100644 --- a/app/src/main/res/values-v31/strings.xml +++ b/app/src/main/res/values-v31/strings.xml @@ -1,4 +1,5 @@ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 997aaee..dd9348f 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -123,4 +123,5 @@ Khôi phục mô-đun Quá trình này yêu cầu kết nối internet If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0fa7ca6..2f66551 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -150,4 +150,5 @@ 由ender-zhao翻译 If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 21979bb..5021afb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -140,4 +140,5 @@ 由 OrStudio.tw(@crcky5322) 提供美妙的翻譯 If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7074e48..677f632 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -154,4 +154,6 @@ Translated by Fox2Code Automatically report bugs and performance to the developers If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder + Androidacy API Key + Use a custom API key for Androidacy diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index a0b7c46..0ddc6f7 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -59,6 +59,13 @@ app:icon="@drawable/ic_baseline_upload_file_24" app:title="@string/submit_modules" app:singleLineTitle="false" /> + + Date: Thu, 25 Aug 2022 11:38:03 -0400 Subject: [PATCH 04/10] Add custom API key support Signed-off-by: androidacy-user --- .../mmm/androidacy/AndroidacyRepoData.java | 40 +++++++----- .../mmm/settings/SettingsActivity.java | 63 +++++++++++++++++-- app/src/main/res/values/strings.xml | 5 ++ 3 files changed, 88 insertions(+), 20 deletions(-) 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 8d205a7..0806db7 100644 --- a/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java +++ b/app/src/main/java/com/fox2code/mmm/androidacy/AndroidacyRepoData.java @@ -67,6 +67,28 @@ public final class AndroidacyRepoData extends RepoData { return RepoManager.getINSTANCE().getAndroidacyRepoData(); } + public boolean isValidToken(string token) { + try { + Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, false); + } catch (Exception e) { + if ("Received error code: 419".equals(e.getMessage()) || + "Received error code: 429".equals(e.getMessage())) { + Log.e(TAG, "We are being rate limited!", e); + long time = System.currentTimeMillis(); + this.androidacyBlockade = time + 3_600_000L; + return false; + } + Log.w(TAG, "Invalid token, resetting..."); + // Remove saved preference + SharedPreferences.Editor editor = this.cachedPreferences.edit(); + editor.remove("androidacy_api_token"); + editor.apply(); + return false; + } + // If status code is 200, we are good + return true; + } + @Override protected boolean prepare() { // Implementation details discussed on telegram @@ -77,21 +99,9 @@ public final class AndroidacyRepoData extends RepoData { // Get token from androidacy_api_token shared preference String token = this.cachedPreferences.getString("androidacy_api_token", null); if (token != null) { - try { - Http.doHttpGet("https://" + this.host + "/auth/me?token=" + token, true); - } catch (Exception e) { - if ("Received error code: 419".equals(e.getMessage()) || - "Received error code: 429".equals(e.getMessage())) { - Log.e(TAG, "We are being rate limited!", e); - this.androidacyBlockade = time + 3_600_000L; - return false; - } - Log.w(TAG, "Invalid token, resetting..."); - // Remove saved preference - SharedPreferences.Editor editor = this.cachedPreferences.edit(); - editor.remove("androidacy_api_token"); - editor.apply(); - this.token = token = null; + this.token = token; + if (!isValidToken(token)) { + token = null; } } if (token == null) { 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 f2e0400..8fbf188 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -3,11 +3,14 @@ package com.fox2code.mmm.settings; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; +import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; +import android.text.InputType; +import android.text.method.PasswordTransformationMethod; import android.util.Log; import android.widget.AutoCompleteTextView; import android.widget.Button; @@ -19,6 +22,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentTransaction; +import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -51,12 +55,16 @@ import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; import org.json.JSONException; +import org.json.JSONObject; import java.io.IOException; import java.util.HashSet; import java.util.Objects; import java.util.Random; +import okhttp3.OkHttpClient; +import okhttp3.Request; + public class SettingsActivity extends FoxActivity implements LanguageActivity { private static final int LANGUAGE_SUPPORT_LEVEL = 1; private static final String TAG = "SettingsActivity"; @@ -270,11 +278,56 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { "https://github.com/Fox2Code/FoxMagiskModuleManager"); return true; }); - // Add a listener to pref_androidacy_repo_api_key to update the api key in shared preferences - findPreference("pref_androidacy_repo_api_key").setOnPreferenceChangeListener((preference, newValue) -> { - MainApplication.getSharedPreferences().edit() - .putString("androidacy_api_token", String.valueOf(newValue)).apply(); - return true; + // Create the pref_androidacy_repo_api_key text input + EditTextPreference prefAndroidacyRepoApiKey = new EditTextPreference(this.requireContext()); + prefAndroidacyRepoApiKey.setKey("pref_androidacy_repo_api_key"); + prefAndroidacyRepoApiKey.setTitle(R.string.api_key); + prefAndroidacyRepoApiKey.setDialogTitle(R.string.api_key); + // Set the summary to the current androidacy_api_token + prefAndroidacyRepoApiKey.setSummary(MainApplication.getSharedPreferences() + .getString("androidacy_api_token", "")); + prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { + editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + editText.setTransformationMethod(PasswordTransformationMethod.getInstance()); + }); + // Bind ok button to save the new androidacy_api_token + // On hitting OK, save the new androidacy_api_token after checking it. While checking, show a progress dialog + prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { + String newToken = String.valueOf(newValue); + if (newToken.isEmpty()) { + MainApplication.getSharedPreferences().edit() + .remove("androidacy_api_token").apply(); + return true; + } + ProgressDialog progressDialog = new ProgressDialog(this.requireContext()); + progressDialog.setMessage(getString(R.string.checking_api_key)); + progressDialog.setCancelable(false); + progressDialog.show(); + new Thread(() -> { + try { + String response = new OkHttpClient().newCall(new Request.Builder() + .url("https://production-api.androidacy.com/auth/me") + .header("Authorization", "Bearer " + newToken) + .build()).execute().body().string(); + JSONObject jsonObject = new JSONObject(response); + if (!jsonObject.has("role")) { + throw new IOException("Invalid response"); + } + MainApplication.getSharedPreferences().edit() + .putString("androidacy_api_token", newToken).apply(); + progressDialog.dismiss(); + this.requireActivity().runOnUiThread(() -> { + prefAndroidacyRepoApiKey.setSummary(newToken); + Toast.makeText(this.requireContext(), + R.string.api_key_valid, Toast.LENGTH_SHORT).show(); + }); + } catch (IOException | JSONException e) { + progressDialog.dismiss(); + this.requireActivity().runOnUiThread(() -> Toast.makeText(this.requireContext(), + R.string.api_key_invalid, Toast.LENGTH_SHORT).show()); + } + }).start(); + return false; }); findPreference("pref_support").setOnPreferenceClickListener(p -> { devModeStep = 0; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 677f632..d5a2335 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -156,4 +156,9 @@ If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder Androidacy API Key Use a custom API key for Androidacy + Androidacy API key is empty + Current Androidacy API key + Could not validate API key. Please try again. + API key is valid. + Validating API key... From 9052703c81fbddc5cf5381d4d8bd70ed69b64d41 Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Thu, 25 Aug 2022 21:23:39 -0400 Subject: [PATCH 05/10] tweak custom API key support Signed-off-by: androidacy-user --- .../mmm/settings/SettingsActivity.java | 72 +++++++++---------- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/repo_preferences.xml | 8 ++- 3 files changed, 42 insertions(+), 40 deletions(-) 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 8fbf188..7b47dfe 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -3,14 +3,13 @@ package com.fox2code.mmm.settings; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; -import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; -import android.text.InputType; -import android.text.method.PasswordTransformationMethod; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.widget.AutoCompleteTextView; import android.widget.Button; @@ -54,16 +53,19 @@ import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; +import org.jetbrains.annotations.NotNull; import org.json.JSONException; -import org.json.JSONObject; import java.io.IOException; import java.util.HashSet; import java.util.Objects; import java.util.Random; +import okhttp3.Call; +import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.Response; public class SettingsActivity extends FoxActivity implements LanguageActivity { private static final int LANGUAGE_SUPPORT_LEVEL = 1; @@ -286,48 +288,42 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { // Set the summary to the current androidacy_api_token prefAndroidacyRepoApiKey.setSummary(MainApplication.getSharedPreferences() .getString("androidacy_api_token", "")); - prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { - editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - editText.setTransformationMethod(PasswordTransformationMethod.getInstance()); - }); - // Bind ok button to save the new androidacy_api_token - // On hitting OK, save the new androidacy_api_token after checking it. While checking, show a progress dialog + // On user input, save the new androidacy_api_token after validating it prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { String newToken = String.valueOf(newValue); - if (newToken.isEmpty()) { + if (newToken.length() == 0) { MainApplication.getSharedPreferences().edit() .remove("androidacy_api_token").apply(); return true; } - ProgressDialog progressDialog = new ProgressDialog(this.requireContext()); - progressDialog.setMessage(getString(R.string.checking_api_key)); - progressDialog.setCancelable(false); - progressDialog.show(); - new Thread(() -> { - try { - String response = new OkHttpClient().newCall(new Request.Builder() - .url("https://production-api.androidacy.com/auth/me") - .header("Authorization", "Bearer " + newToken) - .build()).execute().body().string(); - JSONObject jsonObject = new JSONObject(response); - if (!jsonObject.has("role")) { - throw new IOException("Invalid response"); - } - MainApplication.getSharedPreferences().edit() - .putString("androidacy_api_token", newToken).apply(); - progressDialog.dismiss(); - this.requireActivity().runOnUiThread(() -> { - prefAndroidacyRepoApiKey.setSummary(newToken); - Toast.makeText(this.requireContext(), - R.string.api_key_valid, Toast.LENGTH_SHORT).show(); + // Call the androidacy api to validate the token + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url("https://production-api.androidacy.com/auth/me") + .header("Authorization", "Bearer " + newToken) + .build(); + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + // If the request failed, show an error message + new Handler(Looper.getMainLooper()).post(() -> { + Toast.makeText(getContext(), R.string.api_key_invalid, + Toast.LENGTH_SHORT).show(); }); - } catch (IOException | JSONException e) { - progressDialog.dismiss(); - this.requireActivity().runOnUiThread(() -> Toast.makeText(this.requireContext(), - R.string.api_key_invalid, Toast.LENGTH_SHORT).show()); } - }).start(); - return false; + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) { + // If the request succeeded, save the token + new Handler(Looper.getMainLooper()).post(() -> { + MainApplication.getSharedPreferences().edit() + .putString("androidacy_api_token", newToken).apply(); + Toast.makeText(getContext(), R.string.api_key_valid, + Toast.LENGTH_SHORT).show(); + }); + } + }); + return true; }); findPreference("pref_support").setOnPreferenceClickListener(p -> { devModeStep = 0; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d5a2335..6a87d72 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -161,4 +161,6 @@ Could not validate API key. Please try again. API key is valid. Validating API key... + Validating API key... + Please wait diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index 0ddc6f7..c23cbc4 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -1,5 +1,6 @@ - + @@ -65,7 +66,10 @@ app:icon="@drawable/ic_baseline_security_24" app:title="@string/api_key" app:summary="@string/api_key_summary" - app:singleLineTitle="false" /> + app:singleLineTitle="false" + app:dialogTitle="@string/api_key" + app:dialogMessage="@string/api_key_summary" + android:imeOptions="actionDone" /> Date: Fri, 26 Aug 2022 11:45:50 -0400 Subject: [PATCH 06/10] Fix validation of api key Still saves the invalid key though Signed-off-by: androidacy-user --- .../mmm/settings/SettingsActivity.java | 130 ++++++++++-------- .../res/drawable/ic_baseline_vpn_key_24.xml | 10 ++ app/src/main/res/values/strings.xml | 3 +- app/src/main/res/xml/repo_preferences.xml | 37 ++--- 4 files changed, 106 insertions(+), 74 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_vpn_key_24.xml 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 7b47dfe..8b1273b 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -3,6 +3,7 @@ package com.fox2code.mmm.settings; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; +import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -36,6 +37,7 @@ import com.fox2code.mmm.Constants; import com.fox2code.mmm.MainActivity; import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.R; +import com.fox2code.mmm.androidacy.AndroidacyRepoData; import com.fox2code.mmm.background.BackgroundUpdateChecker; import com.fox2code.mmm.installer.InstallerInitializer; import com.fox2code.mmm.module.ActionButtonType; @@ -53,7 +55,6 @@ import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; -import org.jetbrains.annotations.NotNull; import org.json.JSONException; import java.io.IOException; @@ -61,12 +62,6 @@ import java.util.HashSet; import java.util.Objects; import java.util.Random; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - public class SettingsActivity extends FoxActivity implements LanguageActivity { private static final int LANGUAGE_SUPPORT_LEVEL = 1; private static final String TAG = "SettingsActivity"; @@ -96,7 +91,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { int mPendingIntentId = 123456; PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); - AlarmManager mgr = (AlarmManager)this.getSystemService(Context.ALARM_SERVICE); + AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); System.exit(0); // Exit app process } @@ -280,51 +275,6 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { "https://github.com/Fox2Code/FoxMagiskModuleManager"); return true; }); - // Create the pref_androidacy_repo_api_key text input - EditTextPreference prefAndroidacyRepoApiKey = new EditTextPreference(this.requireContext()); - prefAndroidacyRepoApiKey.setKey("pref_androidacy_repo_api_key"); - prefAndroidacyRepoApiKey.setTitle(R.string.api_key); - prefAndroidacyRepoApiKey.setDialogTitle(R.string.api_key); - // Set the summary to the current androidacy_api_token - prefAndroidacyRepoApiKey.setSummary(MainApplication.getSharedPreferences() - .getString("androidacy_api_token", "")); - // On user input, save the new androidacy_api_token after validating it - prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { - String newToken = String.valueOf(newValue); - if (newToken.length() == 0) { - MainApplication.getSharedPreferences().edit() - .remove("androidacy_api_token").apply(); - return true; - } - // Call the androidacy api to validate the token - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder() - .url("https://production-api.androidacy.com/auth/me") - .header("Authorization", "Bearer " + newToken) - .build(); - client.newCall(request).enqueue(new Callback() { - @Override - public void onFailure(@NotNull Call call, @NotNull IOException e) { - // If the request failed, show an error message - new Handler(Looper.getMainLooper()).post(() -> { - Toast.makeText(getContext(), R.string.api_key_invalid, - Toast.LENGTH_SHORT).show(); - }); - } - - @Override - public void onResponse(@NotNull Call call, @NotNull Response response) { - // If the request succeeded, save the token - new Handler(Looper.getMainLooper()).post(() -> { - MainApplication.getSharedPreferences().edit() - .putString("androidacy_api_token", newToken).apply(); - Toast.makeText(getContext(), R.string.api_key_valid, - Toast.LENGTH_SHORT).show(); - }); - } - }); - return true; - }); findPreference("pref_support").setOnPreferenceClickListener(p -> { devModeStep = 0; IntentHelper.openUrl(p.getContext(), "https://t.me/Fox2Code_Chat"); @@ -342,7 +292,8 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { BuildConfig.VERSION_CODE + ")"); } - private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) { + private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity + requireActivity) { return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit(); } @@ -398,6 +349,73 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { Objects.requireNonNull((Preference) findPreference( "pref_androidacy_test_mode")).setVisible(false); } + String originalApiKey = MainApplication.getSharedPreferences() + .getString("pref_androidacy_api_token", ""); + // Create the pref_androidacy_repo_api_key text input with validation + EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key"); + prefAndroidacyRepoApiKey.setKey("pref_androidacy_repo_api_key"); + prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { + editText.setSingleLine(); + // Make the single line wrap + editText.setHorizontallyScrolling(false); + // Set the height to the height of 2 lines + editText.setHeight(editText.getLineHeight() * 2); + }); + prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { + // Curious if this actually works - so crash the app on purpose + // throw new RuntimeException("This is a test crash"); + // get original api key + String apiKey = String.valueOf(newValue); + // Show progress dialog + ProgressDialog progressDialog = new ProgressDialog(getContext()); + progressDialog.setMessage(getString(R.string.checking_api_key)); + progressDialog.setCancelable(false); + progressDialog.show(); + // Check the API key on a background thread + new Thread(() -> { + // If key is empty, just remove it and show a toast + if (apiKey.isEmpty()) { + MainApplication.getSharedPreferences().edit() + .remove("pref_androidacy_repo_api_key").apply(); + new Handler(Looper.getMainLooper()).post(() -> { + progressDialog.dismiss(); + Toast.makeText(getContext(), R.string.api_key_removed, Toast.LENGTH_SHORT).show(); + }); + return; + } else { + // If key < 64 chars, it's not valid + if (apiKey.length() < 64) { + new Handler(Looper.getMainLooper()).post(() -> { + progressDialog.dismiss(); + Toast.makeText(getContext(), R.string.api_key_invalid, Toast.LENGTH_SHORT).show(); + }); + return; + } + } + // Check the API key + boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey); + // Update the UI on the main thread + new Handler(Looper.getMainLooper()).post(() -> { + progressDialog.dismiss(); + if (valid) { + // Show a success message + Toast.makeText(getContext(), R.string.api_key_valid, + Toast.LENGTH_SHORT).show(); + // Save the API key + MainApplication.getSharedPreferences().edit() + .putString("pref_androidacy_api_token", apiKey).apply(); + } else { + // Show an error message + Toast.makeText(getContext(), R.string.api_key_invalid, + Toast.LENGTH_SHORT).show(); + // Restore the original API key + MainApplication.getSharedPreferences().edit() + .putString("pref_androidacy_api_token", originalApiKey).apply(); + } + }); + }).start(); + return true; + }); } @SuppressLint("RestrictedApi") @@ -411,7 +429,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { setRepoData(repoData, "pref_custom_repo_" + i); if (initial) { Preference preference = - findPreference("pref_custom_repo_" + i + "_delete"); + findPreference("pref_custom_repo_" + i + "_delete"); if (preference == null) continue; final int index = i; preference.setOnPreferenceClickListener(preference1 -> { @@ -450,7 +468,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { public void run() { try { customRepoData.quickPrePopulate(); - } catch (IOException|JSONException e) { + } catch (IOException | JSONException e) { Log.e(TAG, "Failed to preload repo values", e); } UiThreadHandler.handler.post(() -> updateCustomRepoList(false)); diff --git a/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml b/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml new file mode 100644 index 0000000..9cdda53 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_vpn_key_24.xml @@ -0,0 +1,10 @@ + + + \ 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 6a87d72..67da3e4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -155,7 +155,7 @@ Automatically report bugs and performance to the developers If you disable this, the developer will not get automatic bug reports, and this may make troubleshooting harder Androidacy API Key - Use a custom API key for Androidacy + Use a custom API key for Androidacy. Useful for premium subscribers, to remove ads and more. Androidacy API key is empty Current Androidacy API key Could not validate API key. Please try again. @@ -163,4 +163,5 @@ Validating API key... Validating API key... Please wait + Successfully reset API key diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index c23cbc4..444b40b 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -40,6 +40,26 @@ app:switchTextOn="@string/repo_enabled" app:switchTextOff="@string/repo_disabled" app:singleLineTitle="false" /> + + + - - - Date: Fri, 26 Aug 2022 21:22:09 -0400 Subject: [PATCH 07/10] Add custom API key support Signed-off-by: androidacy-user --- .../fox2code/mmm/settings/SettingsActivity.java | 16 ++++++++++++++-- app/src/main/res/values/strings.xml | 3 ++- app/src/main/res/xml/repo_preferences.xml | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) 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 8b1273b..1854ee5 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -12,6 +12,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; +import android.view.inputmethod.EditorInfo; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.Toast; @@ -337,6 +338,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { public static class RepoFragment extends PreferenceFragmentCompat { private static final int CUSTOM_REPO_ENTRIES = 5; + @SuppressLint("RestrictedApi") @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { getPreferenceManager().setSharedPreferencesName("mmm"); @@ -353,14 +355,16 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { .getString("pref_androidacy_api_token", ""); // Create the pref_androidacy_repo_api_key text input with validation EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key"); - prefAndroidacyRepoApiKey.setKey("pref_androidacy_repo_api_key"); prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { editText.setSingleLine(); // Make the single line wrap editText.setHorizontallyScrolling(false); // Set the height to the height of 2 lines - editText.setHeight(editText.getLineHeight() * 2); + editText.setHeight(editText.getLineHeight() * 3); + // Make ok button say "Save" + editText.setImeOptions(EditorInfo.IME_ACTION_DONE); }); + prefAndroidacyRepoApiKey.setPositiveButtonText(R.string.save_api_key); prefAndroidacyRepoApiKey.setOnPreferenceChangeListener((preference, newValue) -> { // Curious if this actually works - so crash the app on purpose // throw new RuntimeException("This is a test crash"); @@ -387,6 +391,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { if (apiKey.length() < 64) { new Handler(Looper.getMainLooper()).post(() -> { progressDialog.dismiss(); + // Save the original key + MainApplication.getSharedPreferences().edit() + .putString("pref_androidacy_api_token", originalApiKey).apply(); + // Re-show the dialog with an error + prefAndroidacyRepoApiKey.performClick(); + // Show error + prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid)); + // Set the error color Toast.makeText(getContext(), R.string.api_key_invalid, Toast.LENGTH_SHORT).show(); }); return; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 67da3e4..fbbbc13 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -158,10 +158,11 @@ Use a custom API key for Androidacy. Useful for premium subscribers, to remove ads and more. Androidacy API key is empty Current Androidacy API key - Could not validate API key. Please try again. + Could not validate API key. Please check it and try again. API key is valid. Validating API key... Validating API key... Please wait Successfully reset API key + Validate diff --git a/app/src/main/res/xml/repo_preferences.xml b/app/src/main/res/xml/repo_preferences.xml index 444b40b..8cbb1a8 100644 --- a/app/src/main/res/xml/repo_preferences.xml +++ b/app/src/main/res/xml/repo_preferences.xml @@ -51,6 +51,7 @@ app:dialogIcon="@drawable/ic_baseline_vpn_key_24" app:dependency="pref_androidacy_repo_enabled" android:inputType="text" + android:selectAllOnFocus="true" android:imeOptions="actionDone" /> Date: Sat, 27 Aug 2022 11:59:33 -0400 Subject: [PATCH 08/10] Cleanup custom API key support Also allow devs to purposely crash the app, because it's fun Signed-off-by: androidacy-user --- .../mmm/settings/SettingsActivity.java | 231 +++++++----------- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/root_preferences.xml | 140 +++++------ 4 files changed, 169 insertions(+), 206 deletions(-) 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 1854ee5..4761366 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -3,7 +3,6 @@ package com.fox2code.mmm.settings; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.PendingIntent; -import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -27,6 +26,7 @@ import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreferenceCompat; import androidx.preference.TwoStatePreference; import com.fox2code.foxcompat.FoxActivity; @@ -52,6 +52,7 @@ import com.fox2code.rosettax.LanguageActivity; import com.fox2code.rosettax.LanguageSwitcher; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.internal.TextWatcherAdapter; +import com.google.android.material.snackbar.Snackbar; import com.google.android.material.textfield.MaterialAutoCompleteTextView; import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; @@ -77,10 +78,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { setTitle(R.string.app_name); setActionBarBackground(null); if (savedInstanceState == null) { - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.settings, new SettingsFragment()) - .commit(); + getSupportFragmentManager().beginTransaction().replace(R.id.settings, new SettingsFragment()).commit(); } } @@ -90,8 +88,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { Intent mStartActivity = new Intent(this, MainActivity.class); mStartActivity.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); int mPendingIntentId = 123456; - PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, - mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); + PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE); AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent); System.exit(0); // Exit app process @@ -103,8 +100,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { super.onPause(); } - public static class SettingsFragment extends PreferenceFragmentCompat - implements FoxActivity.OnBackPressedCallback { + public static class SettingsFragment extends PreferenceFragmentCompat implements FoxActivity.OnBackPressedCallback { @Override @SuppressWarnings("ConstantConditions") public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -126,8 +122,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { devModeStep = 0; UiThreadHandler.handler.postDelayed(() -> { MainApplication.getINSTANCE().updateTheme(); - FoxActivity.getFoxActivity(this).setThemeRecreate( - MainApplication.getINSTANCE().getManagerThemeResId()); + FoxActivity.getFoxActivity(this).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId()); }, 1); return true; }); @@ -136,8 +131,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { crashReportingPreference.setChecked(MainApplication.isCrashReportingEnabled()); crashReportingPreference.setOnPreferenceChangeListener((preference, newValue) -> { devModeStep = 0; - getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", - (boolean) newValue).apply(); + getCrashReportingEditor(requireActivity()).putBoolean("crash_reporting", (boolean) newValue).apply(); return true; }); Preference enableBlur = findPreference("pref_enable_blur"); @@ -154,8 +148,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { disableMonet.setOnPreferenceClickListener(preference -> { UiThreadHandler.handler.postDelayed(() -> { MainApplication.getINSTANCE().updateTheme(); - ((FoxActivity) this.requireActivity()).setThemeRecreate( - MainApplication.getINSTANCE().getManagerThemeResId()); + ((FoxActivity) this.requireActivity()).setThemeRecreate(MainApplication.getINSTANCE().getManagerThemeResId()); }, 1); return true; }); @@ -198,8 +191,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { int level = this.currentLanguageLevel(); if (level != LANGUAGE_SUPPORT_LEVEL) { - Log.e(TAG, "Detected language level " + level + - ", latest is " + LANGUAGE_SUPPORT_LEVEL); + Log.e(TAG, "Detected language level " + level + ", latest is " + LANGUAGE_SUPPORT_LEVEL); languageSelector.setSummary(R.string.language_support_outdated); } else { if (!"Translated by Fox2Code".equals( // I don't "translate" english @@ -212,45 +204,45 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { if (!MainApplication.isDeveloper()) { findPreference("pref_disable_low_quality_module_filter").setVisible(false); + // Hide the pref_crash option if not in debug mode - stop users from purposely crashing the app + Objects.requireNonNull((Preference) findPreference("pref_crash")).setVisible(false); + } else { + findPreference("pref_crash").setOnPreferenceClickListener(preference -> { + // Hard crash the app + throw new RuntimeException("This is a test crash"); + }); } - if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND - || !MainApplication.isDeveloper()) { + if (InstallerInitializer.peekMagiskVersion() < Constants.MAGISK_VER_CODE_INSTALL_COMMAND || !MainApplication.isDeveloper()) { findPreference("pref_use_magisk_install_command").setVisible(false); } Preference debugNotification = findPreference("pref_background_update_check_debug"); debugNotification.setEnabled(MainApplication.isBackgroundUpdateCheckEnabled()); debugNotification.setVisible(MainApplication.isDeveloper()); debugNotification.setOnPreferenceClickListener(preference -> { - BackgroundUpdateChecker.postNotification( - this.requireContext(), new Random().nextInt(4) + 2); + BackgroundUpdateChecker.postNotification(this.requireContext(), new Random().nextInt(4) + 2); return true; }); findPreference("pref_background_update_check").setOnPreferenceChangeListener((preference, newValue) -> { boolean enabled = Boolean.parseBoolean(String.valueOf(newValue)); debugNotification.setEnabled(enabled); if (!enabled) { - BackgroundUpdateChecker.onMainActivityResume( - this.requireContext()); + BackgroundUpdateChecker.onMainActivityResume(this.requireContext()); } return true; }); - final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false) - .withLicenseShown(true).withAboutMinimalDesign(false); + final LibsBuilder libsBuilder = new LibsBuilder().withShowLoadingProgress(false).withLicenseShown(true).withAboutMinimalDesign(false); Preference update = findPreference("pref_update"); - update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG || - AppUpdateManager.getAppUpdateManager().peekHasUpdate())); + update.setVisible(BuildConfig.ENABLE_AUTO_UPDATER && (BuildConfig.DEBUG || AppUpdateManager.getAppUpdateManager().peekHasUpdate())); update.setOnPreferenceClickListener(p -> { devModeStep = 0; - IntentHelper.openUrl(p.getContext(), - "https://github.com/Fox2Code/FoxMagiskModuleManager/releases"); + IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/releases"); return true; }); if (BuildConfig.DEBUG || BuildConfig.ENABLE_AUTO_UPDATER) { findPreference("pref_report_bug").setOnPreferenceClickListener(p -> { devModeStep = 0; - IntentHelper.openUrl(p.getContext(), - "https://github.com/Fox2Code/FoxMagiskModuleManager/issues"); + IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager/issues"); return true; }); } else { @@ -260,20 +252,17 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { if (devModeStep == 2) { devModeStep = 0; if (MainApplication.isDeveloper() && !BuildConfig.DEBUG) { - MainApplication.getSharedPreferences().edit() - .putBoolean("developer", false).apply(); + MainApplication.getSharedPreferences().edit().putBoolean("developer", false).apply(); Toast.makeText(getContext(), // Tell the user something changed R.string.dev_mode_disabled, Toast.LENGTH_SHORT).show(); } else { - MainApplication.getSharedPreferences().edit() - .putBoolean("developer", true).apply(); + MainApplication.getSharedPreferences().edit().putBoolean("developer", true).apply(); Toast.makeText(getContext(), // Tell the user something changed R.string.dev_mode_enabled, Toast.LENGTH_SHORT).show(); } return true; } - IntentHelper.openUrl(p.getContext(), - "https://github.com/Fox2Code/FoxMagiskModuleManager"); + IntentHelper.openUrl(p.getContext(), "https://github.com/Fox2Code/FoxMagiskModuleManager"); return true; }); findPreference("pref_support").setOnPreferenceClickListener(p -> { @@ -287,14 +276,10 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { openFragment(libsBuilder.supportFragment(), R.string.licenses); return true; }); - findPreference("pref_pkg_info").setSummary( - BuildConfig.APPLICATION_ID + " v" + - BuildConfig.VERSION_NAME + " (" + - BuildConfig.VERSION_CODE + ")"); + findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID + " v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")"); } - private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity - requireActivity) { + private SharedPreferences.Editor getCrashReportingEditor(FragmentActivity requireActivity) { return requireActivity.getSharedPreferences("crash_reporting", Context.MODE_PRIVATE).edit(); } @@ -302,33 +287,20 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { FoxActivity compatActivity = getFoxActivity(this); compatActivity.setOnBackPressedCallback(this); compatActivity.setTitle(title); - compatActivity.getSupportFragmentManager() - .beginTransaction() - .replace(R.id.settings, fragment) - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) - .commit(); + compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, fragment).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit(); } @Override public boolean onBackPressed(FoxActivity compatActivity) { compatActivity.setTitle(R.string.app_name); - compatActivity.getSupportFragmentManager() - .beginTransaction().replace(R.id.settings, this) - .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) - .commit(); + compatActivity.getSupportFragmentManager().beginTransaction().replace(R.id.settings, this).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit(); return true; } private int currentLanguageLevel() { - int declaredLanguageLevel = - this.getResources().getInteger(R.integer.language_support_level); - if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) - return declaredLanguageLevel; - if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") && - this.getResources().getString(R.string.notification_update_pref) - .equals("Background modules update check") && - this.getResources().getString(R.string.notification_update_desc) - .equals("May increase battery usage")) { + int declaredLanguageLevel = this.getResources().getInteger(R.integer.language_support_level); + if (declaredLanguageLevel != LANGUAGE_SUPPORT_LEVEL) return declaredLanguageLevel; + if (!this.getResources().getConfiguration().locale.getLanguage().equals("en") && this.getResources().getString(R.string.notification_update_pref).equals("Background modules update check") && this.getResources().getString(R.string.notification_update_desc).equals("May increase battery usage")) { return 0; } return LANGUAGE_SUPPORT_LEVEL; @@ -348,13 +320,26 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { setRepoData(RepoManager.DG_MAGISK_REPO_GITHUB); updateCustomRepoList(true); if (!MainApplication.isDeveloper()) { - Objects.requireNonNull((Preference) findPreference( - "pref_androidacy_test_mode")).setVisible(false); + Objects.requireNonNull((Preference) findPreference("pref_androidacy_test_mode")).setVisible(false); + } else { + // Show a warning if user tries to enable test mode + Objects.requireNonNull((SwitchPreferenceCompat) findPreference("pref_androidacy_test_mode")).setOnPreferenceChangeListener((preference, newValue) -> { + if (Boolean.parseBoolean(String.valueOf(newValue))) { + new AlertDialog.Builder(this.requireContext()) + .setTitle(R.string.warning) + .setMessage(R.string.androidacy_test_mode_warning) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + // Do nothing + }) + .show(); + } + return true; + }); } - String originalApiKey = MainApplication.getSharedPreferences() - .getString("pref_androidacy_api_token", ""); + String originalApiKey = MainApplication.getSharedPreferences().getString("pref_androidacy_api_token", ""); // Create the pref_androidacy_repo_api_key text input with validation EditTextPreference prefAndroidacyRepoApiKey = findPreference("pref_androidacy_repo_api_key"); + assert prefAndroidacyRepoApiKey != null; prefAndroidacyRepoApiKey.setOnBindEditTextListener(editText -> { editText.setSingleLine(); // Make the single line wrap @@ -370,61 +355,48 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { // throw new RuntimeException("This is a test crash"); // get original api key String apiKey = String.valueOf(newValue); - // Show progress dialog - ProgressDialog progressDialog = new ProgressDialog(getContext()); - progressDialog.setMessage(getString(R.string.checking_api_key)); - progressDialog.setCancelable(false); - progressDialog.show(); + // Show snack bar with indeterminate progress + Snackbar.make(requireView(), R.string.checking_api_key, Snackbar.LENGTH_INDEFINITE).setAction(R.string.cancel, v -> { + // Restore the original api key + prefAndroidacyRepoApiKey.setText(originalApiKey); + }).show(); // Check the API key on a background thread new Thread(() -> { - // If key is empty, just remove it and show a toast + // If key is empty, just remove it and change the text of the snack bar if (apiKey.isEmpty()) { - MainApplication.getSharedPreferences().edit() - .remove("pref_androidacy_repo_api_key").apply(); - new Handler(Looper.getMainLooper()).post(() -> { - progressDialog.dismiss(); - Toast.makeText(getContext(), R.string.api_key_removed, Toast.LENGTH_SHORT).show(); - }); - return; + MainApplication.getSharedPreferences().edit().remove("pref_androidacy_repo_api_key").apply(); + new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_removed, Snackbar.LENGTH_SHORT).show()); } else { // If key < 64 chars, it's not valid if (apiKey.length() < 64) { new Handler(Looper.getMainLooper()).post(() -> { - progressDialog.dismiss(); + Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show(); // Save the original key - MainApplication.getSharedPreferences().edit() - .putString("pref_androidacy_api_token", originalApiKey).apply(); + MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply(); // Re-show the dialog with an error prefAndroidacyRepoApiKey.performClick(); // Show error prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid)); - // Set the error color - Toast.makeText(getContext(), R.string.api_key_invalid, Toast.LENGTH_SHORT).show(); }); - return; - } - } - // Check the API key - boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey); - // Update the UI on the main thread - new Handler(Looper.getMainLooper()).post(() -> { - progressDialog.dismiss(); - if (valid) { - // Show a success message - Toast.makeText(getContext(), R.string.api_key_valid, - Toast.LENGTH_SHORT).show(); - // Save the API key - MainApplication.getSharedPreferences().edit() - .putString("pref_androidacy_api_token", apiKey).apply(); } else { - // Show an error message - Toast.makeText(getContext(), R.string.api_key_invalid, - Toast.LENGTH_SHORT).show(); - // Restore the original API key - MainApplication.getSharedPreferences().edit() - .putString("pref_androidacy_api_token", originalApiKey).apply(); + boolean valid = AndroidacyRepoData.getInstance().isValidToken(apiKey); + // If the key is valid, save it + if (valid) { + MainApplication.getSharedPreferences().edit().putString("pref_androidacy_repo_api_key", apiKey).apply(); + new Handler(Looper.getMainLooper()).post(() -> Snackbar.make(requireView(), R.string.api_key_valid, Snackbar.LENGTH_SHORT).show()); + } else { + new Handler(Looper.getMainLooper()).post(() -> { + Snackbar.make(requireView(), R.string.api_key_invalid, Snackbar.LENGTH_SHORT).show(); + // Save the original key + MainApplication.getSharedPreferences().edit().putString("pref_androidacy_api_token", originalApiKey).apply(); + // Re-show the dialog with an error + prefAndroidacyRepoApiKey.performClick(); + // Show error + prefAndroidacyRepoApiKey.setDialogMessage(getString(R.string.api_key_invalid)); + }); + } } - }); + } }).start(); return true; }); @@ -432,21 +404,17 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { @SuppressLint("RestrictedApi") public void updateCustomRepoList(boolean initial) { - final SharedPreferences sharedPreferences = Objects.requireNonNull( - this.getPreferenceManager().getSharedPreferences()); - final CustomRepoManager customRepoManager = - RepoManager.getINSTANCE().getCustomRepoManager(); + final SharedPreferences sharedPreferences = Objects.requireNonNull(this.getPreferenceManager().getSharedPreferences()); + final CustomRepoManager customRepoManager = RepoManager.getINSTANCE().getCustomRepoManager(); for (int i = 0; i < CUSTOM_REPO_ENTRIES; i++) { CustomRepoData repoData = customRepoManager.getRepo(i); setRepoData(repoData, "pref_custom_repo_" + i); if (initial) { - Preference preference = - findPreference("pref_custom_repo_" + i + "_delete"); + Preference preference = findPreference("pref_custom_repo_" + i + "_delete"); if (preference == null) continue; final int index = i; preference.setOnPreferenceClickListener(preference1 -> { - sharedPreferences.edit().putBoolean( - "pref_custom_repo_" + index + "_enabled", false).apply(); + sharedPreferences.edit().putBoolean("pref_custom_repo_" + index + "_enabled", false).apply(); customRepoManager.removeRepo(index); updateCustomRepoList(false); return true; @@ -455,16 +423,14 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { } Preference preference = findPreference("pref_custom_add_repo"); if (preference == null) return; - preference.setVisible(customRepoManager.canAddRepo() && - customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES); + preference.setVisible(customRepoManager.canAddRepo() && customRepoManager.getRepoCount() < CUSTOM_REPO_ENTRIES); if (initial) { // Custom repo add button part. preference = findPreference("pref_custom_add_repo_button"); if (preference == null) return; preference.setOnPreferenceClickListener(preference1 -> { final Context context = this.requireContext(); MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context); - final MaterialAutoCompleteTextView input = - new MaterialAutoCompleteTextView(context); + final MaterialAutoCompleteTextView input = new MaterialAutoCompleteTextView(context); input.setHint(R.string.custom_url); builder.setIcon(R.drawable.ic_baseline_add_box_24); builder.setTitle(R.string.add_repo); @@ -472,8 +438,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { builder.setPositiveButton("OK", (dialog, which) -> { String text = String.valueOf(input.getText()); if (customRepoManager.canAddRepo(text)) { - final CustomRepoData customRepoData = - customRepoManager.addRepo(text); + final CustomRepoData customRepoData = customRepoManager.addRepo(text); customRepoData.setEnabled(true); new Thread("Add Custom Repo Thread") { @Override @@ -490,8 +455,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { }); builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); AlertDialog alertDialog = builder.show(); - final Button positiveButton = - alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); + final Button positiveButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); input.setValidator(new AutoCompleteTextView.Validator() { @Override public boolean isValid(CharSequence charSequence) { @@ -505,16 +469,12 @@ 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); + 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(false); - int dp10 = FoxDisplay.dpToPixel(10), - dp20 = FoxDisplay.dpToPixel(20); + int dp10 = FoxDisplay.dpToPixel(10), dp20 = FoxDisplay.dpToPixel(20); FoxViewCompat.setMargin(input, dp20, dp10, dp20, dp10); return true; }); @@ -523,8 +483,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { private void setRepoData(String url) { final RepoData repoData = RepoManager.getINSTANCE().get(url); - setRepoData(repoData, "pref_" + (repoData == null ? - RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId())); + setRepoData(repoData, "pref_" + (repoData == null ? RepoManager.internalIdOfUrl(url) : repoData.getPreferenceId())); } private void setRepoData(final RepoData repoData, String preferenceName) { @@ -539,11 +498,9 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { 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.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); + p.setTitle(((Boolean) newValue) ? R.string.repo_enabled : R.string.repo_disabled); return true; }); } @@ -554,8 +511,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { preference.setVisible(true); preference.setOnPreferenceClickListener(p -> { if (homepage.startsWith("https://www.androidacy.com/")) { - IntentHelper.openUrlAndroidacy( - getFoxActivity(this), homepage, true); + IntentHelper.openUrlAndroidacy(getFoxActivity(this), homepage, true); } else { IntentHelper.openUrl(getFoxActivity(this), homepage); } @@ -600,8 +556,7 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity { preference.setVisible(true); preference.setOnPreferenceClickListener(p -> { if (submissionUrl.startsWith("https://www.androidacy.com/")) { - IntentHelper.openUrlAndroidacy( - getFoxActivity(this), submissionUrl, true); + IntentHelper.openUrlAndroidacy(getFoxActivity(this), submissionUrl, true); } else { IntentHelper.openUrl(getFoxActivity(this), submissionUrl); } diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a552495..58a4726 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -24,4 +24,5 @@ #FFFFFFFF #FFFFFFFF #FFDADADA + #3A3A3A \ 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 fbbbc13..b2ba2b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -165,4 +165,7 @@ Please wait Successfully reset API key Validate + Warning! + You are setting the app to use a non-production endpoint for Androidacy. This may result in app instability and failure to load the online repo. Do NOT report bugs if you have this switch on. Change will take effect on app restart. + Crash the app for testing diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index eec6891..3678524 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -3,161 +3,165 @@ + app:key="pref_manage_repos" + app:singleLineTitle="false" + app:title="@string/manage_repos_pref" /> + app:title="@string/show_incompatible_pref" /> + app:title="@string/disable_low_quality_module_filter_pref" /> + app:title="@string/use_magisk_install_command_pref" /> + app:title="@string/notification_update_pref" /> + app:singleLineTitle="false" + app:title="@string/notification_update_debug_pref" /> + app:icon="@drawable/ic_baseline_palette_24" + app:key="pref_theme" + app:singleLineTitle="false" + app:title="@string/theme_pref" /> + app:key="pref_language_selector" + app:title="@string/language" /> + app:key="pref_enable_blur" + app:singleLineTitle="false" + app:title="@string/enable_blur_pref" /> + app:key="pref_force_dark_terminal" + app:singleLineTitle="false" + app:title="@string/force_dark_terminal_title" /> + app:key="pref_enable_monet" + app:singleLineTitle="false" + app:title="@string/enable_monet" /> + app:title="@string/wrap_text_pref" /> + app:title="@string/dns_over_https_pref" /> + app:title="@string/showcase_mode_pref" /> + app:title="@string/prevent_reboot_pref" /> - + app:title="@string/crash_reporting" /> + + - + + app:key="pref_update" + app:singleLineTitle="false" + app:title="@string/app_update" /> + app:key="pref_report_bug" + app:singleLineTitle="false" + app:title="@string/report_bugs" /> + app:key="pref_source_code" + app:singleLineTitle="false" + app:title="@string/source_code" /> + app:key="pref_support" + app:singleLineTitle="false" + app:title="@string/support" /> + app:key="pref_show_licenses" + app:singleLineTitle="false" + app:title="@string/show_licenses" /> + app:summary="@string/loading" /> \ No newline at end of file From 40e9d1f5fb798230bebce6b011ae85f12d89d441 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Mon, 29 Aug 2022 15:58:10 +0200 Subject: [PATCH 09/10] Fix and Refactor both RepoManager and BackgroundUpdateChecker --- app/build.gradle | 28 +++---- app/src/main/AndroidManifest.xml | 2 + .../main/java/com/fox2code/mmm/XHooks.java | 5 ++ .../background/BackgroundBootListener.java | 7 +- .../background/BackgroundUpdateChecker.java | 21 ++++-- .../fox2code/mmm/manager/ModuleManager.java | 39 ++-------- .../com/fox2code/mmm/repo/RepoManager.java | 61 ++++------------ .../com/fox2code/mmm/repo/RepoUpdater.java | 2 +- .../com/fox2code/mmm/utils/PropUtils.java | 7 +- .../com/fox2code/mmm/utils/SyncManager.java | 73 +++++++++++++++++++ 10 files changed, 134 insertions(+), 111 deletions(-) create mode 100644 app/src/main/java/com/fox2code/mmm/utils/SyncManager.java diff --git a/app/build.gradle b/app/build.gradle index a85e10c..aa4c246 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,6 @@ plugins { id 'com.android.application' id 'com.mikepenz.aboutlibraries.plugin' - id "io.sentry.android.gradle" version "3.1.4" } android { @@ -11,8 +10,8 @@ android { applicationId "com.fox2code.mmm" minSdk 21 targetSdk 33 - versionCode 54 - versionName "0.6.2" + versionCode 53 + versionName "0.6.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -35,11 +34,10 @@ android { "default" { dimension "type" buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true" - buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "true" buildConfigField( - "java.util.List", - "ENABLED_REPOS", - "java.util.Arrays.asList(\"magisk_alt_repo\", \"dg_magisk_repo\", \"androidacy_repo\")", + "java.util.List", + "ENABLED_REPOS", + "java.util.Arrays.asList(\"magisk_alt_repo\", \"androidacy_repo\")", ) } @@ -52,15 +50,12 @@ android { // with our keys, so the APK wouldn't install anyways). buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "false" - // Respect privacy paranoiac nature of F-Droid builds - buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "false" - // Repo with ads or tracking feature are disabled by default for the // F-Droid flavor. buildConfigField( - "java.util.List", - "ENABLED_REPOS", - "java.util.Arrays.asList(\"magisk_alt_repo\")", + "java.util.List", + "ENABLED_REPOS", + "java.util.Arrays.asList(\"magisk_alt_repo\")", ) } } @@ -80,7 +75,7 @@ aboutLibraries { } configurations { - implementation.exclude group: 'org.jetbrains', module: 'annotations' + implementation.exclude group: 'org.jetbrains' , module: 'annotations' } dependencies { @@ -92,9 +87,8 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.webkit:webkit:1.5.0' + implementation 'androidx.webkit:webkit:1.4.0' implementation 'com.google.android.material:material:1.6.1' - // Update root build.gradle instead. implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}" implementation "dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0" implementation "dev.rikka.rikkax.insets:insets:1.3.0" @@ -119,7 +113,7 @@ dependencies { implementation "com.caverock:androidsvg:1.4" // Test - testImplementation 'junit:junit:4.13.2' + testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 49205b5..d55947b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,6 +21,8 @@ + + repoModules = + RepoManager.getINSTANCE().getModules(); for (LocalModuleInfo localModuleInfo : ModuleManager.getINSTANCE().getModules().values()) { if ("twrp-keep".equals(localModuleInfo.id)) continue; - RepoModule repoModule = RepoManager.getINSTANCE() - .getModules().get(localModuleInfo.id); + RepoModule repoModule = repoModules.get(localModuleInfo.id); localModuleInfo.checkModuleUpdate(); - if (localModuleInfo.updateVersionCode > localModuleInfo.versionCode) { + if (localModuleInfo.updateVersionCode > localModuleInfo.versionCode && + !PropUtils.isNullString(localModuleInfo.updateVersion)) { moduleUpdateCount++; } else if (repoModule != null && - repoModule.moduleInfo.versionCode > localModuleInfo.versionCode) { + repoModule.moduleInfo.versionCode > localModuleInfo.versionCode && + !PropUtils.isNullString(repoModule.moduleInfo.version)) { moduleUpdateCount++; } } diff --git a/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java b/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java index a2483f3..4eccb72 100644 --- a/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java +++ b/app/src/main/java/com/fox2code/mmm/manager/ModuleManager.java @@ -3,9 +3,13 @@ package com.fox2code.mmm.manager; import android.content.SharedPreferences; import android.util.Log; +import androidx.annotation.NonNull; + import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.installer.InstallerInitializer; +import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.PropUtils; +import com.fox2code.mmm.utils.SyncManager; import com.topjohnwu.superuser.Shell; import com.topjohnwu.superuser.io.SuFile; import com.topjohnwu.superuser.io.SuFileInputStream; @@ -17,7 +21,7 @@ import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Iterator; -public final class ModuleManager { +public final class ModuleManager extends SyncManager { private static final String TAG = "ModuleManager"; private static final int FLAG_MM_INVALID = ModuleInfo.FLAG_METADATA_INVALID; @@ -28,9 +32,7 @@ public final class ModuleManager { private static final int FLAGS_RESET_UPDATE = FLAG_MM_INVALID | FLAG_MM_UNPROCESSED; private final HashMap moduleInfos; private final SharedPreferences bootPrefs; - private final Object scanLock = new Object(); private int updatableModuleCount = 0; - private boolean scanning; private static final ModuleManager INSTANCE = new ModuleManager(); @@ -43,36 +45,7 @@ public final class ModuleManager { this.bootPrefs = MainApplication.getBootSharedPreferences(); } - // MultiThread friendly method - public void scan() { - if (!this.scanning) { - // Do scan - synchronized (scanLock) { - this.scanning = true; - try { - this.scanInternal(); - } finally { - this.scanning = false; - } - } - } else { - // Wait for current scan - synchronized (scanLock) {} - } - } - - // Pause execution until the scan is completed if one is currently running - public void afterScan() { - if (this.scanning) synchronized (this.scanLock) {} - } - - public void runAfterScan(Runnable runnable) { - synchronized (this.scanLock) { - runnable.run(); - } - } - - private void scanInternal() { + protected void scanInternal(@NonNull UpdateListener updateListener) { boolean firstBoot = MainApplication.isFirstBoot(); boolean firstScan = this.bootPrefs.getBoolean("mm_first_scan", true); SharedPreferences.Editor editor = firstScan ? this.bootPrefs.edit() : null; 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 26b85bd..4d9baca 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -4,6 +4,8 @@ import android.content.Context; import android.content.SharedPreferences; import android.util.Log; +import androidx.annotation.NonNull; + import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.XHooks; import com.fox2code.mmm.androidacy.AndroidacyRepoData; @@ -12,14 +14,16 @@ import com.fox2code.mmm.utils.Files; import com.fox2code.mmm.utils.Hashes; import com.fox2code.mmm.utils.Http; import com.fox2code.mmm.utils.PropUtils; +import com.fox2code.mmm.utils.SyncManager; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; -public final class RepoManager { +public final class RepoManager extends SyncManager { private static final String TAG = "RepoManager"; private static final String MAGISK_REPO_MANAGER = @@ -75,6 +79,7 @@ public final class RepoManager { private boolean initialized; private RepoManager(MainApplication mainApplication) { + INSTANCE = this; // Set early fox XHooks this.initialized = false; this.mainApplication = mainApplication; this.repoData = new LinkedHashMap<>(); @@ -90,6 +95,7 @@ public final class RepoManager { dgRepo.defaultWebsite = "https://dergoogler.com/repo"; this.androidacyRepoData = this.addAndroidacyRepoData(); this.customRepoManager = new CustomRepoManager(mainApplication, this); + XHooks.onRepoManagerInitialize(); // Populate default cache boolean x = false; for (RepoData repoData:this.repoData.values()) { @@ -136,7 +142,7 @@ public final class RepoManager { if (DG_MAGISK_REPO.equals(url)) url = DG_MAGISK_REPO_GITHUB; RepoData repoData; - synchronized (this.repoUpdateLock) { + synchronized (this.syncLock) { repoData = this.repoData.get(url); if (repoData == null) { if (ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT.equals(url) || @@ -152,57 +158,18 @@ public final class RepoManager { return repoData; } - public interface UpdateListener { - void update(double value); - } - - private final Object repoUpdateLock = new Object(); - private boolean repoUpdating; private boolean repoLastResult = true; - public boolean isRepoUpdating() { - return this.repoUpdating; - } - - public void afterUpdate() { - if (this.repoUpdating) synchronized (this.repoUpdateLock) {} - } - - public void runAfterUpdate(Runnable runnable) { - synchronized (this.repoUpdateLock) { - runnable.run(); - } - } - - // MultiThread friendly method - public void update(UpdateListener updateListener) { - if (updateListener == null) - updateListener = value -> {}; - if (!this.repoUpdating) { - // Do scan - synchronized (this.repoUpdateLock) { - this.repoUpdating = true; - try { - this.repoLastResult = - this.scanInternal(updateListener); - } finally { - this.repoUpdating = false; - } - } - } else { - // Wait for current scan - synchronized (this.repoUpdateLock) {} - } - } - private static final double STEP1 = 0.1D; private static final double STEP2 = 0.8D; private static final double STEP3 = 0.1D; - private boolean scanInternal(UpdateListener updateListener) { + protected void scanInternal(@NonNull UpdateListener updateListener) { this.modules.clear(); updateListener.update(0D); - RepoData[] repoDatas = this.repoData.values().toArray(new RepoData[0]); + // Using LinkedHashSet to deduplicate Androidacy entry. + RepoData[] repoDatas = new LinkedHashSet<>( + this.repoData.values()).toArray(new RepoData[0]); RepoUpdater[] repoUpdaters = new RepoUpdater[repoDatas.length]; int moduleToUpdate = 0; for (int i = 0; i < repoDatas.length; i++) { @@ -215,7 +182,7 @@ public final class RepoManager { for (int i = 0; i < repoUpdaters.length; i++) { List repoModules = repoUpdaters[i].toUpdate(); RepoData repoData = repoDatas[i]; - Log.d(TAG, "Registering " + repoData.name); + Log.d(TAG, "Registering " + repoData.getName()); for (RepoModule repoModule:repoModules) { try { if (repoModule.propUrl != null && @@ -261,7 +228,7 @@ public final class RepoManager { } Log.i(TAG, "Got " + this.modules.size() + " modules!"); updateListener.update(1D); - return hasInternet; + this.repoLastResult = hasInternet; } public void updateEnabledStates() { 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 cd5c301..e2614b9 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoUpdater.java @@ -48,7 +48,7 @@ public class RepoUpdater { // Return repo to update return this.toUpdate.size(); } catch (Exception e) { - Log.e(TAG, "Failed to get manifest", e); + Log.e(TAG, "Failed to get manifest of " + this.repoData.id, e); this.indexRaw = null; this.toUpdate = Collections.emptyList(); this.toApply = Collections.emptySet(); diff --git a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java index 3403d94..246307c 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java +++ b/app/src/main/java/com/fox2code/mmm/utils/PropUtils.java @@ -380,10 +380,13 @@ public class PropUtils { moduleId.substring(1).replace('_', ' '); } + public static boolean isNullString(String string) { + return string == null || string.isEmpty() || "null".equals(string); + } + // Make versionName no longer than 16 charters to avoid UI overflow. public static String shortenVersionName(String versionName, long versionCode) { - if (versionName == null || versionName.isEmpty() || - "null".equals(versionName)) return "v" + versionCode; + if (isNullString(versionName)) return "v" + versionCode; if (versionName.length() <= 16) return versionName; int i = versionName.lastIndexOf('.'); if (i != -1 && i <= 16 && versionName.indexOf('.') != i diff --git a/app/src/main/java/com/fox2code/mmm/utils/SyncManager.java b/app/src/main/java/com/fox2code/mmm/utils/SyncManager.java new file mode 100644 index 0000000..718286b --- /dev/null +++ b/app/src/main/java/com/fox2code/mmm/utils/SyncManager.java @@ -0,0 +1,73 @@ +package com.fox2code.mmm.utils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Manager that want both to be thread safe and not to worry about thread safety + * {@link #scan()} and {@link #update(UpdateListener)} can be called from multiple + * thread at the same time, {@link #scanInternal(UpdateListener)} will only be + * called from one thread at a time only. + */ +public abstract class SyncManager { + private static final UpdateListener NO_OP = value -> {}; + protected final Object syncLock = new Object(); + private boolean syncing; + + public final void scan() { + this.update(null); + } + + // MultiThread friendly method + public final void update(@Nullable UpdateListener updateListener) { + if (updateListener == null) updateListener = NO_OP; + if (!this.syncing) { + // Do scan + synchronized (this.syncLock) { + this.syncing = true; + try { + this.scanInternal(updateListener); + } finally { + this.syncing = false; + } + } + } else { + // Wait for current scan + synchronized (this.syncLock) { + Thread.yield(); + } + } + } + + // Pause execution until the scan is completed if one is currently running + public final void afterScan() { + if (this.syncing) synchronized (this.syncLock) { Thread.yield(); } + } + + public final void runAfterScan(Runnable runnable) { + synchronized (this.syncLock) { + runnable.run(); + } + } + + public final boolean isRepoUpdating() { + return this.syncing; + } + + public final void afterUpdate() { + if (this.syncing) synchronized (this.syncLock) { Thread.yield(); } + } + + public final void runAfterUpdate(Runnable runnable) { + synchronized (this.syncLock) { + runnable.run(); + } + } + + // This method can't be called twice at the same time. + protected abstract void scanInternal(@NonNull UpdateListener updateListener); + + public interface UpdateListener { + void update(double value); + } +} From e1ce5f68a793a80bf7e6737a03f95ca78febe4cc Mon Sep 17 00:00:00 2001 From: androidacy-user Date: Mon, 29 Aug 2022 11:32:28 -0400 Subject: [PATCH 10/10] Update dependencies Signed-off-by: androidacy-user --- app/build.gradle | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index aa4c246..94fb2f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,6 +34,7 @@ android { "default" { dimension "type" buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true" + buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "true" buildConfigField( "java.util.List", "ENABLED_REPOS", @@ -50,6 +51,9 @@ android { // with our keys, so the APK wouldn't install anyways). buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "false" + // Disable crash reporting for F-Droid flavor by default + buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "false" + // Repo with ads or tracking feature are disabled by default for the // F-Droid flavor. buildConfigField( @@ -79,6 +83,8 @@ configurations { } dependencies { + // Error reporting + implementation 'io.sentry:sentry-android:6.4.0' // UI implementation 'androidx.appcompat:appcompat:1.5.0' implementation 'androidx.emoji2:emoji2:1.2.0' @@ -87,7 +93,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'androidx.webkit:webkit:1.4.0' + implementation 'androidx.webkit:webkit:1.5.0' implementation 'com.google.android.material:material:1.6.1' implementation "com.mikepenz:aboutlibraries:${latestAboutLibsRelease}" implementation "dev.rikka.rikkax.layoutinflater:layoutinflater:1.2.0"