mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
feat(mount): use /data/adb/revanced
again and ensure migration scenario (#948)
This commit is contained in:
parent
af054fba49
commit
35e99cb014
2 changed files with 97 additions and 79 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue