From 62505f2543632f74ce7496e9e0862adc8b5c9d7f Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 26 Sep 2023 05:14:27 +0200 Subject: [PATCH 01/17] build: Bump dependencies --- android/app/build.gradle | 2 +- .../revanced/manager/flutter/MainActivity.kt | 70 +++++++++++-------- assets/i18n/en_US.json | 1 - lib/models/patch.dart | 11 +-- lib/services/manager_api.dart | 10 ++- lib/services/patcher_api.dart | 35 ---------- lib/ui/views/patcher/patcher_viewmodel.dart | 45 +----------- .../patches_selector_view.dart | 4 +- 8 files changed, 51 insertions(+), 127 deletions(-) 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: From 8661d72e453b12bd8696fad5121a66f93486427e Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Sep 2023 17:00:34 +0200 Subject: [PATCH 02/17] feat: Simplify label --- assets/i18n/en_US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 9092bbdc..8ff7d9bc 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -23,7 +23,7 @@ "widgetTitle": "Dashboard", "updatesSubtitle": "Updates", - "patchedSubtitle": "Patched applications", + "patchedSubtitle": "Patched apps", "noUpdates": "No updates available", From 8ce266bc94fb3add1fe9f2787734f121664e8df4 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Sep 2023 18:39:07 +0200 Subject: [PATCH 03/17] perf: Reduce amount of network requests --- assets/i18n/en_US.json | 4 +- lib/models/patch.dart | 1 - lib/models/patched_application.dart | 4 - lib/services/github_api.dart | 59 +------ lib/services/manager_api.dart | 68 +------- lib/services/revanced_api.dart | 34 ++-- lib/ui/views/home/home_viewmodel.dart | 9 +- .../navigation/navigation_viewmodel.dart | 4 +- .../widgets/homeView/installed_apps_card.dart | 2 - .../settings_advanced_section.dart | 2 +- lib/ui/widgets/shared/application_item.dart | 162 +++++------------- pubspec.yaml | 1 + 12 files changed, 78 insertions(+), 272 deletions(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 8ff7d9bc..571888cf 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -56,9 +56,7 @@ "updatesDisabled": "Updating a patched app is currently disabled. Repatch the app again." }, "applicationItem": { - "patchButton": "Patch", - "infoButton": "Info", - "changelogLabel": "Changelog" + "infoButton": "Info" }, "latestCommitCard": { "loadingLabel": "Loading...", diff --git a/lib/models/patch.dart b/lib/models/patch.dart index b3d99e2a..fe2b3c33 100644 --- a/lib/models/patch.dart +++ b/lib/models/patch.dart @@ -1,5 +1,4 @@ import 'package:json_annotation/json_annotation.dart'; -import 'package:revanced_manager/utils/string.dart'; part 'patch.g.dart'; diff --git a/lib/models/patched_application.dart b/lib/models/patched_application.dart index 90bfb9a3..8f54dd72 100644 --- a/lib/models/patched_application.dart +++ b/lib/models/patched_application.dart @@ -16,9 +16,7 @@ class PatchedApplication { required this.patchDate, this.isRooted = false, this.isFromStorage = false, - this.hasUpdates = false, this.appliedPatches = const [], - this.changelog = const [], }); factory PatchedApplication.fromJson(Map json) => @@ -36,9 +34,7 @@ class PatchedApplication { DateTime patchDate; bool isRooted; bool isFromStorage; - bool hasUpdates; List appliedPatches; - List changelog; Map toJson() => _$PatchedApplicationToJson(this); diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 0949f1b9..5f393daf 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -51,6 +51,7 @@ class GithubAPI { Future clearAllCache() async { try { await _cacheOptions.store!.clean(); + await DefaultCacheManager().emptyCache(); } on Exception catch (e) { if (kDebugMode) { print(e); @@ -142,38 +143,6 @@ class GithubAPI { } } - Future> getCommits( - String packageName, - String repoName, - DateTime since, - ) async { - final String path = - 'src/main/kotlin/app/revanced/patches/${repoAppPath[packageName]}'; - try { - final response = await _dio.get( - '/repos/$repoName/commits', - queryParameters: { - 'path': path, - 'since': since.toIso8601String(), - }, - ); - final List commits = response.data; - return commits - .map( - (commit) => commit['commit']['message'].split('\n')[0] + - ' - ' + - commit['commit']['author']['name'] + - '\n' as String, - ) - .toList(); - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } - return []; - } - Future getLatestReleaseFile( String extension, String repoName, @@ -237,30 +206,4 @@ class GithubAPI { } return null; } - - Future> getPatches( - String repoName, - String version, - String url, - ) async { - List patches = []; - try { - final File? f = await getPatchesReleaseFile( - '.json', - repoName, - version, - url, - ); - if (f != null) { - final List list = jsonDecode(f.readAsStringSync()); - patches = list.map((patch) => Patch.fromJson(patch)).toList(); - } - } on Exception catch (e) { - if (kDebugMode) { - print(e); - } - } - - return patches; - } } diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 7d42f6d7..5882f810 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -616,39 +616,6 @@ class ManagerAPI { ); } - Future reAssessSavedApps() async { - final List patchedApps = getPatchedApps(); - final List unsavedApps = - await getUnsavedApps(patchedApps); - patchedApps.addAll(unsavedApps); - final List toRemove = - await getAppsToRemove(patchedApps); - patchedApps.removeWhere((a) => toRemove.contains(a)); - for (final PatchedApplication app in patchedApps) { - app.hasUpdates = - await hasAppUpdates(app.originalPackageName, app.patchDate); - app.changelog = - await getAppChangelog(app.originalPackageName, app.patchDate); - if (!app.hasUpdates) { - final String? currentInstalledVersion = - (await DeviceApps.getApp(app.packageName))?.versionName; - if (currentInstalledVersion != null) { - final String currentSavedVersion = app.version; - final int currentInstalledVersionInt = int.parse( - currentInstalledVersion.replaceAll(RegExp('[^0-9]'), ''), - ); - final int currentSavedVersionInt = int.parse( - currentSavedVersion.replaceAll(RegExp('[^0-9]'), ''), - ); - if (currentInstalledVersionInt > currentSavedVersionInt) { - app.hasUpdates = true; - } - } - } - } - await setPatchedApps(patchedApps); - } - Future isAppUninstalled(PatchedApplication app) async { bool existsRoot = false; final bool existsNonRoot = await DeviceApps.isAppInstalled(app.packageName); @@ -662,37 +629,6 @@ class ManagerAPI { return !existsNonRoot; } - Future hasAppUpdates( - String packageName, - DateTime patchDate, - ) async { - final List commits = await _githubAPI.getCommits( - packageName, - getPatchesRepo(), - patchDate, - ); - return commits.isNotEmpty; - } - - Future> getAppChangelog( - String packageName, - DateTime patchDate, - ) async { - List newCommits = await _githubAPI.getCommits( - packageName, - getPatchesRepo(), - patchDate, - ); - if (newCommits.isEmpty) { - newCommits = await _githubAPI.getCommits( - packageName, - getPatchesRepo(), - patchDate, - ); - } - return newCommits; - } - Future isSplitApk(PatchedApplication patchedApp) async { Application? app; if (patchedApp.isFromStorage) { @@ -760,6 +696,8 @@ class ManagerAPI { Future resetLastSelectedPatches() async { final File selectedPatchesFile = File(storedPatchesFile); - selectedPatchesFile.deleteSync(); + if (selectedPatchesFile.existsSync()) { + selectedPatchesFile.deleteSync(); + } } } diff --git a/lib/services/revanced_api.dart b/lib/services/revanced_api.dart index dde23cee..f21e6b71 100644 --- a/lib/services/revanced_api.dart +++ b/lib/services/revanced_api.dart @@ -7,12 +7,15 @@ import 'package:dio_cache_interceptor/dio_cache_interceptor.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:injectable/injectable.dart'; +import 'package:synchronized/synchronized.dart'; import 'package:timeago/timeago.dart'; @lazySingleton class RevancedAPI { late Dio _dio = Dio(); + final Lock getToolsLock = Lock(); + final _cacheOptions = CacheOptions( store: MemCacheStore(), maxStale: const Duration(days: 1), @@ -38,6 +41,7 @@ class RevancedAPI { Future clearAllCache() async { try { await _cacheOptions.store!.clean(); + await DefaultCacheManager().emptyCache(); } on Exception catch (e) { if (kDebugMode) { print(e); @@ -66,21 +70,23 @@ class RevancedAPI { Future?> _getLatestRelease( String extension, String repoName, - ) async { - try { - final response = await _dio.get('/tools'); - final List tools = response.data['tools']; - return tools.firstWhereOrNull( - (t) => - t['repository'] == repoName && - (t['name'] as String).endsWith(extension), - ); - } on Exception catch (e) { - if (kDebugMode) { - print(e); + ) { + return getToolsLock.synchronized(() async { + try { + final response = await _dio.get('/tools'); + final List tools = response.data['tools']; + return tools.firstWhereOrNull( + (t) => + t['repository'] == repoName && + (t['name'] as String).endsWith(extension), + ); + } on Exception catch (e) { + if (kDebugMode) { + print(e); + } + return null; } - return null; - } + }); } Future getLatestReleaseVersion( diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index cfc99e66..7ff6d1bb 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -37,15 +37,15 @@ class HomeViewModel extends BaseViewModel { DateTime? _lastUpdate; bool showUpdatableApps = false; List patchedInstalledApps = []; - List patchedUpdatableApps = []; String? _latestManagerVersion = ''; File? downloadedApk; Future initialize(BuildContext context) async { - _latestManagerVersion = await _managerAPI.getLatestManagerVersion(); if (!_managerAPI.getPatchesConsent()) { await showPatchesConsent(context); } + + _latestManagerVersion = await _managerAPI.getLatestManagerVersion(); await _patcherAPI.initialize(); await flutterLocalNotificationsPlugin.initialize( const InitializationSettings( @@ -83,7 +83,6 @@ class HomeViewModel extends BaseViewModel { } } _getPatchedApps(); - _managerAPI.reAssessSavedApps().then((_) => _getPatchedApps()); } void navigateToAppInfo(PatchedApplication app) { @@ -108,10 +107,6 @@ class HomeViewModel extends BaseViewModel { void _getPatchedApps() { patchedInstalledApps = _managerAPI.getPatchedApps().toList(); - patchedUpdatableApps = _managerAPI - .getPatchedApps() - .where((app) => app.hasUpdates == true) - .toList(); notifyListeners(); } diff --git a/lib/ui/views/navigation/navigation_viewmodel.dart b/lib/ui/views/navigation/navigation_viewmodel.dart index a2a0e4bb..a911f070 100644 --- a/lib/ui/views/navigation/navigation_viewmodel.dart +++ b/lib/ui/views/navigation/navigation_viewmodel.dart @@ -39,9 +39,9 @@ class NavigationViewModel extends IndexTrackingViewModel { // Force disable Material You on Android 11 and below if (dynamicTheme.themeId.isOdd) { - const int ANDROID_12_SDK_VERSION = 31; + const int android12SdkVersion = 31; final AndroidDeviceInfo info = await DeviceInfoPlugin().androidInfo; - if (info.version.sdkInt < ANDROID_12_SDK_VERSION) { + if (info.version.sdkInt < android12SdkVersion) { await prefs.setInt('themeMode', 0); await prefs.setBool('useDynamicTheme', false); await dynamicTheme.setTheme(0); diff --git a/lib/ui/widgets/homeView/installed_apps_card.dart b/lib/ui/widgets/homeView/installed_apps_card.dart index 7a989856..ec825340 100644 --- a/lib/ui/widgets/homeView/installed_apps_card.dart +++ b/lib/ui/widgets/homeView/installed_apps_card.dart @@ -79,8 +79,6 @@ class InstalledAppsCard extends StatelessWidget { icon: app.icon, name: app.name, patchDate: app.patchDate, - changelog: app.changelog, - isUpdatableApp: false, onPressed: () => locator().navigateToAppInfo(app), ), diff --git a/lib/ui/widgets/settingsView/settings_advanced_section.dart b/lib/ui/widgets/settingsView/settings_advanced_section.dart index 2d9be3fc..f3e838a6 100644 --- a/lib/ui/widgets/settingsView/settings_advanced_section.dart +++ b/lib/ui/widgets/settingsView/settings_advanced_section.dart @@ -5,8 +5,8 @@ import 'package:flutter_i18n/widgets/I18nText.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_api_url.dart'; import 'package:revanced_manager/ui/views/settings/settingsFragment/settings_manage_sources.dart'; import 'package:revanced_manager/ui/views/settings/settings_viewmodel.dart'; -import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_auto_update_patches.dart'; +import 'package:revanced_manager/ui/widgets/settingsView/settings_enable_patches_selection.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_experimental_universal_patches.dart'; import 'package:revanced_manager/ui/widgets/settingsView/settings_section.dart'; diff --git a/lib/ui/widgets/shared/application_item.dart b/lib/ui/widgets/shared/application_item.dart index 42eee351..b7336435 100644 --- a/lib/ui/widgets/shared/application_item.dart +++ b/lib/ui/widgets/shared/application_item.dart @@ -1,6 +1,5 @@ import 'dart:typed_data'; -import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_card.dart'; @@ -13,151 +12,84 @@ class ApplicationItem extends StatefulWidget { required this.icon, required this.name, required this.patchDate, - required this.changelog, - required this.isUpdatableApp, required this.onPressed, }) : super(key: key); final Uint8List icon; final String name; final DateTime patchDate; - final List changelog; - final bool isUpdatableApp; final Function() onPressed; @override State createState() => _ApplicationItemState(); } -class _ApplicationItemState extends State - with TickerProviderStateMixin { - late AnimationController _animationController; +class _ApplicationItemState extends State { @override void initState() { super.initState(); - _animationController = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 300), - ); - } - - @override - void dispose() { - _animationController.dispose(); - super.dispose(); } @override Widget build(BuildContext context) { - final ExpandableController expController = ExpandableController(); return Container( margin: const EdgeInsets.only(bottom: 16.0), child: CustomCard( - onTap: () { - expController.toggle(); - _animationController.isCompleted - ? _animationController.reverse() - : _animationController.forward(); - }, - child: ExpandablePanel( - controller: expController, - theme: const ExpandableThemeData( - inkWellBorderRadius: BorderRadius.all(Radius.circular(16)), - tapBodyToCollapse: false, - tapBodyToExpand: false, - tapHeaderToExpand: false, - hasIcon: false, - animationDuration: Duration(milliseconds: 450), - ), - header: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: Row( - children: [ - SizedBox( - width: 40, - child: Image.memory(widget.icon, height: 40, width: 40), - ), - const SizedBox(width: 19), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.name, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - Text( - format(widget.patchDate), - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - ], - ), - ), - ], - ), - ), - Row( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Row( children: [ - RotationTransition( - turns: Tween(begin: 0.0, end: 0.50) - .animate(_animationController), - child: const Padding( - padding: EdgeInsets.all(8.0), - child: Icon(Icons.arrow_drop_down), - ), + SizedBox( + width: 40, + child: Image.memory(widget.icon, height: 40, width: 40), ), - const SizedBox(width: 8), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - CustomMaterialButton( - label: widget.isUpdatableApp - ? I18nText('applicationItem.patchButton') - : I18nText('applicationItem.infoButton'), - onPressed: widget.onPressed, - ), - ], + const SizedBox(width: 19), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.name, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + Text( + format(widget.patchDate), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + ), + ), + ], + ), ), ], ), - ], - ), - collapsed: const SizedBox(), - expanded: Padding( - padding: const EdgeInsets.only( - top: 16.0, - left: 4.0, - right: 4.0, - bottom: 4.0, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - I18nText( - 'applicationItem.changelogLabel', - child: const Text( - '', - style: TextStyle(fontWeight: FontWeight.w700), - ), + Row( + children: [ + const SizedBox(width: 8), + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + CustomMaterialButton( + label: I18nText('applicationItem.infoButton'), + onPressed: widget.onPressed, + ), + ], ), - const SizedBox(height: 4), - Text('\u2022 ${widget.changelog.join('\n\u2022 ')}'), ], ), - ), + ], ), ), ); diff --git a/pubspec.yaml b/pubspec.yaml index 98d16d32..297c8ada 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -75,6 +75,7 @@ dependencies: flutter_markdown: ^0.6.14 dio_cache_interceptor: ^3.4.0 install_plugin: ^2.1.0 + synchronized: ^3.1.0 dev_dependencies: json_serializable: ^6.6.1 From 15b8613d3cb2e0fe9b19d3bb9304f53db8cba372 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Sep 2023 19:40:02 +0200 Subject: [PATCH 04/17] feat: Only log relevant records --- .../main/kotlin/app/revanced/manager/flutter/MainActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 3cf0fafb..bd33a8b2 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 @@ -180,8 +180,11 @@ class MainActivity : FlutterActivity() { } object : java.util.logging.Handler() { - override fun publish(record: LogRecord) = + override fun publish(record: LogRecord) { + if (record.loggerName?.startsWith("app.revanced") != true) return + updateProgress(-1.0, "", record.message) + } override fun flush() = Unit override fun close() = flush() From 2e8e3b0d1ec4396796e264501ca6dbf1c615a878 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 29 Sep 2023 20:12:39 +0200 Subject: [PATCH 05/17] fix: Do not hardcode any predefined packages --- assets/i18n/en_US.json | 4 -- lib/services/github_api.dart | 11 ----- .../views/installer/installer_viewmodel.dart | 43 ++++--------------- .../appInfoView/app_info_viewmodel.dart | 12 +----- 4 files changed, 9 insertions(+), 61 deletions(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 571888cf..25945796 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -159,10 +159,6 @@ "exportApkButtonTooltip": "Export patched APK", "exportLogButtonTooltip": "Export log", - "installErrorDialogTitle": "Error", - "installErrorDialogText1": "Root install is not possible with the current patches selection.\nRepatch your app or choose non-root install.", - "installErrorDialogText2": "Non-root install is not possible with the current patches selection.\nRepatch your app or choose root install if you have your device rooted.", - "installErrorDialogText3": "Root install is not possible as the original APK was selected from storage.\nSelect an installed app or choose non-root install.", "noExit": "Installer is still running, cannot exit..." }, "settingsView": { diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 5f393daf..442b3ee6 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -21,17 +21,6 @@ class GithubAPI { priority: CachePriority.high, ); - final Map repoAppPath = { - 'com.google.android.youtube': 'youtube', - 'com.google.android.apps.youtube.music': 'music', - 'com.twitter.android': 'twitter', - 'com.reddit.frontpage': 'reddit', - 'com.zhiliaoapp.musically': 'tiktok', - 'de.dwd.warnapp': 'warnwetter', - 'com.garzotto.pflotsh.ecmwf_a': 'ecmwf', - 'com.spotify.music': 'spotify', - }; - Future initialize(String repoUrl) async { try { _dio = Dio( diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index f523f2a0..2245cab7 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -270,34 +270,6 @@ class InstallerViewModel extends BaseViewModel { Future installResult(BuildContext context, bool installAsRoot) async { try { _app.isRooted = installAsRoot; - final bool hasMicroG = - _patches.any((p) => p.name.endsWith('MicroG support')); - final bool rootMicroG = installAsRoot && hasMicroG; - final bool rootFromStorage = installAsRoot && _app.isFromStorage; - final bool ytWithoutRootMicroG = - !installAsRoot && !hasMicroG && _app.packageName.contains('youtube'); - if (rootMicroG || rootFromStorage || ytWithoutRootMicroG) { - return showDialog( - context: context, - builder: (context) => AlertDialog( - title: I18nText('installerView.installErrorDialogTitle'), - backgroundColor: Theme.of(context).colorScheme.secondaryContainer, - content: I18nText( - rootMicroG - ? 'installerView.installErrorDialogText1' - : rootFromStorage - ? 'installerView.installErrorDialogText3' - : 'installerView.installErrorDialogText2', - ), - actions: [ - CustomMaterialButton( - label: I18nText('okButton'), - onPressed: () => Navigator.of(context).pop(), - ), - ], - ), - ); - } else { update( 1.0, 'Installing...', @@ -311,16 +283,17 @@ class InstallerViewModel extends BaseViewModel { _app.isFromStorage = false; _app.patchDate = DateTime.now(); _app.appliedPatches = _patches.map((p) => p.name).toList(); - if (hasMicroG) { - _app.name += ' ReVanced'; - _app.packageName = _app.packageName.replaceFirst( - 'com.google.', - 'app.revanced.', - ); + + // In case a patch changed the app name or package name, + // update the app info. + final app = await DeviceApps.getAppFromStorage(_app.apkFilePath); + if (app != null) { + _app.name = app.appName; + _app.packageName = app.packageName; } + await _managerAPI.savePatchedApp(_app); } - } } on Exception catch (e) { if (kDebugMode) { print(e); diff --git a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart index dd364c7d..69b3f68b 100644 --- a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart +++ b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart @@ -147,17 +147,7 @@ class AppInfoViewModel extends BaseViewModel { } String getAppliedPatchesString(List appliedPatches) { - final List names = appliedPatches - .map( - (p) => p - .replaceAll('-', ' ') - .split('-') - .join(' ') - .toTitleCase() - .replaceFirst('Microg', 'MicroG'), - ) - .toList(); - return '\u2022 ${names.join('\n\u2022 ')}'; + return '\u2022 ${appliedPatches.join('\n\u2022 ')}'; } void openApp(PatchedApplication app) { From 1e8d8f749abc61e6b28b9db9f44c7abab17e6544 Mon Sep 17 00:00:00 2001 From: aAbed Date: Sat, 30 Sep 2023 14:57:48 +0545 Subject: [PATCH 06/17] fix: do not ask for patches consent before initializing model --- lib/ui/views/home/home_viewmodel.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 7ff6d1bb..69ce644d 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -41,11 +41,10 @@ class HomeViewModel extends BaseViewModel { File? downloadedApk; Future initialize(BuildContext context) async { + _latestManagerVersion = await _managerAPI.getLatestManagerVersion(); if (!_managerAPI.getPatchesConsent()) { await showPatchesConsent(context); } - - _latestManagerVersion = await _managerAPI.getLatestManagerVersion(); await _patcherAPI.initialize(); await flutterLocalNotificationsPlugin.initialize( const InitializationSettings( From 6bdc0c7bb24e98835caf0e9ab6bee03b0eeee476 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 19:58:45 +0200 Subject: [PATCH 07/17] feat: Simplify label --- assets/i18n/en_US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 25945796..e0038f3e 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -29,7 +29,7 @@ "WIP": "Work in progress...", - "noInstallations": "No patched applications installed", + "noInstallations": "No patched apps installed", "installUpdate": "Continue to install the update?", "updateDialogTitle": "Update Manager", From 36c86e22b1305043d6d19753cbbe1a3dc4df2eca Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 19:59:31 +0200 Subject: [PATCH 08/17] fix: Load installed apps --- .../revanced/manager/flutter/MainActivity.kt | 1 - lib/services/manager_api.dart | 71 +++++++++---------- lib/ui/views/home/home_viewmodel.dart | 3 +- 3 files changed, 35 insertions(+), 40 deletions(-) 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 bd33a8b2..691267b3 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 @@ -94,7 +94,6 @@ class MainActivity : FlutterActivity() { val patchBundleFilePath = call.argument("patchBundleFilePath")!! val cacheDirPath = call.argument("cacheDirPath")!! - JSONArray().apply { try { PatchBundleLoader.Dex( diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 5882f810..275efc93 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -42,12 +42,14 @@ class ManagerAPI { String defaultManagerRepo = 'revanced/revanced-manager'; String? patchesVersion = ''; String? integrationsVersion = ''; + bool isDefaultPatchesRepo() { return getPatchesRepo().toLowerCase() == 'revanced/revanced-patches'; } bool isDefaultIntegrationsRepo() { - return getIntegrationsRepo().toLowerCase() == 'revanced/revanced-integrations'; + return getIntegrationsRepo().toLowerCase() == + 'revanced/revanced-integrations'; } Future initialize() async { @@ -309,7 +311,7 @@ class ManagerAPI { final Directory appCache = await getTemporaryDirectory(); Directory('${appCache.path}/cache').createSync(); final Directory workDir = - Directory('${appCache.path}/cache').createTempSync('tmp-'); + Directory('${appCache.path}/cache').createTempSync('tmp-'); final Directory cacheDir = Directory('${workDir.path}/cache'); cacheDir.createSync(); @@ -324,7 +326,9 @@ class ManagerAPI { ); final List patchesJsonList = jsonDecode(patchesJson); - patches = patchesJsonList.map((patchJson) => Patch.fromJson(patchJson)).toList(); + patches = patchesJsonList + .map((patchJson) => Patch.fromJson(patchJson)) + .toList(); return patches; } on Exception catch (e) { if (kDebugMode) { @@ -501,48 +505,18 @@ class ManagerAPI { return toRemove; } - Future> getUnsavedApps( - List patchedApps, - ) async { - final List unsavedApps = []; + Future> getMountedApps() async { + final List mountedApps = []; final bool hasRootPermissions = await _rootAPI.hasRootPermissions(); if (hasRootPermissions) { final List installedApps = await _rootAPI.getInstalledApps(); for (final String packageName in installedApps) { - if (!patchedApps.any((app) => app.packageName == packageName)) { - final ApplicationWithIcon? application = await DeviceApps.getApp( - packageName, - true, - ) as ApplicationWithIcon?; - if (application != null) { - unsavedApps.add( - PatchedApplication( - name: application.appName, - packageName: application.packageName, - originalPackageName: application.packageName, - version: application.versionName!, - apkFilePath: application.apkFilePath, - icon: application.icon, - patchDate: DateTime.now(), - isRooted: true, - ), - ); - } - } - } - } - final List userApps = - await DeviceApps.getInstalledApplications(); - for (final Application app in userApps) { - if (app.packageName.startsWith('app.revanced') && - !app.packageName.startsWith('app.revanced.manager.') && - !patchedApps.any((uapp) => uapp.packageName == app.packageName)) { final ApplicationWithIcon? application = await DeviceApps.getApp( - app.packageName, + packageName, true, ) as ApplicationWithIcon?; if (application != null) { - unsavedApps.add( + mountedApps.add( PatchedApplication( name: application.appName, packageName: application.packageName, @@ -551,12 +525,14 @@ class ManagerAPI { apkFilePath: application.apkFilePath, icon: application.icon, patchDate: DateTime.now(), + isRooted: true, ), ); } } } - return unsavedApps; + + return mountedApps; } Future showPatchesChangeWarningDialog(BuildContext context) { @@ -616,6 +592,25 @@ class ManagerAPI { ); } + Future reAssessSavedApps() async { + final List patchedApps = getPatchedApps(); + + // Remove apps that are not installed anymore. + final List toRemove = + await getAppsToRemove(patchedApps); + patchedApps.removeWhere((a) => toRemove.contains(a)); + + // Determine all apps that are installed by mounting. + final List mountedApps = await getMountedApps(); + mountedApps.removeWhere( + (app) => patchedApps + .any((patchedApp) => patchedApp.packageName == app.packageName), + ); + patchedApps.addAll(mountedApps); + + await setPatchedApps(patchedApps); + } + Future isAppUninstalled(PatchedApplication app) async { bool existsRoot = false; final bool existsNonRoot = await DeviceApps.isAppInstalled(app.packageName); diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 69ce644d..40cf85b4 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -81,7 +81,8 @@ class HomeViewModel extends BaseViewModel { _toast.showBottom('homeView.errorDownloadMessage'); } } - _getPatchedApps(); + + _managerAPI.reAssessSavedApps().then((_) => _getPatchedApps()); } void navigateToAppInfo(PatchedApplication app) { From 0492e910ea565bd3cb35f781c298f867ec8bfaf9 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 20:10:45 +0200 Subject: [PATCH 09/17] fix: Fill the preferred action --- lib/ui/views/settings/settings_viewmodel.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ui/views/settings/settings_viewmodel.dart b/lib/ui/views/settings/settings_viewmodel.dart index 2441b0a6..7688d8b1 100644 --- a/lib/ui/views/settings/settings_viewmodel.dart +++ b/lib/ui/views/settings/settings_viewmodel.dart @@ -71,12 +71,6 @@ class SettingsViewModel extends BaseViewModel { actions: [ CustomMaterialButton( isFilled: false, - label: I18nText('noButton'), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CustomMaterialButton( label: I18nText('yesButton'), onPressed: () { _managerAPI.setChangingToggleModified(true); @@ -84,6 +78,12 @@ class SettingsViewModel extends BaseViewModel { Navigator.of(context).pop(); }, ), + CustomMaterialButton( + label: I18nText('noButton'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), ], ), ); From 91837ebade5e0a2f47731ba33b7268e3c7bb09e4 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 20:11:45 +0200 Subject: [PATCH 10/17] feat: Remove original package name in app info view --- assets/i18n/en_US.json | 1 - lib/models/patched_application.dart | 2 -- lib/services/github_api.dart | 2 -- lib/services/manager_api.dart | 1 - .../app_selector/app_selector_viewmodel.dart | 2 -- lib/ui/views/patcher/patcher_viewmodel.dart | 6 +++--- .../patches_selector_viewmodel.dart | 10 +++++----- lib/ui/widgets/appInfoView/app_info_view.dart | 16 ---------------- .../widgets/appInfoView/app_info_viewmodel.dart | 1 - 9 files changed, 8 insertions(+), 33 deletions(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index e0038f3e..3ad34a50 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -278,7 +278,6 @@ "rootDialogText": "App was installed with superuser permissions, but currently ReVanced Manager has no permissions.\nPlease grant superuser permissions first.", "packageNameLabel": "Package name", - "originalPackageNameLabel": "Original package name", "installTypeLabel": "Installation type", "rootTypeLabel": "Root", "nonRootTypeLabel": "Non-root", diff --git a/lib/models/patched_application.dart b/lib/models/patched_application.dart index 8f54dd72..23517595 100644 --- a/lib/models/patched_application.dart +++ b/lib/models/patched_application.dart @@ -9,7 +9,6 @@ class PatchedApplication { PatchedApplication({ required this.name, required this.packageName, - required this.originalPackageName, required this.version, required this.apkFilePath, required this.icon, @@ -23,7 +22,6 @@ class PatchedApplication { _$PatchedApplicationFromJson(json); String name; String packageName; - String originalPackageName; String version; final String apkFilePath; @JsonKey( diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 442b3ee6..03eacf8b 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:io'; import 'package:collection/collection.dart'; import 'package:dio/dio.dart'; @@ -7,7 +6,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:injectable/injectable.dart'; import 'package:revanced_manager/app/app.locator.dart'; -import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/services/manager_api.dart'; @lazySingleton diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 275efc93..d3eed845 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -520,7 +520,6 @@ class ManagerAPI { PatchedApplication( name: application.appName, packageName: application.packageName, - originalPackageName: application.packageName, version: application.versionName!, apkFilePath: application.apkFilePath, icon: application.icon, diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index e3691bba..bd029133 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -73,7 +73,6 @@ class AppSelectorViewModel extends BaseViewModel { locator().selectedApp = PatchedApplication( name: application.appName, packageName: application.packageName, - originalPackageName: application.packageName, version: application.versionName!, apkFilePath: application.apkFilePath, icon: application.icon, @@ -202,7 +201,6 @@ class AppSelectorViewModel extends BaseViewModel { locator().selectedApp = PatchedApplication( name: application.appName, packageName: application.packageName, - originalPackageName: application.packageName, version: application.versionName!, apkFilePath: result.files.single.path!, icon: application.icon, diff --git a/lib/ui/views/patcher/patcher_viewmodel.dart b/lib/ui/views/patcher/patcher_viewmodel.dart index bd0bc41b..e0cadb4a 100644 --- a/lib/ui/views/patcher/patcher_viewmodel.dart +++ b/lib/ui/views/patcher/patcher_viewmodel.dart @@ -142,9 +142,9 @@ class PatcherViewModel extends BaseViewModel { this.selectedPatches.clear(); removedPatches.clear(); final List selectedPatches = - await _managerAPI.getSelectedPatches(selectedApp!.originalPackageName); + await _managerAPI.getSelectedPatches(selectedApp!.packageName); final List patches = - _patcherAPI.getFilteredPatches(selectedApp!.originalPackageName); + _patcherAPI.getFilteredPatches(selectedApp!.packageName); this .selectedPatches .addAll(patches.where((patch) => selectedPatches.contains(patch.name))); @@ -160,7 +160,7 @@ class PatcherViewModel extends BaseViewModel { .selectedPatches .removeWhere((patch) => patch.compatiblePackages.isEmpty); } - final usedPatches = _managerAPI.getUsedPatches(selectedApp!.originalPackageName); + final usedPatches = _managerAPI.getUsedPatches(selectedApp!.packageName); for (final patch in usedPatches){ if (!patches.any((p) => p.name == patch.name)){ removedPatches.add('\u2022 ${patch.name}'); diff --git a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart index 71e4a16e..ea48c0da 100644 --- a/lib/ui/views/patches_selector/patches_selector_viewmodel.dart +++ b/lib/ui/views/patches_selector/patches_selector_viewmodel.dart @@ -28,7 +28,7 @@ class PatchesSelectorViewModel extends BaseViewModel { getPatchesVersion().whenComplete(() => notifyListeners()); patches.addAll( _patcherAPI.getFilteredPatches( - selectedApp!.originalPackageName, + selectedApp!.packageName, ), ); patches.sort((a, b) { @@ -98,11 +98,11 @@ class PatchesSelectorViewModel extends BaseViewModel { void selectDefaultPatches() { selectedPatches.clear(); - if (locator().selectedApp?.originalPackageName != null) { + if (locator().selectedApp?.packageName != null) { selectedPatches.addAll( _patcherAPI .getFilteredPatches( - locator().selectedApp!.originalPackageName, + locator().selectedApp!.packageName, ) .where( (element) => @@ -187,7 +187,7 @@ class PatchesSelectorViewModel extends BaseViewModel { final List selectedPatches = this.selectedPatches.map((patch) => patch.name).toList(); await _managerAPI.setSelectedPatches( - locator().selectedApp!.originalPackageName, + locator().selectedApp!.packageName, selectedPatches, ); } @@ -195,7 +195,7 @@ class PatchesSelectorViewModel extends BaseViewModel { Future loadSelectedPatches(BuildContext context) async { if (_managerAPI.isPatchesChangeEnabled()) { final List selectedPatches = await _managerAPI.getSelectedPatches( - locator().selectedApp!.originalPackageName, + locator().selectedApp!.packageName, ); if (selectedPatches.isNotEmpty) { this.selectedPatches.clear(); diff --git a/lib/ui/widgets/appInfoView/app_info_view.dart b/lib/ui/widgets/appInfoView/app_info_view.dart index 2d0f17e1..283beb12 100644 --- a/lib/ui/widgets/appInfoView/app_info_view.dart +++ b/lib/ui/widgets/appInfoView/app_info_view.dart @@ -222,22 +222,6 @@ class AppInfoView extends StatelessWidget { subtitle: Text(app.packageName), ), const SizedBox(height: 4), - ListTile( - contentPadding: - const EdgeInsets.symmetric(horizontal: 20.0), - title: I18nText( - 'appInfoView.originalPackageNameLabel', - child: const Text( - '', - style: TextStyle( - fontSize: 20, - fontWeight: FontWeight.w500, - ), - ), - ), - subtitle: Text(app.originalPackageName), - ), - const SizedBox(height: 4), ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 20.0), diff --git a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart index 69b3f68b..bc24a558 100644 --- a/lib/ui/widgets/appInfoView/app_info_viewmodel.dart +++ b/lib/ui/widgets/appInfoView/app_info_viewmodel.dart @@ -13,7 +13,6 @@ import 'package:revanced_manager/ui/views/home/home_viewmodel.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_viewmodel.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; -import 'package:revanced_manager/utils/string.dart'; import 'package:stacked/stacked.dart'; class AppInfoViewModel extends BaseViewModel { From c4a795418f80ce873d7bdf90fdb2f4f19142b079 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 21:13:32 +0200 Subject: [PATCH 11/17] fix: Move installation log to correct place --- lib/ui/views/installer/installer_viewmodel.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 2245cab7..52318967 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -279,7 +279,6 @@ class InstallerViewModel extends BaseViewModel { ); isInstalled = await _patcherAPI.installPatchedFile(_app); if (isInstalled) { - update(1.0, 'Installed!', 'Installed!'); _app.isFromStorage = false; _app.patchDate = DateTime.now(); _app.appliedPatches = _patches.map((p) => p.name).toList(); @@ -293,6 +292,8 @@ class InstallerViewModel extends BaseViewModel { } await _managerAPI.savePatchedApp(_app); + + update(1.0, 'Installed!', 'Installed!'); } } on Exception catch (e) { if (kDebugMode) { From 2b4b3ca0a51af92fab4b04edbc39d6c3a4ea2c33 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 21:40:03 +0200 Subject: [PATCH 12/17] fix: Retrieve app information from patched app --- lib/services/patcher_api.dart | 24 +++++++++---------- .../views/installer/installer_viewmodel.dart | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index ecc3b218..9a094bec 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -28,7 +28,7 @@ class PatcherAPI { List _universalPatches = []; List _compatiblePackages = []; Map filteredPatches = >{}; - File? _outFile; + File? outFile; Future initialize() async { await _loadPatches(); @@ -162,7 +162,7 @@ class PatcherAPI { final Directory workDir = _tmpDir.createTempSync('tmp-'); final File inputFile = File('${workDir.path}/base.apk'); final File patchedFile = File('${workDir.path}/patched.apk'); - _outFile = File('${workDir.path}/out.apk'); + outFile = File('${workDir.path}/out.apk'); final Directory cacheDir = Directory('${workDir.path}/cache'); cacheDir.createSync(); final String originalFilePath = apkFilePath; @@ -174,7 +174,7 @@ class PatcherAPI { 'originalFilePath': originalFilePath, 'inputFilePath': inputFile.path, 'patchedFilePath': patchedFile.path, - 'outFilePath': _outFile!.path, + 'outFilePath': outFile!.path, 'integrationsPath': integrationsFile!.path, 'selectedPatches': selectedPatches.map((p) => p.name).toList(), 'cacheDirPath': cacheDir.path, @@ -201,7 +201,7 @@ class PatcherAPI { } Future installPatchedFile(PatchedApplication patchedApp) async { - if (_outFile != null) { + if (outFile != null) { try { if (patchedApp.isRooted) { final bool hasRootPermissions = await _rootAPI.hasRootPermissions(); @@ -209,11 +209,11 @@ class PatcherAPI { return _rootAPI.installApp( patchedApp.packageName, patchedApp.apkFilePath, - _outFile!.path, + outFile!.path, ); } } else { - final install = await InstallPlugin.installApk(_outFile!.path); + final install = await InstallPlugin.installApk(outFile!.path); return install['isSuccess']; } } on Exception catch (e) { @@ -228,11 +228,11 @@ class PatcherAPI { void exportPatchedFile(String appName, String version) { try { - if (_outFile != null) { + if (outFile != null) { final String newName = _getFileName(appName, version); CRFileSaver.saveFileWithDialog( SaveFileDialogParams( - sourceFilePath: _outFile!.path, + sourceFilePath: outFile!.path, destinationFileName: newName, ), ); @@ -246,12 +246,12 @@ class PatcherAPI { void sharePatchedFile(String appName, String version) { try { - if (_outFile != null) { + if (outFile != null) { final String newName = _getFileName(appName, version); - final int lastSeparator = _outFile!.path.lastIndexOf('/'); + final int lastSeparator = outFile!.path.lastIndexOf('/'); final String newPath = - _outFile!.path.substring(0, lastSeparator + 1) + newName; - final File shareFile = _outFile!.copySync(newPath); + outFile!.path.substring(0, lastSeparator + 1) + newName; + final File shareFile = outFile!.copySync(newPath); ShareExtend.share(shareFile.path, 'file'); } } on Exception catch (e) { diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 52318967..426b0669 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -285,7 +285,7 @@ class InstallerViewModel extends BaseViewModel { // In case a patch changed the app name or package name, // update the app info. - final app = await DeviceApps.getAppFromStorage(_app.apkFilePath); + final app = await DeviceApps.getAppFromStorage(_patcherAPI.outFile!.path); if (app != null) { _app.name = app.appName; _app.packageName = app.packageName; From 123a375a27a787f621e05bf906e2cbdc6a36e8bb Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 22:14:51 +0200 Subject: [PATCH 13/17] refactor: Remove unused strings --- assets/i18n/en_US.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 3ad34a50..242ebf64 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -69,8 +69,8 @@ "widgetTitle": "Patcher", "patchButton": "Patch", - "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?", + "removedPatchesWarningDialogText": "The following patches have been removed since the last time you used them.\n\n{patches}\n\nProceed anyways?" }, "appSelectorCard": { From 6e26130744efb71c5979f12fb0cfeb4fbe0d1577 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 30 Sep 2023 22:15:46 +0200 Subject: [PATCH 14/17] chore: Add todo --- lib/ui/views/installer/installer_viewmodel.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index 426b0669..ab60c377 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -294,6 +294,8 @@ class InstallerViewModel extends BaseViewModel { await _managerAPI.savePatchedApp(_app); update(1.0, 'Installed!', 'Installed!'); + } else { + // TODO(aabed): Show error message. } } on Exception catch (e) { if (kDebugMode) { From 6961bb7fd096cd618e24e343a92f00fb8eeba1ee Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 1 Oct 2023 04:48:24 +0200 Subject: [PATCH 15/17] fix: Do not delete cached downloads --- lib/services/github_api.dart | 1 - lib/services/revanced_api.dart | 1 - lib/ui/views/home/home_viewmodel.dart | 6 +----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index 03eacf8b..8d3244b3 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -38,7 +38,6 @@ class GithubAPI { Future clearAllCache() async { try { await _cacheOptions.store!.clean(); - await DefaultCacheManager().emptyCache(); } on Exception catch (e) { if (kDebugMode) { print(e); diff --git a/lib/services/revanced_api.dart b/lib/services/revanced_api.dart index f21e6b71..fca17c0e 100644 --- a/lib/services/revanced_api.dart +++ b/lib/services/revanced_api.dart @@ -41,7 +41,6 @@ class RevancedAPI { Future clearAllCache() async { try { await _cacheOptions.store!.clean(); - await DefaultCacheManager().emptyCache(); } on Exception catch (e) { if (kDebugMode) { print(e); diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index 40cf85b4..1ab8437d 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -464,11 +464,7 @@ class HomeViewModel extends BaseViewModel { } Future forceRefresh(BuildContext context) async { - await Future.delayed(const Duration(seconds: 1)); - if (_lastUpdate == null || - _lastUpdate!.difference(DateTime.now()).inSeconds > 2) { - _managerAPI.clearAllData(); - } + _managerAPI.clearAllData(); _toast.showBottom('homeView.refreshSuccess'); initialize(context); } From c87f92b34601097dfb722162043469de0983b62d Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 1 Oct 2023 06:21:03 +0200 Subject: [PATCH 16/17] feat: Adjust install dialog labels --- assets/i18n/en_US.json | 5 ++--- lib/ui/views/installer/installer_viewmodel.dart | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/assets/i18n/en_US.json b/assets/i18n/en_US.json index 242ebf64..d3fe1128 100644 --- a/assets/i18n/en_US.json +++ b/assets/i18n/en_US.json @@ -145,9 +145,8 @@ "installTypeDescription": "Select the installation type to proceed with.", "installButton": "Install", - "installRootType": "Root", - "installNonRootType": "Non-root", - "installRecommendedType": "Recommended", + "installRootType": "Mount", + "installNonRootType": "Normal", "pressBackAgain": "Press back again to cancel", "openButton": "Open", diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index ab60c377..137d2269 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -209,7 +209,6 @@ class InstallerViewModel extends BaseViewModel { ), RadioListTile( title: I18nText('installerView.installNonRootType'), - subtitle: I18nText('installerView.installRecommendedType'), contentPadding: const EdgeInsets.symmetric(horizontal: 16), value: 0, groupValue: value, From 697ae92031a48fd071525694f08e442679c1a131 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 1 Oct 2023 19:02:49 +0200 Subject: [PATCH 17/17] Apply suggestions from code review [skip ci] --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 16c72ee3..7854f0c1 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:15.0.2" + implementation "app.revanced:revanced-patcher:15.0.3" // Signing & aligning implementation("org.bouncycastle:bcpkix-jdk15on:1.70")