From 116cb88b81e2d4ad146ef21ada3fe020981da9c4 Mon Sep 17 00:00:00 2001
From: Peter Serwylo <peter@serwylo.com>
Date: Mon, 5 Jun 2017 16:03:30 +1000
Subject: [PATCH 1/3] Fix incorrect persistent + annoying notification to
 update F-Droid.

There is a persistent shared preference which dictates whether apps
have been successfully downloaded and are ready to install. When
the `InstallManagerService` used to receive an `ACTION_INSTALL_COMPLETE`
broadcast, it would update this preference to no longer be installing.
However, this never got received in the case of F-Droid updating itself.
In that case, we need to instead wait for the system to broadcast an
`Intent.ACTION_PACKAGE_ADDED` intent. This change waits until that
point before removing the preference.

Fixes #1027.
---
 .../data/InstalledAppProviderService.java       | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
index 7a1d404c1..35602ba1e 100644
--- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
+++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
@@ -13,6 +13,7 @@ import android.support.annotation.Nullable;
 import android.util.Log;
 
 import org.acra.ACRA;
+import org.fdroid.fdroid.AppUpdateStatusManager;
 import org.fdroid.fdroid.Hasher;
 import org.fdroid.fdroid.Utils;
 import org.fdroid.fdroid.data.Schema.InstalledAppTable;
@@ -219,6 +220,22 @@ public class InstalledAppProviderService extends IntentService {
                     try {
                         String hashType = "sha256";
                         String hash = Utils.getBinaryHash(apk, hashType);
+
+                        // Ensure that we no longer notify the user that this apk successfully
+                        // downloaded and is now ready to be installed. Used to be handled only
+                        // by InstallManagerService after receiving ACTION_INSTALL_COMPLETE, but
+                        // that doesn't work for F-Droid itself, which never receives that action.
+                        for (Apk apkInRepo : ApkProvider.Helper.findApksByHash(this, hash)) {
+
+                            Utils.debugLog(TAG, "Noticed that " + apkInRepo.apkName +
+                                    " version " + apkInRepo.versionName + " was installed," +
+                                    " so marking as no longer pending install");
+
+                            AppUpdateStatusManager.getInstance(this)
+                                    .markAsNoLongerPendingInstall(apkInRepo.getUrl());
+
+                        }
+
                         insertAppIntoDb(this, packageInfo, hashType, hash);
                     } catch (IllegalArgumentException e) {
                         Utils.debugLog(TAG, e.getMessage());

From 1dbf5704b6884d15a179656c3fb1dc2d0f7214b1 Mon Sep 17 00:00:00 2001
From: Peter Serwylo <peter@serwylo.com>
Date: Wed, 7 Jun 2017 22:07:01 +1000
Subject: [PATCH 2/3] Don't remove ourselves from the installed app cache.

If F-Droid was actually removed, then we wouldn't even
have an installed app cache (we aren't even on the device
any more). As such, ignore all requests to remove F-Droid
because it complicates the installed apk cache. Specifically,
there is a race condition between the "compare apk cache to
package manager" and the "package removed receiver", where
the later was overriding the former.
---
 .../fdroid/fdroid/data/InstalledAppProviderService.java    | 1 +
 .../org/fdroid/fdroid/receiver/PackageManagerReceiver.java | 7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
index 35602ba1e..870fdb20e 100644
--- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
+++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
@@ -164,6 +164,7 @@ public class InstalledAppProviderService extends IntentService {
      * @see <a href="https://gitlab.com/fdroid/fdroidclient/issues/819>issue #819</a>
      */
     public static void compareToPackageManager(Context context) {
+        Utils.debugLog(TAG, "Comparing package manager to our installed app cache.");
         Map<String, Long> cachedInfo = InstalledAppProvider.Helper.all(context);
 
         List<PackageInfo> packageInfoList = context.getPackageManager()
diff --git a/app/src/main/java/org/fdroid/fdroid/receiver/PackageManagerReceiver.java b/app/src/main/java/org/fdroid/fdroid/receiver/PackageManagerReceiver.java
index d9c44b19c..3bda33bf4 100644
--- a/app/src/main/java/org/fdroid/fdroid/receiver/PackageManagerReceiver.java
+++ b/app/src/main/java/org/fdroid/fdroid/receiver/PackageManagerReceiver.java
@@ -3,6 +3,7 @@ package org.fdroid.fdroid.receiver;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.text.TextUtils;
 
 import org.fdroid.fdroid.Utils;
 import org.fdroid.fdroid.data.InstalledAppProviderService;
@@ -26,7 +27,11 @@ public class PackageManagerReceiver extends BroadcastReceiver {
             if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                 InstalledAppProviderService.insert(context, intent.getData());
             } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
-                InstalledAppProviderService.delete(context, intent.getData());
+                if (TextUtils.equals(context.getPackageName(), intent.getData().getSchemeSpecificPart())) {
+                    Utils.debugLog(TAG, "Ignoring request to remove ourselves from cache.");
+                } else {
+                    InstalledAppProviderService.delete(context, intent.getData());
+                }
             } else {
                 Utils.debugLog(TAG, "unsupported action: " + action + " " + intent);
             }

From 9e33dcf0db513723bb753b2add91ba246932cd4b Mon Sep 17 00:00:00 2001
From: Peter Serwylo <peter@serwylo.com>
Date: Thu, 8 Jun 2017 09:12:52 +1000
Subject: [PATCH 3/3] Wait 3 seconds before refreshing the view.

With a 1 second debounce, I was getting the view to refresh
several times in response to large apps being processed (e.g.
Firefox, OSMAnd, etc). This was on a (relatively) recent Moto X
2nd Gen, so it would be even more visible on an older device.

The side effect of updating frequently is that the main list
of apps flashes regularly in front of the user (see #986).

This "update the view" is only in response to a background
task that is expected to take several seconds (e.g. 30 seconds)
anyway, so waiting 3 seconds instead of 1 is not particularly
problematic.
---
 .../org/fdroid/fdroid/data/InstalledAppProviderService.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
index 870fdb20e..1298cf49c 100644
--- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
+++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java
@@ -73,7 +73,7 @@ public class InstalledAppProviderService extends IntentService {
         // the list of installed apps and insert them to the database...
         packageChangeNotifier
                 .subscribeOn(Schedulers.newThread())
-                .debounce(1, TimeUnit.SECONDS)
+                .debounce(3, TimeUnit.SECONDS)
                 .subscribe(new Action1<String>() {
                         @Override
                         public void call(String packageName) {