feat: sentry integration.

This commit is contained in:
Aunali321
2022-10-14 23:35:33 +05:30
parent 007b518503
commit f1261398e9
12 changed files with 329 additions and 186 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}
}