Fix empty androidacy client id and bundle cronet

Fdroid apparently won't let us attempt to use cronet from gms because something something proprietary AAAAAAAAAAAAAAAAAAAAAAAAAAA

The scream is the two hours I spent resolving the 15189759875195791 conflicts that resulted from the change.

Also, when ANDROIDACY_CLIENT_ID is empty, do not allow the user to enable Androidacy repo and instead show a message suggesting to download official builds. May have to reword for fdroid

Oh, and now no internet actually means no internet and it'll properly notify when repos fail to update.

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/230/head
androidacy-user 1 year ago
parent dfe53576bd
commit f3d31ed380

@ -158,6 +158,13 @@ If your language is right to left don't forget to set `lang_support_rtl` to `tru
Translators are not expected to have any previous coding experience.
## License
See [LICENSE](LICENCE). Library licenses can be found in the licenses section of the app.
Cronet is licensed under the Apache License, Version 2.0. Static libraries are licensed under
the BSD license. See [LICENSE](https://chromium.googlesource.com/chromium/src/+/master/LICENSE)
for more information. Libraries were built using the microg build script which can be found [here](https://github.com/microg/cronet-build).
## I want to add my own repo
To add you own repo to Fox's mmm it need to follow theses conditions:

@ -9,6 +9,17 @@ android {
namespace "com.fox2code.mmm"
compileSdk 33
buildToolsVersion '30.0.3'
signingConfigs {
release {
// Everything comes from local.properties
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
storeFile file(properties.getProperty('keystore.file'))
storePassword properties.getProperty('keystore.password')
keyAlias 'key0'
keyPassword properties.getProperty('keystore.password')
}
}
defaultConfig {
applicationId "com.fox2code.mmm"
@ -17,13 +28,15 @@ android {
versionCode 60
versionName "0.6.8"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
signingConfig signingConfigs.release
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
debug {
applicationIdSuffix '.debug'
@ -42,9 +55,6 @@ android {
dimension "type"
buildConfigField "boolean", "ENABLE_AUTO_UPDATER", "true"
buildConfigField "boolean", "DEFAULT_ENABLE_CRASH_REPORTING", "true"
buildConfigField("java.util.List<String>",
"ENABLED_REPOS",
"java.util.Arrays.asList(\"magisk_alt_repo\", \"androidacy_repo\")",)
// Get the androidacy client ID from the androidacy.properties
Properties properties = new Properties()
// If androidacy.properties doesn't exist, use the default client ID (an empty string
@ -52,9 +62,19 @@ android {
if (project.rootProject.file('androidacy.properties').exists()) {
properties.load(project.rootProject.file('androidacy.properties').newDataInputStream())
} else {
properties.setProperty('client_id', '""')
properties.setProperty('client_id', '')
}
buildConfigField("String", "ANDROIDACY_CLIENT_ID", properties.getProperty('client_id'))
// If client ID is empty, disable androidacy
if (properties.getProperty('client_id').isEmpty()) {
buildConfigField("java.util.List<String>",
"ENABLED_REPOS", "java.util.Arrays.asList(\"magisk_alt_repo\")")
} else {
buildConfigField("java.util.List<String>",
"ENABLED_REPOS",
"java.util.Arrays.asList(\"magisk_alt_repo\", \"androidacy_repo\")",)
}
}
fdroid {
@ -82,7 +102,7 @@ android {
if (project.rootProject.file('androidacy.properties').exists()) {
properties.load(project.rootProject.file('androidacy.properties').newDataInputStream())
} else {
properties.setProperty('client_id', '""')
properties.setProperty('client_id', '')
}
buildConfigField("String", "ANDROIDACY_CLIENT_ID", properties.getProperty('client_id'))
}
@ -160,7 +180,7 @@ sentry {
// as Gradle will resolve it to the latest version.
//
// Defaults to the latest published sentry version.
sentryVersion = '6.8.0'
sentryVersion = '6.9.2'
}
}
@ -198,18 +218,20 @@ dependencies {
implementation 'androidx.work:work-runtime:2.7.1'
implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:5.0.0-alpha.10'
implementation 'com.squareup.okhttp3:okhttp-brotli:5.0.0-alpha.10'
implementation 'com.google.net.cronet:cronet-okhttp:0.1.0'
// Chromium cronet from microG
implementation fileTree(dir: 'libs', include: '*.jar')
// Force prefer our own version of Cronet
implementation 'com.github.topjohnwu.libsu:io:5.0.1'
implementation 'com.github.Fox2Code:RosettaX:1.0.9'
implementation 'com.github.Fox2Code:AndroidANSI:1.0.1'
if (hasSentryConfig) {
// Error reporting
defaultImplementation 'io.sentry:sentry-android:6.8.0'
defaultImplementation 'io.sentry:sentry-android-fragment:6.8.0'
defaultImplementation 'io.sentry:sentry-android-okhttp:6.8.0'
defaultImplementation 'io.sentry:sentry-android-core:6.8.0'
defaultImplementation 'io.sentry:sentry-android-ndk:6.8.0'
defaultImplementation 'io.sentry:sentry-android:6.9.2'
defaultImplementation 'io.sentry:sentry-android-fragment:6.9.2'
defaultImplementation 'io.sentry:sentry-android-okhttp:6.9.2'
defaultImplementation 'io.sentry:sentry-android-core:6.9.2'
defaultImplementation 'io.sentry:sentry-android-ndk:6.9.2'
}
// Markdown
@ -217,7 +239,8 @@ dependencies {
implementation "io.noties.markwon:html:4.6.2"
implementation "io.noties.markwon:image:4.6.2"
implementation "io.noties.markwon:syntax-highlight:4.6.2"
implementation 'com.google.android.gms:play-services-cronet:18.0.1'
implementation 'com.google.net.cronet:cronet-okhttp:0.1.0'
// Ignore all org.chromium.net dependencies
annotationProcessor "io.noties:prism4j-bundler:2.0.0"
implementation "com.caverock:androidsvg:1.4"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -187,6 +187,11 @@
android.graphics.Insets getWaterfallInsets();
}
# Keep all of Cronet API and google's internal classes
-keep class org.chromium.net.** { *; }
-keep class org.chromium.** { *; }
-keep class com.google.** { *; }
# Silence some warnings
-dontwarn android.os.SystemProperties
-dontwarn android.view.ThreadedRenderer
@ -196,4 +201,22 @@
-dontwarn me.weishu.reflection.Reflection
-dontwarn org.lsposed.hiddenapibypass.HiddenApiBypass
-dontwarn rikka.core.res.ResourcesCompatLayoutInflaterListener
-dontwarn rikka.core.util.ResourceUtils
-dontwarn rikka.core.util.ResourceUtils
-dontwarn com.afollestad.materialdialogs.MaterialDialog
-dontwarn com.afollestad.materialdialogs.WhichButton
-dontwarn com.afollestad.materialdialogs.actions.DialogActionExtKt
-dontwarn com.afollestad.materialdialogs.callbacks.DialogCallbackExtKt
-dontwarn com.afollestad.materialdialogs.internal.button.DialogActionButton
-dontwarn com.afollestad.materialdialogs.internal.button.DialogActionButtonLayout
-dontwarn com.afollestad.materialdialogs.internal.main.DialogLayout
-dontwarn com.afollestad.materialdialogs.internal.main.DialogTitleLayout
-dontwarn com.afollestad.materialdialogs.internal.message.DialogContentLayout
-dontwarn com.oracle.svm.core.annotate.AutomaticFeature
-dontwarn com.oracle.svm.core.annotate.Delete
-dontwarn com.oracle.svm.core.annotate.Substitute
-dontwarn com.oracle.svm.core.annotate.TargetClass
-dontwarn com.oracle.svm.core.configure.ResourcesRegistry
-dontwarn javax.lang.model.element.Modifier
-dontwarn org.graalvm.nativeimage.ImageSingletons
-dontwarn org.graalvm.nativeimage.hosted.Feature$BeforeAnalysisAccess
-dontwarn org.graalvm.nativeimage.hosted.Feature

@ -22,7 +22,6 @@ import android.widget.CheckBox;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SearchView;
import androidx.cardview.widget.CardView;
import androidx.core.app.NotificationManagerCompat;
@ -207,6 +206,8 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
NotificationType.NEED_CAPTCHA_ANDROIDACY.autoAdd(moduleViewListBuilder);
if (!NotificationType.NO_INTERNET.shouldRemove()) {
moduleViewListBuilder.addNotification(NotificationType.NO_INTERNET);
} else if (!NotificationType.REPO_UPDATE_FAILED.shouldRemove()) {
moduleViewListBuilder.addNotification(NotificationType.REPO_UPDATE_FAILED);
} else {
// Compatibility data still needs to be updated
AppUpdateManager appUpdateManager = AppUpdateManager.getAppUpdateManager();
@ -406,10 +407,10 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
} else {
// Compatibility data still needs to be updated
AppUpdateManager appUpdateManager = AppUpdateManager.getAppUpdateManager();
noodleDebug.replace("Check App Update");
// noodleDebug.replace("Check App Update");
if (BuildConfig.ENABLE_AUTO_UPDATER && appUpdateManager.checkUpdate(true))
moduleViewListBuilder.addNotification(NotificationType.UPDATE_AVAILABLE);
noodleDebug.replace("Check Json Update");
// noodleDebug.replace("Check Json Update");
if (max != 0) {
int current = 0;
noodleDebug.push("");
@ -429,7 +430,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
noodleDebug.pop();
}
}
noodleDebug.replace("Apply");
// noodleDebug.replace("Apply");
runOnUiThread(() -> {
this.progressIndicator.setVisibility(View.GONE);
this.swipeRefreshLayout.setRefreshing(false);
@ -441,8 +442,8 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
RepoManager.getINSTANCE().updateEnabledStates();
RepoManager.getINSTANCE().runAfterUpdate(moduleViewListBuilder::appendRemoteModules);
this.moduleViewListBuilder.applyTo(moduleList, moduleViewAdapter);
noodleDebug.pop();
noodleDebug.unbind();
// noodleDebug.pop();
// noodleDebug.unbind();
}, "Repo update thread").start();
}

@ -34,6 +34,7 @@ import com.topjohnwu.superuser.Shell;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;
import io.noties.markwon.Markwon;
@ -173,7 +174,7 @@ public class MainApplication extends FoxApplication implements androidx.work.Con
}
public static boolean isCrashReportingEnabled() {
return getSharedPreferences().getBoolean("pref_crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING && !BuildConfig.DEBUG);
return getSharedPreferences().getBoolean("pref_crash_reporting", BuildConfig.DEFAULT_ENABLE_CRASH_REPORTING);
}
public static SharedPreferences getBootSharedPreferences() {
@ -316,6 +317,13 @@ public class MainApplication extends FoxApplication implements androidx.work.Con
}
SentryMain.initialize(this);
if (Objects.equals(BuildConfig.ANDROIDACY_CLIENT_ID, "")) {
Log.w("MainApplication", "Androidacy client id is empty! Please set it in androidacy" +
".properties. Will not enable Androidacy.");
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("pref_androidacy_repo_enabled", false);
editor.apply();
}
}
@Override

@ -68,6 +68,12 @@ public enum NotificationType implements NotificationTypeCst {
RepoManager.getINSTANCE().hasConnectivity();
}
},
REPO_UPDATE_FAILED(R.string.repo_update_failed, R.drawable.ic_baseline_cloud_off_24) {
@Override
public boolean shouldRemove() {
return RepoManager.getINSTANCE().isLastUpdateSuccess();
}
},
NEED_CAPTCHA_ANDROIDACY(R.string.androidacy_need_captcha, R.drawable.ic_baseline_refresh_24, v ->
IntentHelper.openUrlAndroidacy(v.getContext(),
"https://" + Http.needCaptchaAndroidacyHost() + "/", false)) {

@ -31,6 +31,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import okhttp3.HttpUrl;
@ -155,6 +156,13 @@ public final class AndroidacyRepoData extends RepoData {
@Override
protected boolean prepare() throws NoSuchAlgorithmException {
// If ANDROIDACY_CLIENT_ID is not set or is empty, disable this repo and return
if (Objects.equals(BuildConfig.ANDROIDACY_CLIENT_ID, "")) {
SharedPreferences.Editor editor = this.cachedPreferences.edit();
editor.putBoolean("pref_androidacy_repo_enabled", false);
editor.apply();
return false;
}
if (Http.needCaptchaAndroidacy()) return false;
// Implementation details discussed on telegram
// First, ping the server to check if it's alive

@ -19,6 +19,9 @@ import com.fox2code.mmm.utils.PropUtils;
import com.fox2code.mmm.utils.SyncManager;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
@ -27,37 +30,74 @@ import java.util.LinkedHashSet;
import java.util.List;
public final class RepoManager extends SyncManager {
private static final String TAG = "RepoManager";
private static final String MAGISK_REPO_MANAGER =
"https://magisk-modules-repo.github.io/submission/modules.json";
public static final String MAGISK_REPO =
"https://raw.githubusercontent.com/Magisk-Modules-Repo/submission/modules/modules.json";
public static final String MAGISK_REPO_HOMEPAGE = "https://github.com/Magisk-Modules-Repo";
public static final String MAGISK_ALT_REPO =
"https://raw.githubusercontent.com/Magisk-Modules-Alt-Repo/json/main/modules.json";
public static final String MAGISK_ALT_REPO_HOMEPAGE =
"https://github.com/Magisk-Modules-Alt-Repo";
public static final String MAGISK_ALT_REPO_JSDELIVR =
"https://cdn.jsdelivr.net/gh/Magisk-Modules-Alt-Repo/json@main/modules.json";
public static final String ANDROIDACY_MAGISK_REPO_ENDPOINT =
"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 =
"https://www.androidacy.com/modules-repo";
public static final String DG_MAGISK_REPO =
"https://repo.dergoogler.com/modules.json";
public static final String DG_MAGISK_REPO_GITHUB =
"https://googlers-magisk-repo.github.io/modules.json";
public static final String DG_MAGISK_REPO_GITHUB_RAW =
"https://raw.githubusercontent.com/Googlers-Repo/googlers-repo.github.io/master/modules.json";
private static final String TAG = "RepoManager";
private static final String MAGISK_REPO_MANAGER =
"https://magisk-modules-repo.github.io/submission/modules.json";
private static final Object lock = new Object();
private static final double STEP1 = 0.1D;
private static final double STEP2 = 0.8D;
private static final double STEP3 = 0.1D;
private static volatile RepoManager INSTANCE;
private final MainApplication mainApplication;
private final LinkedHashMap<String, RepoData> repoData;
private final HashMap<String, RepoModule> modules;
private final AndroidacyRepoData androidacyRepoData;
private final CustomRepoManager customRepoManager;
private boolean hasInternet;
private boolean repoLastError = false;
private boolean initialized;
public String repoLastErrorName = null;
private RepoManager(MainApplication mainApplication) {
INSTANCE = this; // Set early fox XHooks
this.initialized = false;
this.mainApplication = mainApplication;
this.repoData = new LinkedHashMap<>();
this.modules = new HashMap<>();
// We do not have repo list config yet.
RepoData altRepo = this.addRepoData(
MAGISK_ALT_REPO, "Magisk Modules Alt Repo");
altRepo.defaultWebsite = RepoManager.MAGISK_ALT_REPO_HOMEPAGE;
altRepo.defaultSubmitModule =
"https://github.com/Magisk-Modules-Alt-Repo/submission/issues";
RepoData dgRepo = this.addRepoData(
DG_MAGISK_REPO_GITHUB_RAW, "Googlers Magisk Repo");
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()) {
if (repoData == this.androidacyRepoData) {
if (x) return;
x = true;
}
this.populateDefaultCache(repoData);
}
this.initialized = true;
}
public static RepoManager getINSTANCE() {
if (INSTANCE == null || !INSTANCE.initialized) {
@ -93,44 +133,50 @@ public final class RepoManager extends SyncManager {
return INSTANCE;
}
private final MainApplication mainApplication;
private final LinkedHashMap<String, RepoData> repoData;
private final HashMap<String, RepoModule> modules;
private final AndroidacyRepoData androidacyRepoData;
private final CustomRepoManager customRepoManager;
private boolean initialized;
public static String internalIdOfUrl(String url) {
switch (url) {
case MAGISK_ALT_REPO:
case MAGISK_ALT_REPO_JSDELIVR:
return "magisk_alt_repo";
case ANDROIDACY_MAGISK_REPO_ENDPOINT:
case ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT:
return "androidacy_repo";
case DG_MAGISK_REPO:
case DG_MAGISK_REPO_GITHUB:
case DG_MAGISK_REPO_GITHUB_RAW:
return "dg_magisk_repo";
default:
return "repo_" + Hashes.hashSha1(
url.getBytes(StandardCharsets.UTF_8));
}
}
private RepoManager(MainApplication mainApplication) {
INSTANCE = this; // Set early fox XHooks
this.initialized = false;
this.mainApplication = mainApplication;
this.repoData = new LinkedHashMap<>();
this.modules = new HashMap<>();
// We do not have repo list config yet.
RepoData altRepo = this.addRepoData(
MAGISK_ALT_REPO, "Magisk Modules Alt Repo");
altRepo.defaultWebsite = RepoManager.MAGISK_ALT_REPO_HOMEPAGE;
altRepo.defaultSubmitModule =
"https://github.com/Magisk-Modules-Alt-Repo/submission/issues";
RepoData dgRepo = this.addRepoData(
DG_MAGISK_REPO_GITHUB_RAW, "Googlers Magisk Repo");
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()) {
if (repoData == this.androidacyRepoData) {
if (x) return; x = true;
}
this.populateDefaultCache(repoData);
static boolean isBuiltInRepo(String repo) {
switch (repo) {
case RepoManager.MAGISK_ALT_REPO:
case RepoManager.MAGISK_ALT_REPO_JSDELIVR:
case RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT:
case RepoManager.ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT:
case RepoManager.DG_MAGISK_REPO:
case RepoManager.DG_MAGISK_REPO_GITHUB:
case RepoManager.DG_MAGISK_REPO_GITHUB_RAW:
return true;
}
this.initialized = true;
return false;
}
/**
* Safe way to do {@code RepoManager.getInstance().androidacyRepoData.isEnabled()}
* without initializing RepoManager
*/
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isAndroidacyRepoEnabled() {
return INSTANCE != null && INSTANCE.androidacyRepoData != null &&
INSTANCE.androidacyRepoData.isEnabled();
}
private void populateDefaultCache(RepoData repoData) {
for (RepoModule repoModule:repoData.moduleHashMap.values()) {
for (RepoModule repoModule : repoData.moduleHashMap.values()) {
if (!repoModule.moduleInfo.hasFlag(ModuleInfo.FLAG_METADATA_INVALID)) {
RepoModule registeredRepoModule = this.modules.get(repoModule.id);
if (registeredRepoModule == null) {
@ -181,12 +227,6 @@ public final class RepoManager extends SyncManager {
return repoData;
}
private boolean repoLastResult = true;
private static final double STEP1 = 0.1D;
private static final double STEP2 = 0.8D;
private static final double STEP3 = 0.1D;
protected void scanInternal(@NonNull UpdateListener updateListener) {
NoodleDebug noodleDebug = NoodleDebug.getNoodleDebug();
// First, check if we have internet connection
@ -216,7 +256,7 @@ public final class RepoManager extends SyncManager {
noodleDebug.replace(repoData.getName());
Log.d(TAG, "Registering " + repoData.getName());
noodleDebug.push("");
for (RepoModule repoModule:repoModules) {
for (RepoModule repoModule : repoModules) {
noodleDebug.replace(repoModule.id);
try {
if (repoModule.propUrl != null &&
@ -244,7 +284,7 @@ public final class RepoManager extends SyncManager {
updateListener.update(STEP1 + (STEP2 / moduleToUpdate * updatedModules));
}
noodleDebug.pop();
for (RepoModule repoModule:repoUpdaters[i].toApply()) {
for (RepoModule repoModule : repoUpdaters[i].toApply()) {
if ((repoModule.moduleInfo.flags & ModuleInfo.FLAG_METADATA_INVALID) == 0) {
RepoModule registeredRepoModule = this.modules.get(repoModule.id);
if (registeredRepoModule == null) {
@ -259,21 +299,45 @@ public final class RepoManager extends SyncManager {
noodleDebug.pop();
noodleDebug.replace("Finishing update");
noodleDebug.push("");
boolean hasInternet = false;
for (int i = 0; i < repoDatas.length; i++) {
noodleDebug.replace(repoUpdaters[i].repoData.getName());
hasInternet |= repoUpdaters[i].finish();
updateListener.update(STEP1 + STEP2 + (STEP3 / repoDatas.length * (i + 1)));
this.hasInternet = false;
// Check if we have internet connection
// Attempt to contact connectivitycheck.gstatic.com/generate_204
// If we can't, we don't have internet connection
try {
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();
if (urlConnection.getResponseCode() == 204 &&
urlConnection.getContentLength() == 0) {
this.hasInternet = true;
}
} catch (IOException e) {
Log.e(TAG, "Failed to check internet connection", e);
}
noodleDebug.pop();
if (hasInternet) {
for (int i = 0; i < repoDatas.length; i++) {
noodleDebug.replace(repoUpdaters[i].repoData.getName());
this.repoLastError = !repoUpdaters[i].finish();
if (this.repoLastError) {
Log.e(TAG, "Failed to update " + repoUpdaters[i].repoData.getName());
this.repoLastErrorName = repoUpdaters[i].repoData.getName();
}
updateListener.update(STEP1 + STEP2 + (STEP3 / repoDatas.length * (i + 1)));
}
}
noodleDebug.pop();
Log.i(TAG, "Got " + this.modules.size() + " modules!");
updateListener.update(1D);
this.repoLastResult = hasInternet;
noodleDebug.pop(); // pop "Finishing update"
}
public void updateEnabledStates() {
for (RepoData repoData:this.repoData.values()) {
for (RepoData repoData : this.repoData.values()) {
boolean wasEnabled = repoData.isEnabled();
repoData.updateEnabledState();
if (!wasEnabled && repoData.isEnabled()) {
@ -288,39 +352,7 @@ public final class RepoManager extends SyncManager {
}
public boolean hasConnectivity() {
return this.repoLastResult;
}
public static String internalIdOfUrl(String url) {
switch (url) {
case MAGISK_ALT_REPO:
case MAGISK_ALT_REPO_JSDELIVR:
return "magisk_alt_repo";
case ANDROIDACY_MAGISK_REPO_ENDPOINT:
case ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT:
return "androidacy_repo";
case DG_MAGISK_REPO:
case DG_MAGISK_REPO_GITHUB:
case DG_MAGISK_REPO_GITHUB_RAW:
return "dg_magisk_repo";
default:
return "repo_" + Hashes.hashSha1(
url.getBytes(StandardCharsets.UTF_8));
}
}
static boolean isBuiltInRepo(String repo) {
switch (repo) {
case RepoManager.MAGISK_ALT_REPO:
case RepoManager.MAGISK_ALT_REPO_JSDELIVR:
case RepoManager.ANDROIDACY_MAGISK_REPO_ENDPOINT:
case RepoManager.ANDROIDACY_TEST_MAGISK_REPO_ENDPOINT:
case RepoManager.DG_MAGISK_REPO:
case RepoManager.DG_MAGISK_REPO_GITHUB:
case RepoManager.DG_MAGISK_REPO_GITHUB_RAW:
return true;
}
return false;
return this.hasInternet;
}
private RepoData addRepoData(String url, String fallBackName) {
@ -375,12 +407,7 @@ public final class RepoManager extends SyncManager {
return new LinkedHashSet<>(this.repoData.values());
}
/**
* Safe way to do {@code RepoManager.getInstance().androidacyRepoData.isEnabled()}
* without initializing RepoManager
*/
public static boolean isAndroidacyRepoEnabled() {
return INSTANCE != null && INSTANCE.androidacyRepoData != null &&
INSTANCE.androidacyRepoData.isEnabled();
public boolean isLastUpdateSuccess() {
return this.repoLastError;
}
}

@ -19,6 +19,7 @@ import org.json.JSONObject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@ -51,7 +52,7 @@ public class RepoUpdater {
}
this.indexRaw = Http.doHttpGet(this.repoData.getUrl(), false);
// Ensure it's a valid json and response code is 200
if (this.indexRaw.hashCode() == 0) {
if (Arrays.hashCode(this.indexRaw) == 0) {
this.indexRaw = null;
this.toUpdate = Collections.emptyList();
this.toApply = this.repoData.moduleHashMap.values();
@ -83,6 +84,10 @@ public class RepoUpdater {
public boolean finish() {
final boolean success = this.indexRaw != null;
// If repo is not enabled we don't need to do anything, just return true
if (!this.repoData.isEnabled()) {
return true;
}
if (this.indexRaw != null) {
try {
Files.write(this.repoData.metaDataCache, this.indexRaw);

@ -529,10 +529,32 @@ public class SettingsActivity extends FoxActivity implements LanguageActivity {
return true;
});
}
// Disable toggling the pref_androidacy_repo_enabled on builds without an
// ANDROIDACY_CLIENT_ID or where the ANDROIDACY_CLIENT_ID is empty
Preference androidacyRepoEnabled = Objects.requireNonNull(findPreference("pref_androidacy_repo_enabled"));
if (Objects.equals(BuildConfig.ANDROIDACY_CLIENT_ID, "")) {
androidacyRepoEnabled.setOnPreferenceClickListener(preference -> {
new MaterialAlertDialogBuilder(this.requireContext())
.setTitle(R.string.androidacy_repo_disabled)
.setMessage(R.string.androidacy_repo_disabled_message)
.setPositiveButton(R.string.download_full_app, (dialog, which) -> {
// User clicked OK button. Open GitHub releases page
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
"https://github.com/Fox2Code/FoxMagiskModuleManager/releases"));
startActivity(browserIntent);
})
.show();
// Revert the switch to off
SwitchPreferenceCompat switchPreferenceCompat = (SwitchPreferenceCompat) androidacyRepoEnabled;
switchPreferenceCompat.setChecked(false);
// Save the preference
MainApplication.getSharedPreferences().edit().putBoolean("pref_androidacy_repo_enabled", false).apply();
return false;
});
}
String[] originalApiKeyRef = new String[]{MainApplication.getINSTANCE().getSharedPreferences("androidacy", 0).getString("pref_androidacy_api_token", null)};
// Get the dummy pref_androidacy_repo_api_token EditTextPreference
EditTextPreference prefAndroidacyRepoApiKey = Objects.requireNonNull(findPreference("pref_androidacy_api_token"));
prefAndroidacyRepoApiKey.setDependency("pref_androidacy_repo_enabled");
prefAndroidacyRepoApiKey.setTitle(R.string.api_key);
prefAndroidacyRepoApiKey.setSummary(R.string.api_key_summary);
prefAndroidacyRepoApiKey.setDialogTitle(R.string.api_key);

@ -19,7 +19,7 @@ import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.androidacy.AndroidacyUtil;
import com.fox2code.mmm.installer.InstallerInitializer;
import com.fox2code.mmm.repo.RepoManager;
import com.google.android.gms.net.CronetProviderInstaller;
import com.google.net.cronet.okhttptransport.CronetCallFactory;
import com.google.net.cronet.okhttptransport.CronetInterceptor;
import org.chromium.net.CronetEngine;
@ -141,14 +141,16 @@ public class Http {
});
// Add cronet interceptor
// install cronet
try {
/*try {
// Detect if cronet is installed
CronetProviderInstaller.installProvider(mainApplication);
} catch (Exception e) {
Log.e(TAG, "Failed to install cronet", e);
}
}*/
// init cronet
try {
// Load the cronet library
System.loadLibrary("cronet.108.0.5359.95");
CronetEngine.Builder builder = new CronetEngine.Builder(mainApplication);
builder.enableBrotli(true);
builder.enableHttp2(true);

@ -191,4 +191,11 @@
<string name="force_black_theme_desc">Forces AMOLED black backgrounds when using dark theme.
Please be aware this may have contrast problems with some color themes.</string>
<string name="force_black_theme_pref">Force black theme</string>
<string name="androidacy_repo_disabled">This repo is currently disabled</string>
<string name="androidacy_repo_disabled_message">This build is missing client keys for the
Androidacy Repo.
Please
download the GitHub release if you\'d like to benefit from features like module reviews, automatic security checks, and more.</string>
<string name="download_full_app">Download full version</string>
<string name="repo_update_failed">Some repos have failed to update</string>
</resources>

@ -44,6 +44,7 @@
app:icon="@drawable/ic_baseline_vpn_key_24"
app:key="pref_androidacy_api_token"
app:singleLineTitle="false"
app:dependency="pref_androidacy_repo_enabled"
app:isPreferenceVisible="false"
app:title="@string/api_key" />
<SwitchPreferenceCompat

@ -3,7 +3,9 @@
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="QueryAllPackagesPermission">
<application android:icon="@mipmap/ic_launcher">
<application android:icon="@mipmap/ic_launcher" android:enableOnBackInvokedCallback="true"
tools:targetApi="tiramisu">
<meta-data
android:name="io.sentry.auto-init"
android:value="false" />

@ -9,4 +9,4 @@ dependencyResolutionManagement {
}
}
rootProject.name = "MagiskModuleManager"
include ':app'
include ':app'
Loading…
Cancel
Save