diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails.java b/app/src/main/java/org/fdroid/fdroid/AppDetails.java index dc8c00e9c..15e0539e4 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails.java @@ -432,6 +432,12 @@ public class AppDetails extends AppCompatActivity { myAppObserver); } + @Override + protected void onResume() { + super.onResume(); + updateNotificationsForApp(); + } + @Override protected void onResumeFragments() { // Must be called before super.onResumeFragments(), as the fragments depend on the active @@ -462,13 +468,34 @@ public class AppDetails extends AppCompatActivity { protected void onStop() { super.onStop(); + visiblePackageName = null; getContentResolver().unregisterContentObserver(myAppObserver); + + // When leaving the app details, make sure to refresh app status for this app, since + // we might want to show notifications for it now. + updateNotificationsForApp(); + } + + /** + * Some notifications (like "downloading" and "installed") are not shown for this app if it is open in app details. + * When closing, we need to refresh the notifications, so they are displayed again. + */ + private void updateNotificationsForApp() { + if (app != null) { + AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this); + for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) { + if (status.status == AppUpdateStatusManager.Status.Installed) { + appUpdateStatusManager.removeApk(status.getUniqueKey()); + } else { + appUpdateStatusManager.refreshApk(status.getUniqueKey()); + } + } + } } @Override protected void onPause() { super.onPause(); - visiblePackageName = null; // save the active URL for this app in case we come back getPreferences(MODE_PRIVATE) .edit() @@ -554,7 +581,7 @@ public class AppDetails extends AppCompatActivity { String errorMessage = intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); - if (!TextUtils.isEmpty(errorMessage)) { + if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) { Log.e(TAG, "install aborted with errorMessage: " + errorMessage); String title = String.format( @@ -701,14 +728,6 @@ public class AppDetails extends AppCompatActivity { app = newApp; startingPrefs = app.getPrefs(this).createClone(); - - // Remove all "installed" statuses for this app, since we are now viewing it. - AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this); - for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) { - if (status.status == AppUpdateStatusManager.Status.Installed) { - appUpdateStatusManager.removeApk(status.getUniqueKey()); - } - } } private void refreshApkList() { diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java index 317f21084..d1c395d65 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java @@ -64,6 +64,16 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog private LocalBroadcastManager localBroadcastManager; private String activeDownloadUrlString; + /** + * Check if {@code packageName} is currently visible to the user. + */ + public static boolean isAppVisible(String packageName) { + return packageName != null && packageName.equals(visiblePackageName); + } + + private static String visiblePackageName; + + @Override protected void onCreate(Bundle savedInstanceState) { fdroidApp = (FDroidApp) getApplication(); @@ -131,6 +141,41 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog } } + /** + * Some notifications (like "downloading" and "installed") are not shown for this app if it is open in app details. + * When closing, we need to refresh the notifications, so they are displayed again. + */ + private void updateNotificationsForApp() { + if (app != null) { + AppUpdateStatusManager appUpdateStatusManager = AppUpdateStatusManager.getInstance(this); + for (AppUpdateStatusManager.AppUpdateStatus status : appUpdateStatusManager.getByPackageName(app.packageName)) { + if (status.status == AppUpdateStatusManager.Status.Installed) { + appUpdateStatusManager.removeApk(status.getUniqueKey()); + } else { + appUpdateStatusManager.refreshApk(status.getUniqueKey()); + } + } + } + } + + @Override + protected void onResume() { + super.onResume(); + if (app != null) { + visiblePackageName = app.packageName; + } + updateNotificationsForApp(); + } + + protected void onStop() { + super.onStop(); + visiblePackageName = null; + + // When leaving the app details, make sure to refresh app status for this app, since + // we might want to show notifications for it now. + updateNotificationsForApp(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { boolean ret = super.onCreateOptionsMenu(menu); @@ -372,7 +417,7 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog String errorMessage = intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); - if (!TextUtils.isEmpty(errorMessage)) { + if (!TextUtils.isEmpty(errorMessage) && !isFinishing()) { Log.e(TAG, "install aborted with errorMessage: " + errorMessage); String title = String.format( diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index 0ea683021..92ad49a82 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -237,6 +237,16 @@ public class AppUpdateStatusManager { } } + public void refreshApk(String key) { + synchronized (appMapping) { + AppUpdateStatus entry = appMapping.get(key); + if (entry != null) { + Utils.debugLog(LOGTAG, "Refresh APK " + entry.apk.apkName); + notifyChange(entry, true); + } + } + } + public void updateApkProgress(String key, int max, int current) { synchronized (appMapping) { AppUpdateStatus entry = appMapping.get(key); diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java index f1149601b..e06a27594 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java @@ -178,8 +178,9 @@ class NotificationHelper { // Ignore unknown status if (entry.status == AppUpdateStatusManager.Status.Unknown) return true; - // Ignore first time install downloads, assumed to be done from UI - else if (!entry.app.isInstalled() && (entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall)) + // Ignore downloading, readyToInstall and installError if we are showing the details screen for this app + else if ((entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall || entry.status == AppUpdateStatusManager.Status.InstallError) && + (AppDetails.isAppVisible(entry.app.packageName) || AppDetails2.isAppVisible(entry.app.packageName))) return true; return false; } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 23fe520dd..ebd53031d 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -15,6 +15,7 @@ import android.text.TextUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.fdroid.fdroid.AppDetails; +import org.fdroid.fdroid.AppDetails2; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.Hasher; import org.fdroid.fdroid.Utils; @@ -313,17 +314,13 @@ public class InstallManagerService extends Service { localBroadcastManager.unregisterReceiver(this); break; case Installer.ACTION_INSTALL_INTERRUPTED: - AppUpdateStatusManager.AppUpdateStatus status = appUpdateStatusManager.get(downloadUrl); - appUpdateStatusManager.removeApk(downloadUrl); apk = intent.getParcelableExtra(Installer.EXTRA_APK); String errorMessage = intent.getStringExtra(Installer.EXTRA_ERROR_MESSAGE); - - // show notification if app details is not visible if (!TextUtils.isEmpty(errorMessage)) { - if (status == null || status.app == null || !AppDetails.isAppVisible(status.app.packageName)) { - appUpdateStatusManager.setApkError(apk, errorMessage); - } + appUpdateStatusManager.setApkError(apk, errorMessage); + } else { + appUpdateStatusManager.removeApk(downloadUrl); } localBroadcastManager.unregisterReceiver(this); break;