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

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/ui/views/installer/installer_viewmodel.dart';
@ -18,130 +17,89 @@ class InstallerView extends StatelessWidget {
disposeViewModel: false,
onModelReady: (model) => model.initialize(),
viewModelBuilder: () => locator<InstallerViewModel>(),
builder: (context, model, child) => WillStartForegroundTask(
onWillStart: () async => model.isPatching,
androidNotificationOptions: AndroidNotificationOptions(
channelId: 'revanced-patcher-patching',
channelName: 'Patching',
channelDescription: 'This notification appears when the patching '
'foreground service is running.',
channelImportance: NotificationChannelImportance.LOW,
priority: NotificationPriority.LOW,
),
notificationTitle: 'Patching',
notificationText: 'ReVanced Manager is patching',
callback: () => {},
child: WillPopScope(
child: Scaffold(
body: SafeArea(
child: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 12),
controller: _controller,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: constraints.maxWidth,
minHeight: constraints.maxHeight,
builder: (context, model, child) => WillPopScope(
child: Scaffold(
floatingActionButton: Visibility(
visible: model.showButtons,
child: FloatingActionButton.extended(
onPressed: () =>
model.isInstalled ? model.openApp() : model.installResult(),
label: I18nText(model.isInstalled
? 'installerView.fabOpenButton'
: 'installerView.fabInstallButton'),
icon: model.isInstalled
? const Icon(Icons.open_in_new)
: const Icon(Icons.install_mobile),
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Colors.white,
),
),
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 12),
controller: _controller,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
I18nText(
'installerView.widgetTitle',
child: Text(
'',
style: Theme.of(context).textTheme.headline5,
),
),
Visibility(
visible: model.showButtons,
child: IconButton(
icon: const Icon(Icons.share),
onPressed: () => model.shareResult(),
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 4.0,
),
child: IntrinsicHeight(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
I18nText(
'installerView.widgetTitle',
child: Text(
'',
style: Theme.of(context).textTheme.headline5,
),
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 4.0,
),
child: LinearProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
backgroundColor: Colors.white,
value: model.progress,
),
),
Container(
padding: const EdgeInsets.all(12.0),
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: SelectableText(
model.logs,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 15,
height: 1.5,
),
),
),
const Spacer(),
Visibility(
visible: model.showButtons,
child: Row(
children: [
Expanded(
child: MaterialButton(
textColor: Colors.white,
color:
Theme.of(context).colorScheme.secondary,
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 8,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
onPressed: () => model.installResult(),
child: I18nText(
'installerView.installButton',
),
),
),
const SizedBox(width: 12),
Expanded(
child: MaterialButton(
textColor: Colors.white,
color:
Theme.of(context).colorScheme.secondary,
padding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 8,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
onPressed: () => model.shareResult(),
child: I18nText(
'installerView.shareButton',
),
),
),
],
),
),
],
child: LinearProgressIndicator(
color: Theme.of(context).colorScheme.secondary,
backgroundColor: Colors.white,
value: model.progress,
),
),
Container(
padding: const EdgeInsets.all(12.0),
width: double.infinity,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(8),
),
child: SelectableText(
model.logs,
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 15,
height: 1.5,
),
),
),
),
],
),
),
),
onWillPop: () async {
if (!model.isPatching) {
model.cleanWorkplace();
Navigator.of(context).pop();
}
return false;
},
),
onWillPop: () async {
if (!model.isPatching) {
model.cleanWorkplace();
Navigator.of(context).pop();
}
return false;
},
),
);
}

View File

@ -1,3 +1,5 @@
import 'package:device_apps/device_apps.dart';
import 'package:flutter_background/flutter_background.dart';
import 'package:revanced_manager/app/app.locator.dart';
import 'package:revanced_manager/models/patch.dart';
import 'package:revanced_manager/models/patched_application.dart';
@ -11,9 +13,22 @@ class InstallerViewModel extends BaseViewModel {
double? progress = 0.2;
String logs = '';
bool isPatching = false;
bool isInstalled = false;
bool showButtons = false;
Future<void> initialize() async {
await FlutterBackground.initialize(
androidConfig: const FlutterBackgroundAndroidConfig(
notificationTitle: 'Patching',
notificationText: 'ReVanced Manager is patching',
notificationImportance: AndroidNotificationImportance.Default,
notificationIcon: AndroidResource(
name: 'ic_launcher_foreground',
defType: 'drawable',
),
),
);
await FlutterBackground.enableBackgroundExecution();
await locator<PatcherAPI>().handlePlatformChannelMethods();
runPatcher();
}
@ -28,6 +43,7 @@ class InstallerViewModel extends BaseViewModel {
void updateProgress(double value) {
progress = value;
isInstalled = false;
isPatching = progress == 1.0 ? false : true;
showButtons = progress == 1.0 ? true : false;
if (progress == 0.0) {
@ -46,6 +62,18 @@ class InstallerViewModel extends BaseViewModel {
locator<PatchesSelectorViewModel>().selectedPatches;
if (selectedPatches.isNotEmpty) {
addLog('Initializing installer...');
if (selectedApp.isRooted) {
addLog('Checking if an old patched version exists...');
bool oldExists =
await locator<PatcherAPI>().checkOldPatch(selectedApp);
addLog('Done');
if (oldExists) {
addLog('Deleting old patched version...');
await locator<PatcherAPI>().deleteOldPatch(selectedApp);
addLog('Done');
}
}
addLog('Creating working directory...');
bool? isSuccess = await locator<PatcherAPI>().initPatcher();
if (isSuccess != null && isSuccess) {
addLog('Done');
@ -108,6 +136,7 @@ class InstallerViewModel extends BaseViewModel {
} else {
addLog('No app selected! Aborting...');
}
await FlutterBackground.disableBackgroundExecution();
isPatching = false;
}
@ -118,9 +147,8 @@ class InstallerViewModel extends BaseViewModel {
addLog(selectedApp.isRooted
? 'Installing patched file using root method...'
: 'Installing patched file using nonroot method...');
bool isSucess =
await locator<PatcherAPI>().installPatchedFile(selectedApp);
if (isSucess) {
isInstalled = await locator<PatcherAPI>().installPatchedFile(selectedApp);
if (isInstalled) {
addLog('Done');
} else {
addLog('An error occurred! Aborting...');
@ -139,10 +167,18 @@ class InstallerViewModel extends BaseViewModel {
}
}
void cleanWorkplace() {
Future<void> cleanWorkplace() async {
locator<PatcherAPI>().cleanPatcher();
locator<AppSelectorViewModel>().selectedApp = null;
locator<PatchesSelectorViewModel>().selectedPatches.clear();
locator<PatcherViewModel>().notifyListeners();
}
void openApp() {
PatchedApplication? selectedApp =
locator<AppSelectorViewModel>().selectedApp;
if (selectedApp != null) {
DeviceApps.openApp(selectedApp.packageName);
}
}
}

View File

@ -25,11 +25,13 @@ class PatchesSelectorViewModel extends BaseViewModel {
void selectPatches(List<PatchItem> patchItems) {
selectedPatches.clear();
if (patches != null) {
for (PatchItem patch in patchItems) {
if (patch.isSelected) {
selectedPatches.add(
patches!.firstWhere((element) => element.name == patch.name),
);
for (PatchItem item in patchItems) {
if (item.isSelected) {
Patch patch =
patches!.firstWhere((element) => element.name == item.name);
if (!selectedPatches.contains(patch)) {
selectedPatches.add(patch);
}
}
}
}