diff --git a/android/app/build.gradle b/android/app/build.gradle index 9f8312e7..16c72ee3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -85,7 +85,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // ReVanced - implementation "app.revanced:revanced-patcher:14.2.2" + implementation "app.revanced:revanced-patcher:15.0.2" // Signing & aligning implementation("org.bouncycastle:bcpkix-jdk15on:1.70") diff --git a/android/app/src/main/kotlin/app/revanced/manager/flutter/MainActivity.kt b/android/app/src/main/kotlin/app/revanced/manager/flutter/MainActivity.kt index 22463f8c..3cf0fafb 100644 --- a/android/app/src/main/kotlin/app/revanced/manager/flutter/MainActivity.kt +++ b/android/app/src/main/kotlin/app/revanced/manager/flutter/MainActivity.kt @@ -10,20 +10,18 @@ import app.revanced.manager.flutter.utils.zip.structures.ZipEntry import app.revanced.patcher.PatchBundleLoader import app.revanced.patcher.Patcher import app.revanced.patcher.PatcherOptions -import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages -import app.revanced.patcher.extensions.PatchExtensions.dependencies -import app.revanced.patcher.extensions.PatchExtensions.description -import app.revanced.patcher.extensions.PatchExtensions.include -import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.patch.PatchResult import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import kotlinx.coroutines.cancel import kotlinx.coroutines.runBlocking +import org.json.JSONArray +import org.json.JSONObject import java.io.File import java.io.PrintWriter import java.io.StringWriter +import java.lang.Error import java.util.logging.LogRecord import java.util.logging.Logger @@ -93,29 +91,43 @@ class MainActivity : FlutterActivity() { } "getPatches" -> { - val patchBundleFilePath = call.argument("patchBundleFilePath") - val cacheDirPath = call.argument("cacheDirPath") + val patchBundleFilePath = call.argument("patchBundleFilePath")!! + val cacheDirPath = call.argument("cacheDirPath")!! - if (patchBundleFilePath != null) { - val patches = PatchBundleLoader.Dex( - File(patchBundleFilePath), - optimizedDexDirectory = File(cacheDirPath) - ).map { patch -> - val map = HashMap() - map["\"name\""] = "\"${patch.patchName.replace("\"","\\\"")}\"" - map["\"description\""] = "\"${patch.description?.replace("\"","\\\"")}\"" - map["\"excluded\""] = !patch.include - map["\"dependencies\""] = patch.dependencies?.map { "\"${it.java.patchName}\"" } ?: emptyList() - map["\"compatiblePackages\""] = patch.compatiblePackages?.map { - val map2 = HashMap() - map2["\"name\""] = "\"${it.name}\"" - map2["\"versions\""] = it.versions.map { version -> "\"${version}\"" } - map2 - } ?: emptyList() - map + + JSONArray().apply { + try { + PatchBundleLoader.Dex( + File(patchBundleFilePath), + optimizedDexDirectory = File(cacheDirPath) + ) + } catch (ex: Exception) { + return@setMethodCallHandler result.notImplemented() + } catch (err: Error) { + return@setMethodCallHandler result.notImplemented() + }.forEach { + JSONObject().apply { + put("name", it.name) + put("description", it.description) + put("excluded", !it.use) + put("compatiblePackages", JSONArray().apply { + it.compatiblePackages?.forEach { compatiblePackage -> + val compatiblePackageJson = JSONObject().apply { + put("name", compatiblePackage.name) + put( + "versions", + JSONArray().apply { + compatiblePackage.versions?.forEach { version -> + put(version) + } + }) + } + put(compatiblePackageJson) + } + }) + }.let(::put) } - result.success(patches) - } else result.notImplemented() + }.toString().let(result::success) } else -> result.notImplemented() @@ -220,7 +232,7 @@ class MainActivity : FlutterActivity() { val compatibleOrUniversal = isCompatible || patch.compatiblePackages.isNullOrEmpty() - compatibleOrUniversal && selectedPatches.any { it == patch.patchName } + compatibleOrUniversal && selectedPatches.any { it == patch.name } } if (cancel) { @@ -251,9 +263,9 @@ class MainActivity : FlutterActivity() { val msg = patchResult.exception?.let { val writer = StringWriter() it.printStackTrace(PrintWriter(writer)) - "${patchResult.patchName} failed: $writer" + "${patchResult.patch.name} failed: $writer" } ?: run { - "${patchResult.patchName} succeeded" + "${patchResult.patch.name} succeeded" } updateProgress(progress, "", msg) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 05694ced..9092bbdc 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -73,7 +73,6 @@ "patchDialogText": "You have selected a resource patch and a split APK installation has been detected, so patching errors may occur.\nAre you sure you want to proceed?", "armv7WarningDialogText": "Patching on ARMv7 devices is not yet supported and might fail. Proceed anyways?", - "splitApkWarningDialogText": "Patching a split APK is not yet supported and might fail. Proceed anyways?", "removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n{patches}\n\nProceed anyways?" }, "appSelectorCard": { diff --git a/lib/models/patch.dart b/lib/models/patch.dart index 7acf05ba..b3d99e2a 100644 --- a/lib/models/patch.dart +++ b/lib/models/patch.dart @@ -9,26 +9,19 @@ class Patch { required this.name, required this.description, required this.excluded, - required this.dependencies, required this.compatiblePackages, }); factory Patch.fromJson(Map json) => _$PatchFromJson(json); final String name; - final String description; + final String? description; final bool excluded; - final List dependencies; final List compatiblePackages; Map toJson() => _$PatchToJson(this); String getSimpleName() { - return name - .replaceAll('-', ' ') - .split('-') - .join(' ') - .toTitleCase() - .replaceFirst('Microg', 'MicroG'); + return name; } } diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 3401432b..7d42f6d7 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -315,18 +315,16 @@ class ManagerAPI { if (patchBundleFile != null) { try { - final patchesObject = await PatcherAPI.patcherChannel.invokeMethod( + final String patchesJson = await PatcherAPI.patcherChannel.invokeMethod( 'getPatches', { 'patchBundleFilePath': patchBundleFile.path, 'cacheDirPath': cacheDir.path, }, ); - final List> patchesMap = []; - patchesObject.forEach((patch) { - patchesMap.add(jsonDecode('$patch')); - }); - patches = patchesMap.map((patch) => Patch.fromJson(patch)).toList(); + + final List patchesJsonList = jsonDecode(patchesJson); + patches = patchesJsonList.map((patchJson) => Patch.fromJson(patchJson)).toList(); return patches; } on Exception catch (e) { if (kDebugMode) { diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index 5838ab3b..ecc3b218 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -149,46 +149,11 @@ class PatcherAPI { .toList(); } - Future needsResourcePatching( - List selectedPatches, - ) async { - return selectedPatches.any( - (patch) => patch.dependencies.any( - (dep) => dep.contains('resource-'), - ), - ); - } - - Future needsSettingsPatch(List selectedPatches) async { - return selectedPatches.any( - (patch) => patch.dependencies.any( - (dep) => dep.contains('settings'), - ), - ); - } - Future runPatcher( String packageName, String apkFilePath, List selectedPatches, ) async { - final bool includeSettings = await needsSettingsPatch(selectedPatches); - if (includeSettings) { - try { - final Patch? settingsPatch = _patches.firstWhereOrNull( - (patch) => - patch.name.contains('settings') && - patch.compatiblePackages.any((pack) => pack.name == packageName), - ); - if (settingsPatch != null) { - selectedPatches.add(settingsPatch); - } - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } - } final File? patchBundleFile = await _managerAPI.downloadPatches(); final File? integrationsFile = await _managerAPI.downloadIntegrations(); if (patchBundleFile != null) { diff --git a/lib/ui/views/patcher/patcher_viewmodel.dart b/lib/ui/views/patcher/patcher_viewmodel.dart index 33ceb719..bd0bc41b 100644 --- a/lib/ui/views/patcher/patcher_viewmodel.dart +++ b/lib/ui/views/patcher/patcher_viewmodel.dart @@ -44,49 +44,6 @@ class PatcherViewModel extends BaseViewModel { return selectedApp == null; } - Future isValidPatchConfig() async { - final bool needsResourcePatching = await _patcherAPI.needsResourcePatching( - selectedPatches, - ); - if (needsResourcePatching && selectedApp != null) { - final bool isSplit = await _managerAPI.isSplitApk(selectedApp!); - return !isSplit; - } - return true; - } - - Future showPatchConfirmationDialog(BuildContext context) async { - final bool isValid = await isValidPatchConfig(); - if (context.mounted) { - if (isValid) { - showArmv7WarningDialog(context); - } else { - return showDialog( - context: context, - builder: (context) => AlertDialog( - title: I18nText('warning'), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText('patcherView.splitApkWarningDialogText'), - actions: [ - CustomMaterialButton( - label: I18nText('noButton'), - onPressed: () => Navigator.of(context).pop(), - ), - CustomMaterialButton( - label: I18nText('yesButton'), - isFilled: false, - onPressed: () { - Navigator.of(context).pop(); - showArmv7WarningDialog(context); - }, - ), - ], - ), - ); - } - } - } - Future showRemovedPatchesDialog(BuildContext context) async { if (removedPatches.isNotEmpty) { return showDialog( @@ -115,7 +72,7 @@ class PatcherViewModel extends BaseViewModel { ), ); } else { - showArmv7WarningDialog(context); + showArmv7WarningDialog(context); // TODO(aabed): Find out why this is here } } diff --git a/lib/ui/views/patches_selector/patches_selector_view.dart b/lib/ui/views/patches_selector/patches_selector_view.dart index 26766f4e..b0494b52 100644 --- a/lib/ui/views/patches_selector/patches_selector_view.dart +++ b/lib/ui/views/patches_selector/patches_selector_view.dart @@ -194,7 +194,7 @@ class _PatchesSelectorViewState extends State { return PatchItem( name: patch.name, simpleName: patch.getSimpleName(), - description: patch.description, + description: patch.description ?? '', packageVersion: model.getAppInfo().version, supportedPackageVersions: model.getSupportedVersions(patch), @@ -246,7 +246,7 @@ class _PatchesSelectorViewState extends State { return PatchItem( name: patch.name, simpleName: patch.getSimpleName(), - description: patch.description, + description: patch.description ?? '', packageVersion: model.getAppInfo().version, supportedPackageVersions: