From 1d4f4ce01d9efa6c40c6db4869ac5d1f512a9c57 Mon Sep 17 00:00:00 2001 From: Peter Serwylo <peter@serwylo.com> Date: Wed, 27 Sep 2017 22:53:27 +1000 Subject: [PATCH] Correctly handle swiping to dismiss items in updates tab. Items which can be updated (but have not yet been downloaded or queued for download) will act as if the user selected "Ignore this update" from the app details view. Items which represent app statuses (e.g. downloading, downloaded ready to install, installed ready to run) will have the status removed. If required, we will also forget that they are ready to install, so they wont be there next time. --- .../views/apps/AppListItemController.java | 14 ++++++---- .../fdroid/views/updates/UpdatesAdapter.java | 10 +++++++ .../items/AppStatusListItemController.java | 26 +++++++++++++++++++ .../items/KnownVulnAppListItemController.java | 15 +++++++++++ .../UpdateableAppListItemController.java | 20 ++++++++++++++ app/src/main/res/values/strings.xml | 2 ++ 6 files changed, 82 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index aa5d568e1..4a007830d 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -510,11 +510,15 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder { private final View.OnClickListener onCancelDownload = new View.OnClickListener() { @Override public void onClick(View v) { - if (currentStatus == null || currentStatus.status != AppUpdateStatusManager.Status.Downloading) { - return; - } - - InstallManagerService.cancel(activity, currentStatus.getUniqueKey()); + cancelDownload(); } }; + + protected final void cancelDownload() { + if (currentStatus == null || currentStatus.status != AppUpdateStatusManager.Status.Downloading) { + return; + } + + InstallManagerService.cancel(activity, currentStatus.getUniqueKey()); + } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java index 03ee0bd28..046e8f1b1 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java @@ -341,6 +341,16 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder } }; + /** + * If an item representing an {@link org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus} is dismissed, + * then we should rebuild the list of app statuses and update the adapter. If it was an updateable app which was + * dismissed, then it is still harmless to rebuild the list of items anyway, but this isn't strictly required + * because the act of marking an app as "Ignored" will trigger the {@link AppProvider} to re-query for a list + * of updateable apps, separate to this method. However, by the time we get here it is a bit tricky to figure + * out which item was dismissed, so for simplicity (and to make the behaviour more deterministic) we always + * rebuild the full updates list. + */ public void onItemDismissed() { + onAppStatusRemoved(); } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java index ed0b536a1..7aa123aa0 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/AppStatusListItemController.java @@ -45,4 +45,30 @@ public class AppStatusListItemController extends AppListItemController { return null; } + + @Override + public boolean canDismiss() { + return true; + } + + @Nullable + @Override + protected CharSequence onDismissApp(@NonNull App app) { + AppUpdateStatus status = getCurrentStatus(); + if (status != null) { + AppUpdateStatusManager manager = AppUpdateStatusManager.getInstance(activity); + manager.removeApk(status.getUniqueKey()); + switch (status.status) { + case ReadyToInstall: + manager.markAsNoLongerPendingInstall(status); + break; + + case Downloading: + cancelDownload(); + break; + } + } + + return null; + } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java index 23f7bea45..5d93c58a9 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/KnownVulnAppListItemController.java @@ -82,8 +82,23 @@ public class KnownVulnAppListItemController extends AppListItemController { } } + @Override + public boolean canDismiss() { + return true; + } + + @Override + protected CharSequence onDismissApp(@NonNull App app) { + this.ignoreVulnerableApp(app); + return activity.getString(R.string.app_list__dismiss_vulnerable_app); + } + @Override protected void onSecondaryButtonPressed(@NonNull App app) { + this.ignoreVulnerableApp(app); + } + + private void ignoreVulnerableApp(@NonNull App app) { AppPrefs prefs = app.getPrefs(activity); prefs.ignoreVulnerabilities = true; AppPrefsProvider.Helper.update(activity, app, prefs); diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java index 42a45b1a1..3e0d71895 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/items/UpdateableAppListItemController.java @@ -6,7 +6,10 @@ import android.support.annotation.Nullable; import android.view.View; import org.fdroid.fdroid.AppUpdateStatusManager; +import org.fdroid.fdroid.R; import org.fdroid.fdroid.data.App; +import org.fdroid.fdroid.data.AppPrefs; +import org.fdroid.fdroid.data.AppPrefsProvider; import org.fdroid.fdroid.views.apps.AppListItemController; import org.fdroid.fdroid.views.apps.AppListItemState; @@ -28,4 +31,21 @@ public class UpdateableAppListItemController extends AppListItemController { return new AppListItemState(app) .setShowInstallButton(true); } + + @Override + public boolean canDismiss() { + return true; + } + + @Override + @Nullable + protected CharSequence onDismissApp(@NonNull App app) { + AppPrefs prefs = app.getPrefs(activity); + prefs.ignoreThisUpdate = app.suggestedVersionCode; + + // The act of updating here will trigger a re-query of the "can update" apps, so no need to do anything else + // to update the UI in response to this. + AppPrefsProvider.Helper.update(activity, app, prefs); + return activity.getString(R.string.app_list__dismiss_app_update); + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7503ea30f..a3ea2f2f0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -87,6 +87,8 @@ This often occurs with apps installed via Google Play or other sources, if they <string name="app_list__name__downloading_in_progress">Downloading %1$s</string> <string name="app_list__name__successfully_installed">%1$s installed</string> <string name="app_list_download_ready">Downloaded, ready to install</string> + <string name="app_list__dismiss_app_update">Update ignored</string> + <string name="app_list__dismiss_vulnerable_app">Vulnerability ignored</string> <string name="installed_apps__activity_title">Installed Apps</string> <string name="installed_app__updates_ignored">Updates ignored</string>