From f1261398e927903f6c75c44f5d03fdff562bda47 Mon Sep 17 00:00:00 2001 From: Aunali321 Date: Fri, 14 Oct 2022 23:35:33 +0530 Subject: [PATCH] feat: sentry integration. --- .gitignore | 5 + .../revanced/manager/flutter/MainActivity.kt | 11 +- lib/main.dart | 16 +- lib/services/github_api.dart | 53 ++++-- lib/services/manager_api.dart | 68 ++++--- lib/services/patcher_api.dart | 92 +++++---- lib/services/revanced_api.dart | 59 ++++-- lib/services/root_api.dart | 13 +- .../app_selector/app_selector_viewmodel.dart | 4 +- lib/ui/views/home/home_viewmodel.dart | 7 +- .../views/installer/installer_viewmodel.dart | 177 ++++++++++-------- pubspec.yaml | 10 +- 12 files changed, 329 insertions(+), 186 deletions(-) diff --git a/.gitignore b/.gitignore index a78395b8..0bdfcfd0 100644 --- a/.gitignore +++ b/.gitignore @@ -136,3 +136,8 @@ app.*.map.json Firebase related .firebase + +# Environment variables +.env +lib\utils\env_class.g.dart +/lib/utils/env_class.dart \ No newline at end of file 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 0a186a39..2d76f9fd 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 @@ -241,7 +241,16 @@ class MainActivity : FlutterActivity() { ) ) } - Signer("ReVanced", "s3cur3p@ssw0rd").signApk(patchedFile, outFile, keyStoreFile) + + // Signer("ReVanced", "s3cur3p@ssw0rd").signApk(patchedFile, outFile, keyStoreFile) + + try { + Signer("ReVanced", "s3cur3p@ssw0rd").signApk(patchedFile, outFile, keyStoreFile) + } catch (e: Exception) { + //log to console + print("Error signing apk: ${e.message}") + e.printStackTrace() + } handler.post { installerChannel.invokeMethod( diff --git a/lib/main.dart b/lib/main.dart index f02c9c9b..7cceb665 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,7 +8,9 @@ import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/services/revanced_api.dart'; import 'package:revanced_manager/ui/theme/dynamic_theme_builder.dart'; import 'package:revanced_manager/ui/views/navigation/navigation_view.dart'; +import 'package:revanced_manager/utils/env_class.dart'; import 'package:stacked_themes/stacked_themes.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:timezone/data/latest.dart' as tz; Future main() async { @@ -21,7 +23,19 @@ Future main() async { locator().initialize(); await locator().initialize(); tz.initializeTimeZones(); - runApp(const MyApp()); + await SentryFlutter.init( + (options) { + options + ..dsn = Env.SENTRY_DSN + ..environment = 'alpha' + ..release = '0.1' + ..tracesSampleRate = 1.0 + ..anrEnabled = true + ..enableOutOfMemoryTracking = true + ..sampleRate = 1.0; + }, + appRunner: () => runApp(const MyApp()), + ); } class MyApp extends StatelessWidget { diff --git a/lib/services/github_api.dart b/lib/services/github_api.dart index fbdbbc77..7a3fa3bf 100644 --- a/lib/services/github_api.dart +++ b/lib/services/github_api.dart @@ -8,6 +8,8 @@ import 'package:injectable/injectable.dart'; import 'package:native_dio_client/native_dio_client.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/utils/check_for_gms.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_dio/sentry_dio.dart'; @lazySingleton class GithubAPI { @@ -29,25 +31,36 @@ class GithubAPI { }; void initialize() async { - bool isGMSInstalled = await checkForGMS(); + try { + bool isGMSInstalled = await checkForGMS(); - if (!isGMSInstalled) { - _dio = Dio(BaseOptions( - baseUrl: 'https://api.github.com', - )); - print('GitHub API: Using default engine + $isGMSInstalled'); - } else { - _dio = Dio(BaseOptions( - baseUrl: 'https://api.github.com', - )) - ..httpClientAdapter = NativeAdapter(); - print('ReVanced API: Using CronetEngine + $isGMSInstalled'); + if (!isGMSInstalled) { + _dio = Dio(BaseOptions( + baseUrl: 'https://api.github.com', + )); + print('GitHub API: Using default engine + $isGMSInstalled'); + } else { + _dio = Dio(BaseOptions( + baseUrl: 'https://api.github.com', + )) + ..httpClientAdapter = NativeAdapter(); + print('ReVanced API: Using CronetEngine + $isGMSInstalled'); + } + _dio.interceptors.add(_dioCacheManager.interceptor); + _dio.addSentry( + captureFailedRequests: true, + ); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); } - _dio.interceptors.add(_dioCacheManager.interceptor); } Future clearAllCache() async { - await _dioCacheManager.clearAll(); + try { + await _dioCacheManager.clearAll(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + } } Future?> _getLatestRelease(String repoName) async { @@ -57,7 +70,8 @@ class GithubAPI { options: _cacheOptions, ); return response.data; - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } } @@ -87,7 +101,8 @@ class GithubAPI { '\n' as String, ) .toList(); - } catch (e) { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return List.empty(); } } @@ -106,7 +121,8 @@ class GithubAPI { ); } } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } return null; @@ -120,7 +136,8 @@ class GithubAPI { List list = jsonDecode(f.readAsStringSync()); patches = list.map((patch) => Patch.fromJson(patch)).toList(); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return List.empty(); } return patches; diff --git a/lib/services/manager_api.dart b/lib/services/manager_api.dart index 4bfae93a..d12a71e6 100644 --- a/lib/services/manager_api.dart +++ b/lib/services/manager_api.dart @@ -9,6 +9,7 @@ import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/github_api.dart'; import 'package:revanced_manager/services/revanced_api.dart'; import 'package:revanced_manager/services/root_api.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; @lazySingleton @@ -116,9 +117,13 @@ class ManagerAPI { await setPatchedApps(patchedApps); } - void clearAllData() { - _revancedAPI.clearAllCache(); - _githubAPI.clearAllCache(); + void clearAllData() async { + try { + _revancedAPI.clearAllCache(); + _githubAPI.clearAllCache(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + } } Future>> getContributors() async { @@ -126,35 +131,50 @@ class ManagerAPI { } Future> getPatches() async { - String repoName = getPatchesRepo(); - if (repoName == defaultPatchesRepo) { - return await _revancedAPI.getPatches(); - } else { - return await _githubAPI.getPatches(repoName); + try { + String repoName = getPatchesRepo(); + if (repoName == defaultPatchesRepo) { + return await _revancedAPI.getPatches(); + } else { + return await _githubAPI.getPatches(repoName); + } + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + return []; } } Future downloadPatches() async { - String repoName = getPatchesRepo(); - if (repoName == defaultPatchesRepo) { - return await _revancedAPI.getLatestReleaseFile( - '.jar', - defaultPatchesRepo, - ); - } else { - return await _githubAPI.getLatestReleaseFile('.jar', repoName); + try { + String repoName = getPatchesRepo(); + if (repoName == defaultPatchesRepo) { + return await _revancedAPI.getLatestReleaseFile( + '.jar', + defaultPatchesRepo, + ); + } else { + return await _githubAPI.getLatestReleaseFile('.jar', repoName); + } + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + return null; } } Future downloadIntegrations() async { - String repoName = getIntegrationsRepo(); - if (repoName == defaultIntegrationsRepo) { - return await _revancedAPI.getLatestReleaseFile( - '.apk', - defaultIntegrationsRepo, - ); - } else { - return await _githubAPI.getLatestReleaseFile('.apk', repoName); + try { + String repoName = getIntegrationsRepo(); + if (repoName == defaultIntegrationsRepo) { + return await _revancedAPI.getLatestReleaseFile( + '.apk', + defaultIntegrationsRepo, + ); + } else { + return await _githubAPI.getLatestReleaseFile('.apk', repoName); + } + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + return null; } } diff --git a/lib/services/patcher_api.dart b/lib/services/patcher_api.dart index 53a8b5fb..31ad0cd4 100644 --- a/lib/services/patcher_api.dart +++ b/lib/services/patcher_api.dart @@ -10,6 +10,7 @@ import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/manager_api.dart'; import 'package:revanced_manager/services/root_api.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:share_extend/share_extend.dart'; @lazySingleton @@ -44,7 +45,8 @@ class PatcherAPI { if (_patches.isEmpty) { _patches = await _managerAPI.getPatches(); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); _patches = List.empty(); } } @@ -63,7 +65,8 @@ class PatcherAPI { filteredApps.add(app); } } - } catch (e) { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); continue; } } @@ -124,14 +127,19 @@ class PatcherAPI { String packageName, String originalFilePath, ) async { - bool hasRootPermissions = await _rootAPI.hasRootPermissions(); - if (hasRootPermissions) { - originalFilePath = await _rootAPI.getOriginalFilePath( - packageName, - originalFilePath, - ); + try { + bool hasRootPermissions = await _rootAPI.hasRootPermissions(); + if (hasRootPermissions) { + originalFilePath = await _rootAPI.getOriginalFilePath( + packageName, + originalFilePath, + ); + } + return originalFilePath; + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + return originalFilePath; } - return originalFilePath; } Future runPatcher( @@ -151,7 +159,8 @@ class PatcherAPI { if (settingsPatch != null) { selectedPatches.add(settingsPatch); } - } catch (e) { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); // ignore } } @@ -169,24 +178,29 @@ class PatcherAPI { _outFile = File('${workDir.path}/out.apk'); Directory cacheDir = Directory('${workDir.path}/cache'); cacheDir.createSync(); - await patcherChannel.invokeMethod( - 'runPatcher', - { - 'patchBundleFilePath': patchBundleFile.path, - 'originalFilePath': await getOriginalFilePath( - packageName, - originalFilePath, - ), - 'inputFilePath': inputFile.path, - 'patchedFilePath': patchedFile.path, - 'outFilePath': _outFile!.path, - 'integrationsPath': mergeIntegrations ? integrationsFile!.path : '', - 'selectedPatches': selectedPatches.map((p) => p.name).toList(), - 'cacheDirPath': cacheDir.path, - 'mergeIntegrations': mergeIntegrations, - 'keyStoreFilePath': _keyStoreFile.path, - }, - ); + try { + await patcherChannel.invokeMethod( + 'runPatcher', + { + 'patchBundleFilePath': patchBundleFile.path, + 'originalFilePath': await getOriginalFilePath( + packageName, + originalFilePath, + ), + 'inputFilePath': inputFile.path, + 'patchedFilePath': patchedFile.path, + 'outFilePath': _outFile!.path, + 'integrationsPath': mergeIntegrations ? integrationsFile!.path : '', + 'selectedPatches': selectedPatches.map((p) => p.name).toList(), + 'cacheDirPath': cacheDir.path, + 'mergeIntegrations': mergeIntegrations, + 'keyStoreFilePath': _keyStoreFile.path, + }, + ); + } on Exception catch (e, s) { + print(e); + throw await Sentry.captureException(e, stackTrace: s); + } } } @@ -206,7 +220,8 @@ class PatcherAPI { await AppInstaller.installApk(_outFile!.path); return await DeviceApps.isAppInstalled(patchedApp.packageName); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return false; } } @@ -214,13 +229,18 @@ class PatcherAPI { } void sharePatchedFile(String appName, String version) { - if (_outFile != null) { - String prefix = appName.toLowerCase().replaceAll(' ', '-'); - String newName = '$prefix-revanced_v$version.apk'; - int lastSeparator = _outFile!.path.lastIndexOf('/'); - String newPath = _outFile!.path.substring(0, lastSeparator + 1) + newName; - File shareFile = _outFile!.copySync(newPath); - ShareExtend.share(shareFile.path, 'file'); + try { + if (_outFile != null) { + String prefix = appName.toLowerCase().replaceAll(' ', '-'); + String newName = '$prefix-revanced_v$version.apk'; + int lastSeparator = _outFile!.path.lastIndexOf('/'); + String newPath = + _outFile!.path.substring(0, lastSeparator + 1) + newName; + File shareFile = _outFile!.copySync(newPath); + ShareExtend.share(shareFile.path, 'file'); + } + } on Exception catch (e, s) { + Sentry.captureException(e, stackTrace: s); } } diff --git a/lib/services/revanced_api.dart b/lib/services/revanced_api.dart index 1eace1db..40794fc8 100644 --- a/lib/services/revanced_api.dart +++ b/lib/services/revanced_api.dart @@ -8,6 +8,8 @@ import 'package:injectable/injectable.dart'; import 'package:revanced_manager/models/patch.dart'; import 'package:revanced_manager/utils/check_for_gms.dart'; import 'package:timeago/timeago.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:sentry_dio/sentry_dio.dart'; @lazySingleton class RevancedAPI { @@ -19,25 +21,36 @@ class RevancedAPI { ); Future initialize(String apiUrl) async { - bool isGMSInstalled = await checkForGMS(); + try { + bool isGMSInstalled = await checkForGMS(); - if (!isGMSInstalled) { - _dio = Dio(BaseOptions( - baseUrl: apiUrl, - )); - print('ReVanced API: Using default engine + $isGMSInstalled'); - } else { - _dio = Dio(BaseOptions( - baseUrl: apiUrl, - )) - ..httpClientAdapter = NativeAdapter(); - print('ReVanced API: Using CronetEngine + $isGMSInstalled'); + if (!isGMSInstalled) { + _dio = Dio(BaseOptions( + baseUrl: apiUrl, + )); + print('ReVanced API: Using default engine + $isGMSInstalled'); + } else { + _dio = Dio(BaseOptions( + baseUrl: apiUrl, + )) + ..httpClientAdapter = NativeAdapter(); + print('ReVanced API: Using CronetEngine + $isGMSInstalled'); + } + _dio.interceptors.add(_dioCacheManager.interceptor); + _dio.addSentry( + captureFailedRequests: true, + ); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); } - _dio.interceptors.add(_dioCacheManager.interceptor); } Future clearAllCache() async { - await _dioCacheManager.clearAll(); + try { + await _dioCacheManager.clearAll(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + } } Future>> getContributors() async { @@ -49,7 +62,8 @@ class RevancedAPI { String name = repo['name']; contributors[name] = repo['contributors']; } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return {}; } return contributors; @@ -60,7 +74,8 @@ class RevancedAPI { var response = await _dio.get('/patches', options: _cacheOptions); List patches = response.data; return patches.map((patch) => Patch.fromJson(patch)).toList(); - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return List.empty(); } } @@ -77,7 +92,8 @@ class RevancedAPI { t['repository'] == repoName && (t['name'] as String).endsWith(extension), ); - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } } @@ -94,7 +110,8 @@ class RevancedAPI { if (release != null) { return release['version']; } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } return null; @@ -110,7 +127,8 @@ class RevancedAPI { String url = release['browser_download_url']; return await DefaultCacheManager().getSingleFile(url); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } return null; @@ -129,7 +147,8 @@ class RevancedAPI { DateTime timestamp = DateTime.parse(release['timestamp'] as String); return format(timestamp, locale: 'en_short'); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return null; } return null; diff --git a/lib/services/root_api.dart b/lib/services/root_api.dart index 7965a359..2e63d20f 100644 --- a/lib/services/root_api.dart +++ b/lib/services/root_api.dart @@ -1,4 +1,5 @@ import 'package:root/root.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; class RootAPI { final String _managerDirPath = '/data/local/tmp/revanced-manager'; @@ -9,7 +10,8 @@ class RootAPI { try { bool? isRooted = await Root.isRootAvailable(); return isRooted != null && isRooted; - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return false; } } @@ -22,7 +24,8 @@ class RootAPI { return isRooted != null && isRooted; } return false; - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return false; } } @@ -75,7 +78,8 @@ class RootAPI { apps.removeWhere((pack) => pack.isEmpty); return apps.map((pack) => pack.trim()).toList(); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return List.empty(); } return List.empty(); @@ -121,7 +125,8 @@ class RootAPI { await installApk(packageName, patchedFilePath); await mountApk(packageName, originalFilePath); return true; - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return false; } } diff --git a/lib/ui/views/app_selector/app_selector_viewmodel.dart b/lib/ui/views/app_selector/app_selector_viewmodel.dart index 69695a21..55403b8a 100644 --- a/lib/ui/views/app_selector/app_selector_viewmodel.dart +++ b/lib/ui/views/app_selector/app_selector_viewmodel.dart @@ -7,6 +7,7 @@ import 'package:revanced_manager/models/patched_application.dart'; import 'package:revanced_manager/services/patcher_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:stacked/stacked.dart'; class AppSelectorViewModel extends BaseViewModel { @@ -63,7 +64,8 @@ class AppSelectorViewModel extends BaseViewModel { locator().notifyListeners(); } } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); _toast.show('appSelectorView.errorMessage'); } } diff --git a/lib/ui/views/home/home_viewmodel.dart b/lib/ui/views/home/home_viewmodel.dart index e28c864f..d2190f5d 100644 --- a/lib/ui/views/home/home_viewmodel.dart +++ b/lib/ui/views/home/home_viewmodel.dart @@ -16,6 +16,7 @@ import 'package:revanced_manager/services/toast.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:sentry_flutter/sentry_flutter.dart'; import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; import 'package:timezone/timezone.dart' as tz; @@ -94,7 +95,8 @@ class HomeViewModel extends BaseViewModel { int currentVersionInt = int.parse(currentVersion.replaceAll(RegExp('[^0-9]'), '')); return latestVersionInt > currentVersionInt; - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); return false; } } @@ -135,7 +137,8 @@ class HomeViewModel extends BaseViewModel { } else { _toast.show('homeView.errorDownloadMessage'); } - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); _toast.show('homeView.errorInstallMessage'); } } diff --git a/lib/ui/views/installer/installer_viewmodel.dart b/lib/ui/views/installer/installer_viewmodel.dart index d355600b..17d1fb86 100644 --- a/lib/ui/views/installer/installer_viewmodel.dart +++ b/lib/ui/views/installer/installer_viewmodel.dart @@ -14,6 +14,7 @@ import 'package:revanced_manager/services/root_api.dart'; import 'package:revanced_manager/services/toast.dart'; import 'package:revanced_manager/ui/views/patcher/patcher_viewmodel.dart'; import 'package:revanced_manager/ui/widgets/shared/custom_material_button.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:stacked/stacked.dart'; import 'package:wakelock/wakelock.dart'; @@ -57,7 +58,8 @@ class InstallerViewModel extends BaseViewModel { ), ), ).then((value) => FlutterBackground.enableBackgroundExecution()); - } on Exception { + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); // ignore } } @@ -121,91 +123,108 @@ class InstallerViewModel extends BaseViewModel { } Future runPatcher() async { - update(0.0, 'Initializing...', 'Initializing installer'); - if (_patches.isNotEmpty) { - try { - update(0.1, '', 'Creating working directory'); - await _patcherAPI.runPatcher( - _app.packageName, - _app.apkFilePath, - _patches, - ); - } catch (e) { - update( - -100.0, - 'Aborting...', - 'An error occurred! Aborting\nError:\n$e', - ); + try { + update(0.0, 'Initializing...', 'Initializing installer'); + if (_patches.isNotEmpty) { + try { + update(0.1, '', 'Creating working directory'); + await _patcherAPI.runPatcher( + _app.packageName, + _app.apkFilePath, + _patches, + ); + } on Exception catch (e, s) { + update( + -100.0, + 'Aborting...', + 'An error occurred! Aborting\nError:\n$e', + ); + await Sentry.captureException(e, stackTrace: s); + throw await Sentry.captureException(e, stackTrace: s); + } + } else { + update(-100.0, 'Aborting...', 'No app or patches selected! Aborting'); } - } else { - update(-100.0, 'Aborting...', 'No app or patches selected! Aborting'); - } - if (FlutterBackground.isBackgroundExecutionEnabled) { - try { - FlutterBackground.disableBackgroundExecution(); - } on Exception { - // ignore + if (FlutterBackground.isBackgroundExecutionEnabled) { + try { + FlutterBackground.disableBackgroundExecution(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + // ignore + } } + await Wakelock.disable(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); } - await Wakelock.disable(); } void installResult(BuildContext context, bool installAsRoot) async { - _app.isRooted = installAsRoot; - bool hasMicroG = _patches.any((p) => p.name.endsWith('microg-support')); - bool rootMicroG = installAsRoot && hasMicroG; - bool rootFromStorage = installAsRoot && _app.isFromStorage; - 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', + try { + _app.isRooted = installAsRoot; + bool hasMicroG = _patches.any((p) => p.name.endsWith('microg-support')); + bool rootMicroG = installAsRoot && hasMicroG; + bool rootFromStorage = installAsRoot && _app.isFromStorage; + 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(), + ) + ], ), - actions: [ - CustomMaterialButton( - label: I18nText('okButton'), - onPressed: () => Navigator.of(context).pop(), - ) - ], - ), - ); - } else { - update( - 1.0, - 'Installing...', - _app.isRooted - ? 'Installing patched file using root method' - : 'Installing patched file using nonroot method', - ); - 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(); - if (hasMicroG) { - _app.name += ' ReVanced'; - _app.packageName = _app.packageName.replaceFirst( - 'com.google.', - 'app.revanced.', - ); + ); + } else { + update( + 1.0, + 'Installing...', + _app.isRooted + ? 'Installing patched file using root method' + : 'Installing patched file using nonroot method', + ); + 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(); + if (hasMicroG) { + _app.name += ' ReVanced'; + _app.packageName = _app.packageName.replaceFirst( + 'com.google.', + 'app.revanced.', + ); + } + await _managerAPI.savePatchedApp(_app); } - await _managerAPI.savePatchedApp(_app); } + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); } } void shareResult() { - _patcherAPI.sharePatchedFile(_app.name, _app.version); + try { + if (isInstalled) { + _patcherAPI.sharePatchedFile(_app.name, _app.version); + } + } on Exception catch (e, s) { + Sentry.captureException(e, stackTrace: s); + } } void shareLog() { @@ -213,10 +232,14 @@ class InstallerViewModel extends BaseViewModel { } Future cleanPatcher() async { - _patcherAPI.cleanPatcher(); - locator().selectedApp = null; - locator().selectedPatches.clear(); - locator().notifyListeners(); + try { + _patcherAPI.cleanPatcher(); + locator().selectedApp = null; + locator().selectedPatches.clear(); + locator().notifyListeners(); + } on Exception catch (e, s) { + await Sentry.captureException(e, stackTrace: s); + } } void openApp() { diff --git a/pubspec.yaml b/pubspec.yaml index 7ad397f5..8c64f7c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,6 +10,7 @@ environment: sdk: ">=2.17.5 <3.0.0" dependencies: + sentry_flutter: ^6.12.2 animations: ^2.0.4 app_installer: ^1.1.0 collection: ^1.16.0 @@ -71,15 +72,20 @@ dependencies: timezone: ^0.8.0 url_launcher: ^6.1.5 wakelock: ^0.6.2 + sentry_dio: ^6.12.2 + envied: ^0.2.3 dev_dependencies: + json_serializable: ^6.3.1 build_runner: any flutter_launcher_icons: ^0.10.0 flutter_lints: ^2.0.1 flutter_test: sdk: flutter - injectable_generator: ^1.5.4 - json_serializable: ^6.3.1 + injectable_generator: ^1.5.4 + envied_generator: ^0.2.3 + + flutter: uses-material-design: true