mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
feat: sentry integration.
This commit is contained in:
parent
007b518503
commit
f1261398e9
12 changed files with 329 additions and 186 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -136,3 +136,8 @@ app.*.map.json
|
|||
|
||||
Firebase related
|
||||
.firebase
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
lib\utils\env_class.g.dart
|
||||
/lib/utils/env_class.dart
|
|
@ -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(
|
||||
|
|
|
@ -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<GithubAPI>().initialize();
|
||||
await locator<PatcherAPI>().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 {
|
||||
|
|
|
@ -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<void> clearAllCache() async {
|
||||
await _dioCacheManager.clearAll();
|
||||
try {
|
||||
await _dioCacheManager.clearAll();
|
||||
} on Exception catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>?> _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<dynamic> 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;
|
||||
|
|
|
@ -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<Map<String, List<dynamic>>> getContributors() async {
|
||||
|
@ -126,35 +131,50 @@ class ManagerAPI {
|
|||
}
|
||||
|
||||
Future<List<Patch>> 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<File?> 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<File?> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<void> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<void> 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<void> clearAllCache() async {
|
||||
await _dioCacheManager.clearAll();
|
||||
try {
|
||||
await _dioCacheManager.clearAll();
|
||||
} on Exception catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, List<dynamic>>> 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<dynamic> 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<PatcherViewModel>().notifyListeners();
|
||||
}
|
||||
}
|
||||
} on Exception {
|
||||
} on Exception catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
_toast.show('appSelectorView.errorMessage');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<void> 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: <Widget>[
|
||||
CustomMaterialButton(
|
||||
label: I18nText('okButton'),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
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<void> cleanPatcher() async {
|
||||
_patcherAPI.cleanPatcher();
|
||||
locator<PatcherViewModel>().selectedApp = null;
|
||||
locator<PatcherViewModel>().selectedPatches.clear();
|
||||
locator<PatcherViewModel>().notifyListeners();
|
||||
try {
|
||||
_patcherAPI.cleanPatcher();
|
||||
locator<PatcherViewModel>().selectedApp = null;
|
||||
locator<PatcherViewModel>().selectedPatches.clear();
|
||||
locator<PatcherViewModel>().notifyListeners();
|
||||
} on Exception catch (e, s) {
|
||||
await Sentry.captureException(e, stackTrace: s);
|
||||
}
|
||||
}
|
||||
|
||||
void openApp() {
|
||||
|
|
10
pubspec.yaml
10
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
|
||||
|
|
Loading…
Reference in a new issue