diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 888744f..5c61a76 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,7 +29,7 @@ = Build.VERSION_CODES.M) { + showSetupBox(); + + // Wait for pref_first_launch to be false + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this); + while (prefs.getBoolean("pref_first_launch", true)) { + try { + //noinspection BusyWait + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + ensurePermissions(); Log.i(TAG, "Scanning for modules!"); if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Initialize Update"); final int max = ModuleManager.getINSTANCE().getUpdatableModuleCount(); @@ -260,6 +279,16 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe String lastEventId = preferences.getString("lastEventId", ""); if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Last Event ID: " + lastEventId); if (!lastEventId.equals("")) { + try { + ExperimentalCronetEngine cronetEngine = new ExperimentalCronetEngine.Builder(this).build(); + CronetURLStreamHandlerFactory cronetURLStreamHandlerFactory = new CronetURLStreamHandlerFactory(cronetEngine); + URL.setURLStreamHandlerFactory(cronetURLStreamHandlerFactory); + } catch (Exception e) { + if (BuildConfig.DEBUG) { + Log.w(TAG, "Failed to setup cronet HTTPURLConnection factory", e); + Log.w(TAG, "This might mean the factory is already set"); + } + } // Three edit texts for the user to enter their email, name and a description of the issue EditText email = new EditText(this); email.setHint(R.string.email); @@ -320,9 +349,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe if (connection.getResponseCode() == 200) { runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_success, Toast.LENGTH_LONG).show()); } else { - runOnUiThread(() -> Toast.makeText(this, - R.string.sentry_dialogue_failed_toast, - Toast.LENGTH_LONG).show()); + runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_failed_toast, Toast.LENGTH_LONG).show()); } } catch (IOException | JSONException ignored) { // Show a toast if the user feedback could not be submitted @@ -619,4 +646,53 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe } } } + + // Method to show a setup box on first launch + @RequiresApi(api = Build.VERSION_CODES.M) + @SuppressLint({"InflateParams", "RestrictedApi", "UnspecifiedImmutableFlag", "ApplySharedPref"}) + private void showSetupBox() { + // Check if this is the first launch + if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("pref_first_launch", true)) { + MainApplication.getBootSharedPreferences().edit().putBoolean("mm_first_scan", false).commit(); + // Show setup box + runOnUiThread(() -> { + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); + builder.setCancelable(false); + builder.setTitle(R.string.setup_title); + builder.setView(getLayoutInflater().inflate(R.layout.setup_box, null)); + // For now, we'll just have the positive button save the preferences and dismiss the dialog + builder.setPositiveButton(R.string.setup_button, (dialog, which) -> { + // Set the preferences + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + prefs.edit().putBoolean("pref_background_update_check", + ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_background_update_check))).isChecked()).commit(); + prefs.edit().putBoolean("pref_crash_reporting", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_crash_reporting))).isChecked()).commit(); + prefs.edit().putBoolean("pref_androidacy_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_androidacy_repo))).isChecked()).commit(); + prefs.edit().putBoolean("pref_magisk_alt_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_magisk_alt_repo))).isChecked()).commit(); + if (BuildConfig.DEBUG) { + Log.d("MainActivity", String.format("Background update check: %s, Crash reporting: %s, Androidacy repo: %s, Magisk alt repo: %s", + prefs.getBoolean("pref_background_update_check", false), + prefs.getBoolean("pref_crash_reporting", false), + prefs.getBoolean("pref_androidacy_repo_enabled", false), + prefs.getBoolean("pref_magisk_alt_repo_enabled", false))); + } + // Set pref_first_launch to false + PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("pref_first_launch", + false).commit(); + // Restart the app + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + }); + builder.setNegativeButton(R.string.setup_button_skip, (dialog, which) -> { + // Set pref_first_launch to false + PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("pref_first_launch", + false).commit(); + dialog.dismiss(); + }); + builder.show(); + }); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/fox2code/mmm/NotificationType.java b/app/src/main/java/com/fox2code/mmm/NotificationType.java index b71d25e..57ed5a5 100644 --- a/app/src/main/java/com/fox2code/mmm/NotificationType.java +++ b/app/src/main/java/com/fox2code/mmm/NotificationType.java @@ -64,8 +64,7 @@ public enum NotificationType implements NotificationTypeCst { NO_INTERNET(R.string.fail_internet, R.drawable.ic_baseline_cloud_off_24) { @Override public boolean shouldRemove() { - return AppUpdateManager.getAppUpdateManager().isLastCheckSuccess() || - RepoManager.getINSTANCE().hasConnectivity(); + return RepoManager.getINSTANCE().hasConnectivity(); } }, REPO_UPDATE_FAILED(R.string.repo_update_failed, R.drawable.ic_baseline_cloud_off_24) { 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 c2479c8..9e8dc38 100644 --- a/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java +++ b/app/src/main/java/com/fox2code/mmm/repo/RepoManager.java @@ -202,9 +202,12 @@ public final class RepoManager extends SyncManager { if (repoData == null) { if (ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT.equals(url) || ANDROIDACY_MAGISK_REPO_ENDPOINT.equals(url)) { - if (this.androidacyRepoData != null) + //noinspection ReplaceNullCheck + if (this.androidacyRepoData != null) { return this.androidacyRepoData; - return this.addAndroidacyRepoData(); + } else { + return this.addAndroidacyRepoData(); + } } else { return this.addRepoData(url, fallBackName); } @@ -289,7 +292,6 @@ public final class RepoManager extends SyncManager { HttpURLConnection urlConnection = (HttpURLConnection) new URL( "https://connectivitycheck.gstatic.com/generate_204").openConnection(); urlConnection.setInstanceFollowRedirects(false); - urlConnection.setConnectTimeout(1000); urlConnection.setReadTimeout(1000); urlConnection.setUseCaches(false); urlConnection.getInputStream().close(); 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 05304c7..58ba64d 100644 --- a/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java +++ b/app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java @@ -9,6 +9,8 @@ import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.Signature; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -61,6 +63,7 @@ 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.google.common.hash.Hashing; import com.mikepenz.aboutlibraries.LibsBuilder; import com.topjohnwu.superuser.internal.UiThreadHandler; @@ -461,9 +464,24 @@ 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 + ")" + - getRepackageState()); // State may not be "I am just running from myself as myself" + // Determine if this is an official build based on the signature + boolean isOfficial = false; + try { + // Get the signature of the key used to sign the app + @SuppressLint("PackageManagerGetSignatures") Signature[] signatures = requireContext().getPackageManager().getPackageInfo(requireContext().getPackageName(), PackageManager.GET_SIGNATURES).signatures; + String officialSignatureHash = + "7bec7c4462f4aac616612d9f56a023ee3046e83afa956463b5fab547fd0a0be6"; + String ourSignatureHash = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString(); + isOfficial = ourSignatureHash.equals(officialSignatureHash); + } catch (PackageManager.NameNotFoundException ignored) { + } + String flavor = BuildConfig.FLAVOR; + String type = BuildConfig.BUILD_TYPE; + // Set the summary of pref_pkg_info to something like Github-debug v1.0 (123) (Official) + String pkgInfo = getString(R.string.pref_pkg_info_summary, flavor + "-" + type, + BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, isOfficial ? + getString(R.string.official) : getString(R.string.unofficial)); + findPreference("pref_pkg_info").setSummary(pkgInfo); } @SuppressLint("RestrictedApi") diff --git a/app/src/main/java/com/fox2code/mmm/utils/Http.java b/app/src/main/java/com/fox2code/mmm/utils/Http.java index 6affed8..39e04dd 100644 --- a/app/src/main/java/com/fox2code/mmm/utils/Http.java +++ b/app/src/main/java/com/fox2code/mmm/utils/Http.java @@ -54,7 +54,6 @@ import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.dnsoverhttps.DnsOverHttps; -import okhttp3.logging.HttpLoggingInterceptor; import okio.BufferedSink; public class Http { @@ -159,6 +158,12 @@ public class Http { } builder.setStoragePath(mainApplication.getCacheDir().getAbsolutePath() + "/cronet"); builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 10 * 1024 * 1024); + // Add quic hint + builder.addQuicHint("github.com", 443, 443); + builder.addQuicHint("githubusercontent.com", 443, 443); + builder.addQuicHint("jsdelivr.net", 443, 443); + builder.addQuicHint("androidacy.com", 443, 443); + builder.addQuicHint("sentry.io", 443, 443); CronetEngine engine = builder.build(); httpclientBuilder.addInterceptor(CronetInterceptor.newBuilder(engine).build()); } catch (Exception e) { @@ -172,13 +177,6 @@ public class Http { httpClient = followRedirects(httpclientBuilder, true).build(); followRedirects(httpclientBuilder, false).build(); httpclientBuilder.dns(fallbackDNS); - if (BuildConfig.DEBUG) { - // Enable logging - HttpLoggingInterceptor logging = new HttpLoggingInterceptor(s -> Log.d(TAG, s)); - logging.setLevel(HttpLoggingInterceptor.Level.BODY); - httpclientBuilder.addInterceptor(logging); - Log.d(TAG, "OkHttp logging enabled"); - } httpClientDoH = followRedirects(httpclientBuilder, true).build(); followRedirects(httpclientBuilder, false).build(); httpclientBuilder.cache(new Cache(new File(mainApplication.getCacheDir(), "http_cache"), 16L * 1024L * 1024L)); // 16Mib of cache @@ -343,24 +341,49 @@ public class Http { } public static void ensureCacheDirs(MainActivity mainActivity) { + // Recursively ensure cache dirs for webview exist under our cache dir File cacheDir = mainActivity.getCacheDir(); - File cacheDir2 = new File(cacheDir, "HTTP Cache"); - if (!cacheDir2.exists()) { - if (!cacheDir2.mkdirs()) { - Log.e(TAG, "Failed to create cache dir"); + File webviewCacheDir = new File(cacheDir, "WebView"); + if (!webviewCacheDir.exists()) { + if (!webviewCacheDir.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); + } + } + File webviewCacheDirCache = new File(webviewCacheDir, "Default"); + if (!webviewCacheDirCache.exists()) { + if (!webviewCacheDirCache.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); + } + } + File webviewCacheDirCacheCodeCache = new File(webviewCacheDirCache, "HTTP Cache"); + if (!webviewCacheDirCacheCodeCache.exists()) { + if (!webviewCacheDirCacheCodeCache.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); + } + } + File webviewCacheDirCacheCodeCacheIndex = new File(webviewCacheDirCacheCodeCache, "Code Cache"); + if (!webviewCacheDirCacheCodeCacheIndex.exists()) { + if (!webviewCacheDirCacheCodeCacheIndex.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); + } + } + File webviewCacheDirCacheCodeCacheIndexIndex = new File(webviewCacheDirCacheCodeCacheIndex, "Index"); + if (!webviewCacheDirCacheCodeCacheIndexIndex.exists()) { + if (!webviewCacheDirCacheCodeCacheIndexIndex.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); } } - // Ensure js and wasm cache dirs - File jsCacheDir = new File(cacheDir2, "js"); - if (!jsCacheDir.exists()) { - if (!jsCacheDir.mkdirs()) { - Log.e(TAG, "Failed to create js cache dir"); + // Create the js and wasm dirs + File webviewCacheDirCacheCodeCacheIndexIndexJs = new File(webviewCacheDirCacheCodeCache, "js"); + if (!webviewCacheDirCacheCodeCacheIndexIndexJs.exists()) { + if (!webviewCacheDirCacheCodeCacheIndexIndexJs.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); } } - File wasmCacheDir = new File(cacheDir2, "wasm"); - if (!wasmCacheDir.exists()) { - if (!wasmCacheDir.mkdirs()) { - Log.e(TAG, "Failed to create wasm cache dir"); + File webviewCacheDirCacheCodeCacheIndexIndexWasm = new File(webviewCacheDirCacheCodeCache, "wasm"); + if (!webviewCacheDirCacheCodeCacheIndexIndexWasm.exists()) { + if (!webviewCacheDirCacheCodeCacheIndexIndexWasm.mkdirs()) { + Log.e(TAG, "Failed to create webview cache dir"); } } } diff --git a/app/src/main/res/layout/setup_box.xml b/app/src/main/res/layout/setup_box.xml new file mode 100644 index 0000000..c362f2c --- /dev/null +++ b/app/src/main/res/layout/setup_box.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/raw/sentry_io_root_ca b/app/src/main/res/raw/sentry_io_root_ca new file mode 100644 index 0000000..fd4341d --- /dev/null +++ b/app/src/main/res/raw/sentry_io_root_ca @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/app/src/main/res/raw/sentry_root_ca b/app/src/main/res/raw/sentry_root_ca new file mode 100644 index 0000000..b85c803 --- /dev/null +++ b/app/src/main/res/raw/sentry_root_ca @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8f7ad0b..0e85cc0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -208,8 +208,8 @@ by adding some information about the error below.\nName and email are optional but will allow us to contact you if needed for more information. Oops! Looks like the app closed unexpectedly. - Name - Email + Your name + Your email Tell us what happened Submit Could not submit feedback due to an error @@ -218,4 +218,19 @@ Could not submit feedback as no description was provided Scroll to online repo + %1$s v%2$s (%3$o) | %4$s Build + Official + Unofficial + First time setup + Looks like this is your first time opening the app.\nPick + the basic options you desire below. You can change them later in settings. + Finish setup + Allow us to check for updates in the background. May use more battery. + Enable the Androidacy repo, which features user reviews, automatic virus scans, fast updates, a wide selection, and is backed by Androidacy. + Enable the Magisk Alternative Repo. Less rules and reviewing than the original. Fully hosted on GitHub. + Enable automatic crash reporting and performance monitoring. Crash reports are anonymized with all personal info removed, and are onlly accessible to the developers. Uses sentry.io. + You can add custom repos later in settings. + Repos + Misc settings + Skip diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml index dbc7e47..363ca6c 100644 --- a/app/src/main/res/xml/network_security_config.xml +++ b/app/src/main/res/xml/network_security_config.xml @@ -8,20 +8,27 @@ github.com + githubusercontent.com - githubusercontent.com + gstatic.com - + - gstatic.com + ingest.sentry.io - + + + + + sentry.io + + \ No newline at end of file diff --git a/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java b/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java index ba6b121..ceeae18 100644 --- a/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java +++ b/app/src/sentry/java/com/fox2code/mmm/sentry/SentryMain.java @@ -25,9 +25,9 @@ public class SentryMain { @SuppressLint({"RestrictedApi", "UnspecifiedImmutableFlag"}) public static void initialize(final MainApplication mainApplication) { Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { - SharedPreferences.Editor editor = mainApplication.getSharedPreferences( - "sentry", Context.MODE_PRIVATE).edit(); + SharedPreferences.Editor editor = mainApplication.getSharedPreferences("sentry", Context.MODE_PRIVATE).edit(); editor.putString("lastExitReason", "crash"); + editor.putLong("lastExitTime", System.currentTimeMillis()); editor.apply(); // If we just let the default uncaught exception handler handle the // exception, the app will hang and never close. @@ -56,9 +56,7 @@ public class SentryMain { // With this callback, you can modify the event or, when returning null, also discard the event. options.setBeforeSend((event, hint) -> { // Save lastEventId to private shared preferences - SharedPreferences sharedPreferences = MainApplication.getINSTANCE().getSharedPreferences( - "sentry", - Context.MODE_PRIVATE); + SharedPreferences sharedPreferences = MainApplication.getINSTANCE().getSharedPreferences("sentry", Context.MODE_PRIVATE); String lastEventId = Objects.requireNonNull(event.getEventId()).toString(); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("lastEventId", lastEventId);