Bug 1396941 - SuggestedSitePreparer: Update local cache if suggested sites change. r=mcomella
authorSebastian Kaspari <s.kaspari@gmail.com>
Wed, 13 Sep 2017 19:57:19 +0200
changeset 430372 163de8db41e8e1057f11816f5586bed29e837d76
parent 430371 0cd2b311c3fb2321ad5df14d0d0470f76363c8fe
child 430373 9f1636ed17b6a33ae581a696c0ed1d34e7fe5622
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcomella
bugs1396941
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1396941 - SuggestedSitePreparer: Update local cache if suggested sites change. r=mcomella MozReview-Commit-ID: 2QMqGHQaBSP
mobile/android/base/java/org/mozilla/gecko/icons/preparation/SuggestedSitePreparer.java
--- a/mobile/android/base/java/org/mozilla/gecko/icons/preparation/SuggestedSitePreparer.java
+++ b/mobile/android/base/java/org/mozilla/gecko/icons/preparation/SuggestedSitePreparer.java
@@ -1,38 +1,72 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 package org.mozilla.gecko.icons.preparation;
 
 import android.content.Context;
+import android.database.ContentObserver;
 import android.database.Cursor;
 
 import org.mozilla.gecko.db.BrowserContract;
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.db.SuggestedSites;
 import org.mozilla.gecko.icons.IconDescriptor;
 import org.mozilla.gecko.icons.IconRequest;
 import org.mozilla.gecko.icons.loader.SuggestedSiteLoader;
+import org.mozilla.gecko.util.ThreadUtils;
 
 import java.util.HashSet;
 import java.util.Set;
 
 public class SuggestedSitePreparer implements Preparer {
-
     private boolean initialised = false;
     private final Set<String> siteFaviconMap = new HashSet<>();
 
+    private boolean initialise(final Context context) {
+        registerForSuggestedSitesUpdated(context.getApplicationContext());
+
+        return refreshSiteFaviconMap(context);
+    }
+
+    // Suggested sites can change at runtime - for example when a distribution is (down)loaded. In
+    // this case we need to refresh our local cache of suggested sites' favicons.
+    private void registerForSuggestedSitesUpdated(final Context context) {
+        context.getContentResolver().registerContentObserver(
+                BrowserContract.SuggestedSites.CONTENT_URI,
+                false,
+                new ContentObserver(null) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        // The list of suggested sites has changed. We need to update our local
+                        // mapping.
+                        refreshSiteFaviconMapOnBackgroundThread(context);
+                    }
+                });
+    }
+
+    private void refreshSiteFaviconMapOnBackgroundThread(final Context context) {
+        ThreadUtils.postToBackgroundThread(new Runnable() {
+            @Override
+            public void run() {
+                refreshSiteFaviconMap(context);
+            }
+        });
+    }
+
     // Loading suggested sites (and iterating over them) is potentially slow. The number of suggested
     // sites is low, and a HashSet containing them is therefore likely to be exceedingly small.
     // Hence we opt to iterate over the list once, and do an immediate lookup every time a favicon
     // is requested:
     // Loading can fail if suggested sites haven't been initialised yet, only proceed if we return true.
-    private boolean initialise(final Context context) {
+    private synchronized boolean refreshSiteFaviconMap(Context context) {
+        siteFaviconMap.clear();
+
         final SuggestedSites suggestedSites = BrowserDB.from(context).getSuggestedSites();
 
         // suggestedSites may not have been initialised yet if BrowserApp isn't running yet. Suggested
         // Sites are initialised in BrowserApp.onCreate(), but we might need to load icons when running
         // custom tabs, as geckoview, etc. (But we don't care as much about the bundled icons in those
         // scenarios.)
         if (suggestedSites == null) {
             return false;
@@ -48,18 +82,20 @@ public class SuggestedSitePreparer imple
             }
         } finally {
             cursor.close();
         }
 
         return true;
     }
 
+    // Synchronized so that asynchronous updates of the map (via content observer) are visible
+    // immediately and completely.
     @Override
-    public void prepare(final IconRequest request) {
+    public synchronized void prepare(final IconRequest request) {
         if (request.shouldSkipDisk()) {
             return;
         }
 
         if (!initialised) {
             initialised = initialise(request.getContext());
 
             if (!initialised) {