fix: root installation and foreground task and improve installer a bit

This commit is contained in:
Alberto Ponces
2022-08-15 03:31:36 +01:00
parent 8fd942a808
commit 5c71930ec1
10 changed files with 231 additions and 207 deletions

View File

@ -40,13 +40,12 @@ class GithubAPI {
Future<List<Contributor>> getContributors(String org, repoName) async {
try {
var contributors = await github.repositories.listContributors(
var contributors = github.repositories.listContributors(
RepositorySlug(org, repoName),
);
return contributors.toList();
} on Exception {
print(Exception);
return [];
return List.empty();
}
}
}

View File

@ -32,11 +32,8 @@ class PatcherAPI {
Future<dynamic> handlePlatformChannelMethods() async {
platform.setMethodCallHandler((call) async {
switch (call.method) {
case 'updateInstallerLog':
var message = call.arguments<String>('message');
locator<InstallerViewModel>().addLog(message);
return 'OK';
if (call.method == 'updateInstallerLog' && call.arguments != null) {
locator<InstallerViewModel>().addLog(call.arguments);
}
});
}
@ -298,4 +295,17 @@ class PatcherAPI {
return false;
}
}
Future<bool> checkOldPatch(PatchedApplication patchedApp) async {
if (patchedApp.isRooted) {
return await rootAPI.checkApp(patchedApp.packageName);
}
return false;
}
Future<void> deleteOldPatch(PatchedApplication patchedApp) async {
if (patchedApp.isRooted) {
await rootAPI.deleteApp(patchedApp.packageName, patchedApp.apkFilePath);
}
}
}

View File

@ -1,5 +1,3 @@
import 'dart:io';
import 'package:injectable/injectable.dart';
import 'package:root/root.dart';
@ -9,17 +7,35 @@ class RootAPI {
final String postFsDataDirPath = "/data/adb/post-fs-data.d";
final String serviceDDirPath = "/data/adb/service.d";
bool deleteApp(String packageName) {
Future<bool> checkApp(String packageName) async {
try {
File('$managerDirPath/$packageName.apk').deleteSync();
File('$serviceDDirPath/$packageName.sh').deleteSync();
File('$postFsDataDirPath/$packageName.sh').deleteSync();
return true;
String? res = await Root.exec(
cmd: 'ls -la "$managerDirPath/$packageName"',
);
return res != null && res.isNotEmpty;
} on Exception {
return false;
}
}
Future<void> deleteApp(String packageName, String originalFilePath) async {
await Root.exec(
cmd: 'am force-stop "$packageName"',
);
await Root.exec(
cmd: 'su -mm -c "umount -l $originalFilePath"',
);
await Root.exec(
cmd: 'rm -rf "$managerDirPath/$packageName"',
);
await Root.exec(
cmd: 'rm -rf "$serviceDDirPath/$packageName.sh"',
);
await Root.exec(
cmd: 'rm -rf "$postFsDataDirPath/$packageName.sh"',
);
}
Future<bool> installApp(
String packageName,
String originalFilePath,
@ -27,66 +43,76 @@ class RootAPI {
) async {
try {
await Root.exec(
cmd: 'mkdir "$managerDirPath"',
);
String newPatchedFilePath = '$managerDirPath/$packageName.apk';
installServiceDScript(
packageName,
originalFilePath,
newPatchedFilePath,
);
installPostFsDataScript(
packageName,
originalFilePath,
newPatchedFilePath,
);
await Root.exec(
cmd: 'cp $patchedFilePath $newPatchedFilePath',
);
await Root.exec(
cmd: 'chmod 644 "$newPatchedFilePath"',
);
await Root.exec(
cmd: 'chown system:system "$newPatchedFilePath"',
);
await Root.exec(
cmd: 'chcon u:object_r:apk_data_file:s0 "$newPatchedFilePath"',
cmd: 'mkdir -p "$managerDirPath/$packageName"',
);
installServiceDScript(packageName);
installPostFsDataScript(packageName);
installApk(packageName, patchedFilePath);
mountApk(packageName, originalFilePath, patchedFilePath);
return true;
} on Exception {
return false;
}
}
Future<void> installServiceDScript(
String packageName,
String originalFilePath,
String patchedFilePath,
) async {
Future<void> installServiceDScript(String packageName) async {
String content = '#!/system/bin/sh\n'
'while [ "\$(getprop sys.boot_completed | tr -d \'\r\')" != "1" ]; do sleep 1; done\n'
'sleep 1\n'
'chcon u:object_r:apk_data_file:s0 $patchedFilePath\n'
'mount -o bind $patchedFilePath $originalFilePath';
'while [ "\$(getprop sys.boot_completed | tr -d \'"\'"\'\\\\r\'"\'"\')" != "1" ]; do sleep 1; done\n'
'base_path=$managerDirPath/$packageName/base.apk\n'
'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n'
'[ ! -z \$stock_path ] && mount -o bind \$base_path \$stock_path';
String scriptFilePath = '$serviceDDirPath/$packageName.sh';
await Root.exec(
cmd: 'echo "$content" > "$scriptFilePath"',
cmd: 'echo \'$content\' > "$scriptFilePath"',
);
await Root.exec(
cmd: 'chmod 744 "$scriptFilePath"',
);
await Root.exec(cmd: 'chmod 744 "$scriptFilePath"');
}
Future<void> installPostFsDataScript(
Future<void> installPostFsDataScript(String packageName) async {
String content = '#!/system/bin/sh\n'
'stock_path=\$(pm path $packageName | grep base | sed \'"\'"\'s/package://g\'"\'"\')\n'
'[ ! -z \$stock_path ] && umount -l \$stock_path';
String scriptFilePath = '$postFsDataDirPath/$packageName.sh';
await Root.exec(
cmd: 'echo \'$content\' > "$scriptFilePath"',
);
await Root.exec(
cmd: 'chmod 744 "$scriptFilePath"',
);
}
Future<void> installApk(String packageName, String patchedFilePath) async {
String newPatchedFilePath = '$managerDirPath/$packageName/base.apk';
await Root.exec(
cmd: 'cp "$patchedFilePath" "$newPatchedFilePath"',
);
await Root.exec(
cmd: 'chmod 644 "$newPatchedFilePath"',
);
await Root.exec(
cmd: 'chown system:system "$newPatchedFilePath"',
);
await Root.exec(
cmd: 'chcon u:object_r:apk_data_file:s0 "$newPatchedFilePath"',
);
}
Future<void> mountApk(
String packageName,
String originalFilePath,
String patchedFilePath,
) async {
String content = '#!/system/bin/sh\n'
'while read line; do echo \$line | grep $originalFilePath | '
'awk \'{print \$2}\' | xargs umount -l; done< /proc/mounts';
String scriptFilePath = '$postFsDataDirPath/$packageName.sh';
String newPatchedFilePath = '$managerDirPath/$packageName/base.apk';
await Root.exec(
cmd: 'echo "$content" > "$scriptFilePath"',
cmd: 'am force-stop "$packageName"',
);
await Root.exec(
cmd: 'su -mm -c "umount -l $originalFilePath"',
);
await Root.exec(
cmd: 'su -mm -c "mount -o bind $newPatchedFilePath $originalFilePath"',
);
await Root.exec(cmd: 'chmod 744 $scriptFilePath');
}
}