Skip to content
This repository was archived by the owner on May 4, 2023. It is now read-only.

Commit 2c67557

Browse files
[DO NOT MERGE] Add setup screen
Also the usual fixes and whatnot Note the setup is rather broken right now as something else is overwriting the pref right away Signed-off-by: androidacy-user <opensource@androidacy.com>
1 parent 20d51c5 commit 2c67557

File tree

12 files changed

+344
-45
lines changed

12 files changed

+344
-45
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
<application
3131
android:name=".MainApplication"
32-
android:allowBackup="true"
32+
android:allowBackup="false"
3333
android:dataExtractionRules="@xml/data_extraction_rules"
3434
android:fullBackupContent="@xml/full_backup_content"
3535
android:icon="@mipmap/ic_launcher"

app/src/main/java/com/fox2code/mmm/MainActivity.java

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import android.widget.Toast;
2727

2828
import androidx.annotation.NonNull;
29+
import androidx.annotation.RequiresApi;
30+
import androidx.appcompat.app.AlertDialog;
2931
import androidx.appcompat.widget.SearchView;
3032
import androidx.cardview.widget.CardView;
3133
import androidx.core.app.NotificationManagerCompat;
@@ -51,6 +53,7 @@
5153
import com.fox2code.mmm.utils.Http;
5254
import com.fox2code.mmm.utils.IntentHelper;
5355
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
56+
import com.google.android.material.materialswitch.MaterialSwitch;
5457
import com.google.android.material.progressindicator.LinearProgressIndicator;
5558

5659
import org.chromium.net.ExperimentalCronetEngine;
@@ -61,6 +64,7 @@
6164
import java.io.IOException;
6265
import java.net.HttpURLConnection;
6366
import java.net.URL;
67+
import java.util.Objects;
6468

6569
import eightbitlab.com.blurview.BlurView;
6670

@@ -168,7 +172,6 @@ public void onPathReceived(String path) {
168172
moduleViewListBuilder.addNotification(NotificationType.MAGISK_OUTDATED);
169173
if (!MainApplication.isShowcaseMode())
170174
moduleViewListBuilder.addNotification(NotificationType.INSTALL_FROM_STORAGE);
171-
ensurePermissions();
172175
ModuleManager.getINSTANCE().scan();
173176
ModuleManager.getINSTANCE().runAfterScan(moduleViewListBuilder::appendInstalledModules);
174177
this.commonNext();
@@ -195,6 +198,22 @@ public void commonNext() {
195198
// Fix insets not being accounted for correctly
196199
updateScreenInsets(getResources().getConfiguration());
197200
});
201+
202+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
203+
showSetupBox();
204+
205+
// Wait for pref_first_launch to be false
206+
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
207+
while (prefs.getBoolean("pref_first_launch", true)) {
208+
try {
209+
//noinspection BusyWait
210+
Thread.sleep(100);
211+
} catch (InterruptedException e) {
212+
e.printStackTrace();
213+
}
214+
}
215+
}
216+
ensurePermissions();
198217
Log.i(TAG, "Scanning for modules!");
199218
if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Initialize Update");
200219
final int max = ModuleManager.getINSTANCE().getUpdatableModuleCount();
@@ -260,6 +279,16 @@ public void commonNext() {
260279
String lastEventId = preferences.getString("lastEventId", "");
261280
if (BuildConfig.DEBUG) Log.d("NoodleDebug", "Last Event ID: " + lastEventId);
262281
if (!lastEventId.equals("")) {
282+
try {
283+
ExperimentalCronetEngine cronetEngine = new ExperimentalCronetEngine.Builder(this).build();
284+
CronetURLStreamHandlerFactory cronetURLStreamHandlerFactory = new CronetURLStreamHandlerFactory(cronetEngine);
285+
URL.setURLStreamHandlerFactory(cronetURLStreamHandlerFactory);
286+
} catch (Exception e) {
287+
if (BuildConfig.DEBUG) {
288+
Log.w(TAG, "Failed to setup cronet HTTPURLConnection factory", e);
289+
Log.w(TAG, "This might mean the factory is already set");
290+
}
291+
}
263292
// Three edit texts for the user to enter their email, name and a description of the issue
264293
EditText email = new EditText(this);
265294
email.setHint(R.string.email);
@@ -320,9 +349,7 @@ public void commonNext() {
320349
if (connection.getResponseCode() == 200) {
321350
runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_success, Toast.LENGTH_LONG).show());
322351
} else {
323-
runOnUiThread(() -> Toast.makeText(this,
324-
R.string.sentry_dialogue_failed_toast,
325-
Toast.LENGTH_LONG).show());
352+
runOnUiThread(() -> Toast.makeText(this, R.string.sentry_dialogue_failed_toast, Toast.LENGTH_LONG).show());
326353
}
327354
} catch (IOException | JSONException ignored) {
328355
// Show a toast if the user feedback could not be submitted
@@ -619,4 +646,53 @@ private void ensurePermissions() {
619646
}
620647
}
621648
}
649+
650+
// Method to show a setup box on first launch
651+
@RequiresApi(api = Build.VERSION_CODES.M)
652+
@SuppressLint({"InflateParams", "RestrictedApi", "UnspecifiedImmutableFlag", "ApplySharedPref"})
653+
private void showSetupBox() {
654+
// Check if this is the first launch
655+
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean("pref_first_launch", true)) {
656+
MainApplication.getBootSharedPreferences().edit().putBoolean("mm_first_scan", false).commit();
657+
// Show setup box
658+
runOnUiThread(() -> {
659+
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
660+
builder.setCancelable(false);
661+
builder.setTitle(R.string.setup_title);
662+
builder.setView(getLayoutInflater().inflate(R.layout.setup_box, null));
663+
// For now, we'll just have the positive button save the preferences and dismiss the dialog
664+
builder.setPositiveButton(R.string.setup_button, (dialog, which) -> {
665+
// Set the preferences
666+
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
667+
prefs.edit().putBoolean("pref_background_update_check",
668+
((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_background_update_check))).isChecked()).commit();
669+
prefs.edit().putBoolean("pref_crash_reporting", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_crash_reporting))).isChecked()).commit();
670+
prefs.edit().putBoolean("pref_androidacy_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_androidacy_repo))).isChecked()).commit();
671+
prefs.edit().putBoolean("pref_magisk_alt_repo_enabled", ((MaterialSwitch) Objects.requireNonNull(((AlertDialog) dialog).findViewById(R.id.setup_magisk_alt_repo))).isChecked()).commit();
672+
if (BuildConfig.DEBUG) {
673+
Log.d("MainActivity", String.format("Background update check: %s, Crash reporting: %s, Androidacy repo: %s, Magisk alt repo: %s",
674+
prefs.getBoolean("pref_background_update_check", false),
675+
prefs.getBoolean("pref_crash_reporting", false),
676+
prefs.getBoolean("pref_androidacy_repo_enabled", false),
677+
prefs.getBoolean("pref_magisk_alt_repo_enabled", false)));
678+
}
679+
// Set pref_first_launch to false
680+
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("pref_first_launch",
681+
false).commit();
682+
// Restart the app
683+
Intent intent = new Intent(this, MainActivity.class);
684+
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
685+
startActivity(intent);
686+
finish();
687+
});
688+
builder.setNegativeButton(R.string.setup_button_skip, (dialog, which) -> {
689+
// Set pref_first_launch to false
690+
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("pref_first_launch",
691+
false).commit();
692+
dialog.dismiss();
693+
});
694+
builder.show();
695+
});
696+
}
697+
}
622698
}

app/src/main/java/com/fox2code/mmm/NotificationType.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ public boolean shouldRemove() {
6464
NO_INTERNET(R.string.fail_internet, R.drawable.ic_baseline_cloud_off_24) {
6565
@Override
6666
public boolean shouldRemove() {
67-
return AppUpdateManager.getAppUpdateManager().isLastCheckSuccess() ||
68-
RepoManager.getINSTANCE().hasConnectivity();
67+
return RepoManager.getINSTANCE().hasConnectivity();
6968
}
7069
},
7170
REPO_UPDATE_FAILED(R.string.repo_update_failed, R.drawable.ic_baseline_cloud_off_24) {

app/src/main/java/com/fox2code/mmm/repo/RepoManager.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,12 @@ public RepoData addOrGet(String url, String fallBackName) {
202202
if (repoData == null) {
203203
if (ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT.equals(url) ||
204204
ANDROIDACY_MAGISK_REPO_ENDPOINT.equals(url)) {
205-
if (this.androidacyRepoData != null)
205+
//noinspection ReplaceNullCheck
206+
if (this.androidacyRepoData != null) {
206207
return this.androidacyRepoData;
207-
return this.addAndroidacyRepoData();
208+
} else {
209+
return this.addAndroidacyRepoData();
210+
}
208211
} else {
209212
return this.addRepoData(url, fallBackName);
210213
}
@@ -289,7 +292,6 @@ protected void scanInternal(@NonNull UpdateListener updateListener) {
289292
HttpURLConnection urlConnection = (HttpURLConnection) new URL(
290293
"https://connectivitycheck.gstatic.com/generate_204").openConnection();
291294
urlConnection.setInstanceFollowRedirects(false);
292-
urlConnection.setConnectTimeout(1000);
293295
urlConnection.setReadTimeout(1000);
294296
urlConnection.setUseCaches(false);
295297
urlConnection.getInputStream().close();

app/src/main/java/com/fox2code/mmm/settings/SettingsActivity.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import android.content.Context;
1010
import android.content.Intent;
1111
import android.content.SharedPreferences;
12+
import android.content.pm.PackageManager;
13+
import android.content.pm.Signature;
1214
import android.net.Uri;
1315
import android.os.Build;
1416
import android.os.Bundle;
@@ -61,6 +63,7 @@
6163
import com.google.android.material.internal.TextWatcherAdapter;
6264
import com.google.android.material.snackbar.Snackbar;
6365
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
66+
import com.google.common.hash.Hashing;
6467
import com.mikepenz.aboutlibraries.LibsBuilder;
6568
import com.topjohnwu.superuser.internal.UiThreadHandler;
6669

@@ -461,9 +464,24 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
461464
openFragment(libsBuilder.supportFragment(), R.string.licenses);
462465
return true;
463466
});
464-
findPreference("pref_pkg_info").setSummary(BuildConfig.APPLICATION_ID +
465-
" v" + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")" +
466-
getRepackageState()); // State may not be "I am just running from myself as myself"
467+
// Determine if this is an official build based on the signature
468+
boolean isOfficial = false;
469+
try {
470+
// Get the signature of the key used to sign the app
471+
@SuppressLint("PackageManagerGetSignatures") Signature[] signatures = requireContext().getPackageManager().getPackageInfo(requireContext().getPackageName(), PackageManager.GET_SIGNATURES).signatures;
472+
String officialSignatureHash =
473+
"7bec7c4462f4aac616612d9f56a023ee3046e83afa956463b5fab547fd0a0be6";
474+
String ourSignatureHash = Hashing.sha256().hashBytes(signatures[0].toByteArray()).toString();
475+
isOfficial = ourSignatureHash.equals(officialSignatureHash);
476+
} catch (PackageManager.NameNotFoundException ignored) {
477+
}
478+
String flavor = BuildConfig.FLAVOR;
479+
String type = BuildConfig.BUILD_TYPE;
480+
// Set the summary of pref_pkg_info to something like Github-debug v1.0 (123) (Official)
481+
String pkgInfo = getString(R.string.pref_pkg_info_summary, flavor + "-" + type,
482+
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, isOfficial ?
483+
getString(R.string.official) : getString(R.string.unofficial));
484+
findPreference("pref_pkg_info").setSummary(pkgInfo);
467485
}
468486

469487
@SuppressLint("RestrictedApi")

app/src/main/java/com/fox2code/mmm/utils/Http.java

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import okhttp3.Response;
5555
import okhttp3.ResponseBody;
5656
import okhttp3.dnsoverhttps.DnsOverHttps;
57-
import okhttp3.logging.HttpLoggingInterceptor;
5857
import okio.BufferedSink;
5958

6059
public class Http {
@@ -159,6 +158,12 @@ public class Http {
159158
}
160159
builder.setStoragePath(mainApplication.getCacheDir().getAbsolutePath() + "/cronet");
161160
builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK_NO_HTTP, 10 * 1024 * 1024);
161+
// Add quic hint
162+
builder.addQuicHint("github.com", 443, 443);
163+
builder.addQuicHint("githubusercontent.com", 443, 443);
164+
builder.addQuicHint("jsdelivr.net", 443, 443);
165+
builder.addQuicHint("androidacy.com", 443, 443);
166+
builder.addQuicHint("sentry.io", 443, 443);
162167
CronetEngine engine = builder.build();
163168
httpclientBuilder.addInterceptor(CronetInterceptor.newBuilder(engine).build());
164169
} catch (Exception e) {
@@ -172,13 +177,6 @@ public class Http {
172177
httpClient = followRedirects(httpclientBuilder, true).build();
173178
followRedirects(httpclientBuilder, false).build();
174179
httpclientBuilder.dns(fallbackDNS);
175-
if (BuildConfig.DEBUG) {
176-
// Enable logging
177-
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(s -> Log.d(TAG, s));
178-
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
179-
httpclientBuilder.addInterceptor(logging);
180-
Log.d(TAG, "OkHttp logging enabled");
181-
}
182180
httpClientDoH = followRedirects(httpclientBuilder, true).build();
183181
followRedirects(httpclientBuilder, false).build();
184182
httpclientBuilder.cache(new Cache(new File(mainApplication.getCacheDir(), "http_cache"), 16L * 1024L * 1024L)); // 16Mib of cache
@@ -343,24 +341,49 @@ public static boolean hasWebView() {
343341
}
344342

345343
public static void ensureCacheDirs(MainActivity mainActivity) {
344+
// Recursively ensure cache dirs for webview exist under our cache dir
346345
File cacheDir = mainActivity.getCacheDir();
347-
File cacheDir2 = new File(cacheDir, "HTTP Cache");
348-
if (!cacheDir2.exists()) {
349-
if (!cacheDir2.mkdirs()) {
350-
Log.e(TAG, "Failed to create cache dir");
346+
File webviewCacheDir = new File(cacheDir, "WebView");
347+
if (!webviewCacheDir.exists()) {
348+
if (!webviewCacheDir.mkdirs()) {
349+
Log.e(TAG, "Failed to create webview cache dir");
350+
}
351+
}
352+
File webviewCacheDirCache = new File(webviewCacheDir, "Default");
353+
if (!webviewCacheDirCache.exists()) {
354+
if (!webviewCacheDirCache.mkdirs()) {
355+
Log.e(TAG, "Failed to create webview cache dir");
356+
}
357+
}
358+
File webviewCacheDirCacheCodeCache = new File(webviewCacheDirCache, "HTTP Cache");
359+
if (!webviewCacheDirCacheCodeCache.exists()) {
360+
if (!webviewCacheDirCacheCodeCache.mkdirs()) {
361+
Log.e(TAG, "Failed to create webview cache dir");
362+
}
363+
}
364+
File webviewCacheDirCacheCodeCacheIndex = new File(webviewCacheDirCacheCodeCache, "Code Cache");
365+
if (!webviewCacheDirCacheCodeCacheIndex.exists()) {
366+
if (!webviewCacheDirCacheCodeCacheIndex.mkdirs()) {
367+
Log.e(TAG, "Failed to create webview cache dir");
368+
}
369+
}
370+
File webviewCacheDirCacheCodeCacheIndexIndex = new File(webviewCacheDirCacheCodeCacheIndex, "Index");
371+
if (!webviewCacheDirCacheCodeCacheIndexIndex.exists()) {
372+
if (!webviewCacheDirCacheCodeCacheIndexIndex.mkdirs()) {
373+
Log.e(TAG, "Failed to create webview cache dir");
351374
}
352375
}
353-
// Ensure js and wasm cache dirs
354-
File jsCacheDir = new File(cacheDir2, "js");
355-
if (!jsCacheDir.exists()) {
356-
if (!jsCacheDir.mkdirs()) {
357-
Log.e(TAG, "Failed to create js cache dir");
376+
// Create the js and wasm dirs
377+
File webviewCacheDirCacheCodeCacheIndexIndexJs = new File(webviewCacheDirCacheCodeCache, "js");
378+
if (!webviewCacheDirCacheCodeCacheIndexIndexJs.exists()) {
379+
if (!webviewCacheDirCacheCodeCacheIndexIndexJs.mkdirs()) {
380+
Log.e(TAG, "Failed to create webview cache dir");
358381
}
359382
}
360-
File wasmCacheDir = new File(cacheDir2, "wasm");
361-
if (!wasmCacheDir.exists()) {
362-
if (!wasmCacheDir.mkdirs()) {
363-
Log.e(TAG, "Failed to create wasm cache dir");
383+
File webviewCacheDirCacheCodeCacheIndexIndexWasm = new File(webviewCacheDirCacheCodeCache, "wasm");
384+
if (!webviewCacheDirCacheCodeCacheIndexIndexWasm.exists()) {
385+
if (!webviewCacheDirCacheCodeCacheIndexIndexWasm.mkdirs()) {
386+
Log.e(TAG, "Failed to create webview cache dir");
364387
}
365388
}
366389
}

0 commit comments

Comments
 (0)