Various bugfixes

This commit is contained in:
Imran Remtulla
2024-05-17 15:56:41 -04:00
parent fbfeaf2a91
commit 389aebe54e

View File

@@ -820,22 +820,82 @@ class AppsProvider with ChangeNotifier {
appsToInstall =
moveStrToEnd(appsToInstall, obtainiumId, strB: obtainiumTempId);
Future<String> updateFn(String id, {bool skipInstalls = false}) async {
Future<void> installFn(String id, bool willBeSilent,
DownloadedApk? downloadedFile, DownloadedXApkDir? downloadedDir) async {
apps[id]?.downloadProgress = -1;
notifyListeners();
try {
bool sayInstalled = true;
var contextIfNewInstall =
apps[id]?.installedInfo == null ? context : null;
bool needBGWorkaround =
willBeSilent && context == null && !settingsProvider.useShizuku;
if (downloadedFile != null) {
if (needBGWorkaround) {
// ignore: use_build_context_synchronously
installApk(downloadedFile, contextIfNewInstall,
needsBGWorkaround: true);
} else {
// ignore: use_build_context_synchronously
sayInstalled = await installApk(downloadedFile, contextIfNewInstall,
shizukuPretendToBeGooglePlay: apps[id]!
.app
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true);
}
} else {
if (needBGWorkaround) {
// ignore: use_build_context_synchronously
installXApkDir(downloadedDir!, contextIfNewInstall,
needsBGWorkaround: true);
} else {
// ignore: use_build_context_synchronously
sayInstalled = await installXApkDir(
downloadedDir!, contextIfNewInstall,
shizukuPretendToBeGooglePlay: apps[id]!
.app
.additionalSettings['shizukuPretendToBeGooglePlay'] ==
true);
}
}
if (willBeSilent && context == null) {
if (!settingsProvider.useShizuku) {
notificationsProvider?.notify(SilentUpdateAttemptNotification(
[apps[id]!.app],
id: id.hashCode));
} else {
notificationsProvider?.notify(SilentUpdateNotification(
[apps[id]!.app], sayInstalled,
id: id.hashCode));
}
}
if (sayInstalled) {
installedIds.add(id);
}
} finally {
apps[id]?.downloadProgress = null;
notifyListeners();
}
}
Future<Map<Object?, Object?>> downloadFn(String id,
{bool skipInstalls = false}) async {
bool willBeSilent = false;
DownloadedApk? downloadedFile;
DownloadedXApkDir? downloadedDir;
try {
var downloadedArtifact =
// ignore: use_build_context_synchronously
await downloadApp(apps[id]!.app, context,
notificationsProvider: notificationsProvider,
useExisting: useExisting);
DownloadedApk? downloadedFile;
DownloadedXApkDir? downloadedDir;
if (downloadedArtifact is DownloadedApk) {
downloadedFile = downloadedArtifact;
} else {
downloadedDir = downloadedArtifact as DownloadedXApkDir;
}
id = downloadedFile?.appId ?? downloadedDir!.appId;
bool willBeSilent = await canInstallSilently(apps[id]!.app);
willBeSilent = await canInstallSilently(apps[id]!.app);
if (!settingsProvider.useShizuku) {
if (!(await settingsProvider.getInstallPermission(enforce: false))) {
throw ObtainiumError(tr('cancelled'));
@@ -856,80 +916,33 @@ class AppsProvider with ChangeNotifier {
// ignore: use_build_context_synchronously
await waitForUserToReturnToForeground(context);
}
apps[id]?.downloadProgress = -1;
notifyListeners();
try {
if (!skipInstalls) {
bool sayInstalled = true;
var contextIfNewInstall =
apps[id]?.installedInfo == null ? context : null;
bool needBGWorkaround =
willBeSilent && context == null && !settingsProvider.useShizuku;
if (downloadedFile != null) {
if (needBGWorkaround) {
// ignore: use_build_context_synchronously
installApk(downloadedFile, contextIfNewInstall,
needsBGWorkaround: true);
} else {
// ignore: use_build_context_synchronously
sayInstalled = await installApk(
downloadedFile, contextIfNewInstall,
shizukuPretendToBeGooglePlay:
apps[id]!.app.additionalSettings[
'shizukuPretendToBeGooglePlay'] ==
true);
}
} else {
if (needBGWorkaround) {
// ignore: use_build_context_synchronously
installXApkDir(downloadedDir!, contextIfNewInstall,
needsBGWorkaround: true);
} else {
// ignore: use_build_context_synchronously
sayInstalled = await installXApkDir(
downloadedDir!, contextIfNewInstall,
shizukuPretendToBeGooglePlay:
apps[id]!.app.additionalSettings[
'shizukuPretendToBeGooglePlay'] ==
true);
}
}
if (willBeSilent && context == null) {
if (!settingsProvider.useShizuku) {
notificationsProvider?.notify(SilentUpdateAttemptNotification(
[apps[id]!.app],
id: id.hashCode));
} else {
notificationsProvider?.notify(SilentUpdateNotification(
[apps[id]!.app], sayInstalled,
id: id.hashCode));
}
}
if (sayInstalled) {
installedIds.add(id);
}
}
} finally {
apps[id]?.downloadProgress = null;
notifyListeners();
}
} catch (e) {
errors.add(id, e, appName: apps[id]?.name);
}
return id;
return {
'id': id,
'willBeSilent': willBeSilent,
'downloadedFile': downloadedFile,
'downloadedDir': downloadedDir
};
}
List<Map<Object?, Object?>> downloadResults = [];
if (forceParallelDownloads || !settingsProvider.parallelDownloads) {
for (var id in appsToInstall) {
await updateFn(id);
downloadResults.add(await downloadFn(id));
}
} else {
List<String> ids = await Future.wait(
appsToInstall.map((id) => updateFn(id, skipInstalls: true)));
for (var id in ids) {
if (!errors.appIdNames.containsKey(id)) {
await updateFn(id);
}
downloadResults = await Future.wait(
appsToInstall.map((id) => downloadFn(id, skipInstalls: true)));
}
for (var res in downloadResults) {
if (!errors.appIdNames.containsKey(res['id'])) {
await installFn(
res['id'] as String,
res['willBeSilent'] as bool,
res['downloadedFile'] as DownloadedApk?,
res['downloadedDir'] as DownloadedXApkDir?);
}
}
@@ -1166,40 +1179,38 @@ class AppsProvider with ChangeNotifier {
notifyListeners();
var sp = SourceProvider();
List<List<String>> errors = [];
List<App?> newApps = (await getAppsDir()) // Parse Apps from JSON
await Future.wait((await getAppsDir()) // Parse Apps from JSON
.listSync()
.where((item) => item.path.toLowerCase().endsWith('.json'))
.where((item) =>
singleId == null ||
item.path.split('/').last.toLowerCase() ==
'${singleId.toLowerCase()}.json')
.map((e) {
try {
return App.fromJson(jsonDecode(File(e.path).readAsStringSync()));
} catch (err) {
if (err is FormatException) {
logs.add('Corrupt JSON when loading App (will be ignored): $e');
e.renameSync('${e.path}.corrupt');
} else {
rethrow;
.map((item) async {
App? app;
if (item.path.toLowerCase().endsWith('.json') &&
(singleId == null ||
item.path.split('/').last.toLowerCase() ==
'${singleId.toLowerCase()}.json')) {
try {
app = App.fromJson(jsonDecode(File(item.path).readAsStringSync()));
} catch (err) {
if (err is FormatException) {
logs.add('Corrupt JSON when loading App (will be ignored): $e');
item.renameSync('${item.path}.corrupt');
} else {
rethrow;
}
}
}
}).toList();
for (var app in newApps) {
// Put Apps into memory to list them (fast)
if (app != null) {
try {
sp.getSource(app.url, overrideSource: app.overrideSource);
apps.update(
app.id,
(value) => AppInMemory(
app, value.downloadProgress, value.installedInfo, value.icon),
ifAbsent: () => AppInMemory(app, null, null, null));
(value) => AppInMemory(app!, value.downloadProgress,
value.installedInfo, value.icon),
ifAbsent: () => AppInMemory(app!, null, null, null));
} catch (e) {
errors.add([app.id, app.finalName, e.toString()]);
}
}
}
}));
notifyListeners();
if (errors.isNotEmpty) {
removeApps(errors.map((e) => e[0]).toList());
@@ -1207,19 +1218,17 @@ class AppsProvider with ChangeNotifier {
AppsRemovedNotification(errors.map((e) => [e[1], e[2]]).toList()));
}
// Get install status and other OS info for each App (slow)
await Future.wait(apps.values.map((app) {
return updateInstallStatusInMemory(app);
}));
notifyListeners();
// Reconcile version differences
List<App> modifiedApps = [];
for (var app in apps.values) {
await Future.wait(apps.values.map((app) async {
await updateInstallStatusInMemory(app);
var moddedApp =
getCorrectedInstallStatusAppIfPossible(app.app, app.installedInfo);
if (moddedApp != null) {
modifiedApps.add(moddedApp);
}
}
}));
notifyListeners();
// Reconcile version differences
if (modifiedApps.isNotEmpty) {
await saveApps(modifiedApps, attemptToCorrectInstallStatus: false);
var removedAppIds = modifiedApps
@@ -1241,7 +1250,7 @@ class AppsProvider with ChangeNotifier {
{bool attemptToCorrectInstallStatus = true,
bool onlyIfExists = true}) async {
attemptToCorrectInstallStatus = attemptToCorrectInstallStatus;
for (var a in apps) {
await Future.wait(apps.map((a) async {
var app = a.deepCopy();
PackageInfo? info = await getInstalledInfo(app.id);
var icon = await info?.applicationInfo?.getAppIcon();
@@ -1263,14 +1272,14 @@ class AppsProvider with ChangeNotifier {
rethrow;
}
}
}
}));
notifyListeners();
export(isAuto: true);
}
Future<void> removeApps(List<String> appIds) async {
var apkFiles = APKDir.listSync();
for (var appId in appIds) {
await Future.wait(appIds.map((appId) async {
File file = File('${(await getAppsDir()).path}/$appId.json');
if (file.existsSync()) {
file.deleteSync(recursive: true);
@@ -1284,7 +1293,7 @@ class AppsProvider with ChangeNotifier {
if (apps.containsKey(appId)) {
apps.remove(appId);
}
}
}));
if (appIds.isNotEmpty) {
notifyListeners();
export(isAuto: true);
@@ -1543,6 +1552,8 @@ class AppsProvider with ChangeNotifier {
settingsMap.forEach((key, value) {
if (value is int) {
settingsProvider.prefs?.setInt(key, value);
} else if (value is double) {
settingsProvider.prefs?.setDouble(key, value);
} else if (value is bool) {
settingsProvider.prefs?.setBool(key, value);
} else if (value is List) {