feat(mount): use /data/adb/revanced again and ensure migration scenario (#948)

This commit is contained in:
ponces 2023-06-22 23:03:03 +01:00 committed by GitHub
parent af054fba49
commit 35e99cb014
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 79 deletions

View file

@ -144,30 +144,23 @@ class PatcherAPI {
); );
} }
Future<String> getOriginalFilePath( Future<String> getOriginalFilePath(String packageName) async {
String packageName,
String originalFilePath,
) async {
try { try {
final bool hasRootPermissions = await _rootAPI.hasRootPermissions(); final bool hasRootPermissions = await _rootAPI.hasRootPermissions();
if (hasRootPermissions) { if (hasRootPermissions) {
originalFilePath = await _rootAPI.getOriginalFilePath( return await _rootAPI.getOriginalFilePath(packageName);
packageName,
originalFilePath,
);
} }
return originalFilePath;
} on Exception catch (e) { } on Exception catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
} }
return originalFilePath;
} }
return '';
} }
Future<void> runPatcher( Future<void> runPatcher(
String packageName, String packageName,
String originalFilePath, String apkFilePath,
List<Patch> selectedPatches, List<Patch> selectedPatches,
) async { ) async {
final bool includeSettings = await needsSettingsPatch(selectedPatches); final bool includeSettings = await needsSettingsPatch(selectedPatches);
@ -198,15 +191,16 @@ class PatcherAPI {
_outFile = File('${workDir.path}/out.apk'); _outFile = File('${workDir.path}/out.apk');
final Directory cacheDir = Directory('${workDir.path}/cache'); final Directory cacheDir = Directory('${workDir.path}/cache');
cacheDir.createSync(); cacheDir.createSync();
String originalFilePath = await getOriginalFilePath(packageName);
if (originalFilePath.isEmpty) {
originalFilePath = apkFilePath;
}
try { try {
await patcherChannel.invokeMethod( await patcherChannel.invokeMethod(
'runPatcher', 'runPatcher',
{ {
'patchBundleFilePath': patchBundleFile.path, 'patchBundleFilePath': patchBundleFile.path,
'originalFilePath': await getOriginalFilePath( 'originalFilePath': originalFilePath,
packageName,
originalFilePath,
),
'inputFilePath': inputFile.path, 'inputFilePath': inputFile.path,
'patchedFilePath': patchedFile.path, 'patchedFilePath': patchedFile.path,
'outFilePath': _outFile!.path, 'outFilePath': _outFile!.path,

View file

@ -2,7 +2,9 @@ import 'package:flutter/foundation.dart';
import 'package:root/root.dart'; import 'package:root/root.dart';
class RootAPI { class RootAPI {
final String _managerDirPath = '/data/local/tmp/revanced-manager'; // TODO(ponces): remove in the future, keep it for now during migration.
final String _revancedOldDirPath = '/data/local/tmp/revanced-manager';
final String _revancedDirPath = '/data/adb/revanced';
final String _postFsDataDirPath = '/data/adb/post-fs-data.d'; final String _postFsDataDirPath = '/data/adb/post-fs-data.d';
final String _serviceDDirPath = '/data/adb/service.d'; final String _serviceDDirPath = '/data/adb/service.d';
@ -40,55 +42,62 @@ class RootAPI {
seLinux, seLinux,
String filePath, String filePath,
) async { ) async {
if (permissions.isNotEmpty) {
await Root.exec(
cmd: 'chmod $permissions "$filePath"',
);
}
if (ownerGroup.isNotEmpty) {
await Root.exec(
cmd: 'chown $ownerGroup "$filePath"',
);
}
if (seLinux.isNotEmpty) {
await Root.exec(
cmd: 'chcon $seLinux "$filePath"',
);
}
}
Future<bool> isAppInstalled(String packageName) async {
if (packageName.isNotEmpty) {
String? res = await Root.exec(
cmd: 'ls "$_managerDirPath/$packageName"',
);
if (res != null && res.isNotEmpty) {
res = await Root.exec(
cmd: 'ls "$_serviceDDirPath/$packageName.sh"',
);
return res != null && res.isNotEmpty;
}
}
return false;
}
Future<List<String>> getInstalledApps() async {
try { try {
final String? res = await Root.exec( if (permissions.isNotEmpty) {
cmd: 'ls "$_managerDirPath"', await Root.exec(
); cmd: 'chmod $permissions "$filePath"',
if (res != null) { );
final List<String> apps = res.split('\n'); }
apps.removeWhere((pack) => pack.isEmpty); if (ownerGroup.isNotEmpty) {
return apps.map((pack) => pack.trim()).toList(); await Root.exec(
cmd: 'chown $ownerGroup "$filePath"',
);
}
if (seLinux.isNotEmpty) {
await Root.exec(
cmd: 'chcon $seLinux "$filePath"',
);
} }
} on Exception catch (e) { } on Exception catch (e) {
if (kDebugMode) { if (kDebugMode) {
print(e); print(e);
} }
return List.empty();
} }
return List.empty(); }
Future<bool> isAppInstalled(String packageName) async {
if (packageName.isNotEmpty) {
return fileExists('$_serviceDDirPath/$packageName.sh');
}
return false;
}
Future<List<String>> getInstalledApps() async {
final List<String> apps = List.empty();
try {
String? res = await Root.exec(
cmd: 'ls "$_revancedDirPath"',
);
if (res != null) {
final List<String> list = res.split('\n');
list.removeWhere((pack) => pack.isEmpty);
apps.addAll(list.map((pack) => pack.trim()).toList());
}
// TODO(ponces): remove in the future, keep it for now during migration.
res = await Root.exec(
cmd: 'ls "$_revancedOldDirPath"',
);
if (res != null) {
final List<String> list = res.split('\n');
list.removeWhere((pack) => pack.isEmpty);
apps.addAll(list.map((pack) => pack.trim()).toList());
}
} on Exception catch (e) {
if (kDebugMode) {
print(e);
}
}
return apps;
} }
Future<void> deleteApp(String packageName, String originalFilePath) async { Future<void> deleteApp(String packageName, String originalFilePath) async {
@ -98,8 +107,12 @@ class RootAPI {
await Root.exec( await Root.exec(
cmd: 'su -mm -c "umount -l $originalFilePath"', cmd: 'su -mm -c "umount -l $originalFilePath"',
); );
// TODO(ponces): remove in the future, keep it for now during migration.
await Root.exec( await Root.exec(
cmd: 'rm -rf "$_managerDirPath/$packageName"', cmd: 'rm -rf "$_revancedOldDirPath/$packageName"',
);
await Root.exec(
cmd: 'rm -rf "$_revancedDirPath/$packageName"',
); );
await Root.exec( await Root.exec(
cmd: 'rm -rf "$_serviceDDirPath/$packageName.sh"', cmd: 'rm -rf "$_serviceDDirPath/$packageName.sh"',
@ -117,13 +130,13 @@ class RootAPI {
try { try {
await deleteApp(packageName, originalFilePath); await deleteApp(packageName, originalFilePath);
await Root.exec( await Root.exec(
cmd: 'mkdir -p "$_managerDirPath/$packageName"', cmd: 'mkdir -p "$_revancedDirPath/$packageName"',
); );
await setPermissions( await setPermissions(
'0755', '0755',
'shell:shell', 'shell:shell',
'', '',
'$_managerDirPath/$packageName', '$_revancedDirPath/$packageName',
); );
await saveOriginalFilePath(packageName, originalFilePath); await saveOriginalFilePath(packageName, originalFilePath);
await installServiceDScript(packageName); await installServiceDScript(packageName);
@ -142,7 +155,7 @@ class RootAPI {
Future<void> installServiceDScript(String packageName) async { Future<void> installServiceDScript(String packageName) async {
final String content = '#!/system/bin/sh\n' final String content = '#!/system/bin/sh\n'
'while [ "\$(getprop sys.boot_completed | tr -d \'"\'"\'\\\\r\'"\'"\')" != "1" ]; do sleep 3; done\n' 'while [ "\$(getprop sys.boot_completed | tr -d \'"\'"\'\\\\r\'"\'"\')" != "1" ]; do sleep 3; done\n'
'base_path=$_managerDirPath/$packageName/base.apk\n' 'base_path=$_revancedDirPath/$packageName/base.apk\n'
'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n' 'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n'
r'[ ! -z $stock_path ] && mount -o bind $base_path $stock_path'; r'[ ! -z $stock_path ] && mount -o bind $base_path $stock_path';
final String scriptFilePath = '$_serviceDDirPath/$packageName.sh'; final String scriptFilePath = '$_serviceDDirPath/$packageName.sh';
@ -164,7 +177,7 @@ class RootAPI {
} }
Future<void> installApk(String packageName, String patchedFilePath) async { Future<void> installApk(String packageName, String patchedFilePath) async {
final String newPatchedFilePath = '$_managerDirPath/$packageName/base.apk'; final String newPatchedFilePath = '$_revancedDirPath/$packageName/base.apk';
await Root.exec( await Root.exec(
cmd: 'cp "$patchedFilePath" "$newPatchedFilePath"', cmd: 'cp "$patchedFilePath" "$newPatchedFilePath"',
); );
@ -177,7 +190,7 @@ class RootAPI {
} }
Future<void> mountApk(String packageName, String originalFilePath) async { Future<void> mountApk(String packageName, String originalFilePath) async {
final String newPatchedFilePath = '$_managerDirPath/$packageName/base.apk'; final String newPatchedFilePath = '$_revancedDirPath/$packageName/base.apk';
await Root.exec( await Root.exec(
cmd: 'am force-stop "$packageName"', cmd: 'am force-stop "$packageName"',
); );
@ -196,21 +209,18 @@ class RootAPI {
return res != null && res.isNotEmpty; return res != null && res.isNotEmpty;
} }
Future<String> getOriginalFilePath( Future<String> getOriginalFilePath(String packageName) async {
String packageName, final String originalPath = '$_revancedDirPath/$packageName/original.apk';
String originalFilePath, final String oldOrigPath = '$_revancedOldDirPath/$packageName/original.apk';
) async {
final bool isInstalled = await isAppInstalled(packageName); final bool isInstalled = await isAppInstalled(packageName);
if (isInstalled && await isMounted(packageName)) { if (isInstalled && await isMounted(packageName)) {
originalFilePath = '$_managerDirPath/$packageName/original.apk'; if (await fileExists(originalPath)) {
await setPermissions( return originalPath;
'0644', } else if (await fileExists(oldOrigPath)) {
'shell:shell', return oldOrigPath;
'u:object_r:apk_data_file:s0', }
originalFilePath,
);
} }
return originalFilePath; return '';
} }
Future<void> saveOriginalFilePath( Future<void> saveOriginalFilePath(
@ -218,15 +228,15 @@ class RootAPI {
String originalFilePath, String originalFilePath,
) async { ) async {
final String originalRootPath = final String originalRootPath =
'$_managerDirPath/$packageName/original.apk'; '$_revancedDirPath/$packageName/original.apk';
await Root.exec( await Root.exec(
cmd: 'mkdir -p "$_managerDirPath/$packageName"', cmd: 'mkdir -p "$_revancedDirPath/$packageName"',
); );
await setPermissions( await setPermissions(
'0755', '0755',
'shell:shell', 'shell:shell',
'', '',
'$_managerDirPath/$packageName', '$_revancedDirPath/$packageName',
); );
await Root.exec( await Root.exec(
cmd: 'cp "$originalFilePath" "$originalRootPath"', cmd: 'cp "$originalFilePath" "$originalRootPath"',
@ -238,4 +248,18 @@ class RootAPI {
originalFilePath, originalFilePath,
); );
} }
Future<bool> fileExists(String path) async {
try {
final String? res = await Root.exec(
cmd: 'ls $path',
);
return res != null && res.isNotEmpty;
} on Exception catch (e) {
if (kDebugMode) {
print(e);
}
return false;
}
}
} }