mirror of
				https://github.com/ImranR98/Obtainium.git
				synced 2025-11-03 23:03:29 +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