mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-10-30 21:13:28 +01:00 
			
		
		
		
	Various bugfixes
This commit is contained in:
		| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user