| Index: chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
|
| index 8aacf80f512fd19202852de68ff89a67204ab4a7..66c0bc540a1892dd807aa5024aab2ec9daed021d 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
|
| @@ -9,6 +9,7 @@ import android.content.pm.PackageInfo;
|
| import android.content.pm.PackageManager;
|
| import android.graphics.Bitmap;
|
| import android.provider.Settings;
|
| +import android.text.TextUtils;
|
|
|
| import org.chromium.base.CommandLine;
|
| import org.chromium.base.ContextUtils;
|
| @@ -16,15 +17,17 @@ import org.chromium.base.Log;
|
| import org.chromium.base.annotations.CalledByNative;
|
| import org.chromium.chrome.browser.ChromeSwitches;
|
| import org.chromium.chrome.browser.tab.Tab;
|
| +import org.chromium.chrome.browser.util.UrlUtilities;
|
| import org.chromium.webapk.lib.client.WebApkVersion;
|
|
|
| +import java.util.Map;
|
| import java.util.concurrent.TimeUnit;
|
|
|
| /**
|
| * WebApkUpdateManager manages when to check for updates to the WebAPK's Web Manifest, and sends
|
| * an update request to the WebAPK Server when an update is needed.
|
| */
|
| -public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| +public class WebApkUpdateManager implements WebApkUpdateDataFetcher.Observer {
|
| private static final String TAG = "WebApkUpdateManager";
|
|
|
| /** Number of milliseconds between checks for whether the WebAPK's Web Manifest has changed. */
|
| @@ -44,7 +47,7 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| */
|
| private boolean mPreviousUpdateSucceeded;
|
|
|
| - private ManifestUpgradeDetector mUpgradeDetector;
|
| + private WebApkUpdateDataFetcher mFetcher;
|
|
|
| /**
|
| * Checks whether the WebAPK's Web Manifest has changed. Requests an updated WebAPK if the
|
| @@ -60,27 +63,28 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
|
|
| if (!shouldCheckIfWebManifestUpdated(storage, mInfo, mPreviousUpdateSucceeded)) return;
|
|
|
| - mUpgradeDetector = buildManifestUpgradeDetector(tab, mInfo);
|
| - mUpgradeDetector.start();
|
| + mFetcher = buildFetcher();
|
| + mFetcher.start(tab, mInfo, this);
|
| }
|
|
|
| public void destroy() {
|
| - destroyUpgradeDetector();
|
| + destroyFetcher();
|
| }
|
|
|
| @Override
|
| public void onFinishedFetchingWebManifestForInitialUrl(
|
| - boolean needsUpgrade, WebApkInfo info, String bestIconUrl) {
|
| - onGotManifestData(needsUpgrade, info, bestIconUrl);
|
| + WebApkInfo fetchedInfo, String bestIconUrl) {
|
| + onGotManifestData(fetchedInfo, bestIconUrl);
|
| }
|
|
|
| @Override
|
| - public void onGotManifestData(boolean needsUpgrade, WebApkInfo info, String bestIconUrl) {
|
| + public void onGotManifestData(WebApkInfo fetchedInfo, String bestIconUrl) {
|
| WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(mInfo.id());
|
| storage.updateTimeOfLastCheckForUpdatedWebManifest();
|
|
|
| - boolean gotManifest = (info != null);
|
| - needsUpgrade |= isShellApkVersionOutOfDate(mInfo);
|
| + boolean gotManifest = (fetchedInfo != null);
|
| + boolean needsUpgrade = isShellApkVersionOutOfDate(mInfo)
|
| + || (gotManifest && needsUpdate(mInfo, fetchedInfo, bestIconUrl));
|
| Log.v(TAG, "Got Manifest: " + gotManifest);
|
| Log.v(TAG, "WebAPK upgrade needed: " + needsUpgrade);
|
|
|
| @@ -97,7 +101,7 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| // Web Manifests as the user navigates. For instance, the WebAPK's start_url might not
|
| // point to a Web Manifest because start_url redirects to the WebAPK's main page.
|
| if (gotManifest || needsUpgrade) {
|
| - destroyUpgradeDetector();
|
| + destroyFetcher();
|
| }
|
|
|
| if (!needsUpgrade) {
|
| @@ -111,8 +115,8 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| // {@link onBuiltWebApk} being called.
|
| recordUpdate(storage, false);
|
|
|
| - if (info != null) {
|
| - updateAsync(info, bestIconUrl);
|
| + if (fetchedInfo != null) {
|
| + updateAsync(fetchedInfo, bestIconUrl);
|
| return;
|
| }
|
|
|
| @@ -122,10 +126,10 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| }
|
|
|
| /**
|
| - * Builds {@link ManifestUpgradeDetector}. In a separate function for the sake of tests.
|
| + * Builds {@link WebApkUpdateDataFetcher}. In a separate function for the sake of tests.
|
| */
|
| - protected ManifestUpgradeDetector buildManifestUpgradeDetector(Tab tab, WebApkInfo info) {
|
| - return new ManifestUpgradeDetector(tab, info, this);
|
| + protected WebApkUpdateDataFetcher buildFetcher() {
|
| + return new WebApkUpdateDataFetcher();
|
| }
|
|
|
| /**
|
| @@ -142,13 +146,13 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| }
|
|
|
| /**
|
| - * Destroys {@link mUpgradeDetector}. In a separate function for the sake of tests.
|
| + * Destroys {@link mFetcher}. In a separate function for the sake of tests.
|
| */
|
| - protected void destroyUpgradeDetector() {
|
| - if (mUpgradeDetector == null) return;
|
| + protected void destroyFetcher() {
|
| + if (mFetcher == null) return;
|
|
|
| - mUpgradeDetector.destroy();
|
| - mUpgradeDetector = null;
|
| + mFetcher.destroy();
|
| + mFetcher = null;
|
| }
|
|
|
| /** Returns the current time. In a separate function for the sake of testing. */
|
| @@ -201,6 +205,11 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| */
|
| private boolean shouldCheckIfWebManifestUpdated(
|
| WebappDataStorage storage, WebApkInfo info, boolean previousUpdateSucceeded) {
|
| + if (CommandLine.getInstance().hasSwitch(
|
| + ChromeSwitches.CHECK_FOR_WEB_MANIFEST_UPDATE_ON_STARTUP)) {
|
| + return true;
|
| + }
|
| +
|
| // Updating WebAPKs requires "installation from unknown sources" to be enabled. It is
|
| // confusing for a user to see a dialog asking them to enable "installation from unknown
|
| // sources" when they are in the middle of using the WebAPK (as opposed to after requesting
|
| @@ -209,11 +218,6 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| return false;
|
| }
|
|
|
| - if (CommandLine.getInstance().hasSwitch(
|
| - ChromeSwitches.CHECK_FOR_WEB_MANIFEST_UPDATE_ON_STARTUP)) {
|
| - return true;
|
| - }
|
| -
|
| if (isShellApkVersionOutOfDate(info)) return true;
|
|
|
| long now = currentTimeMillis();
|
| @@ -253,6 +257,55 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| }
|
|
|
| /**
|
| + * Checks whether the WebAPK needs to be updated.
|
| + * @param info Meta data from WebAPK's Android Manifest.
|
| + * @param fetchedInfo Fetched data for Web Manifest.
|
| + * @param bestFetchedIconUrl The icon URL in {@link fetchedInfo#iconUrlToMurmur2HashMap()} best
|
| + * suited for use as the launcher icon on this device.
|
| + */
|
| + private boolean needsUpdate(WebApkInfo info, WebApkInfo fetchedInfo, String bestIconUrl) {
|
| + // We should have computed the Murmur2 hash for the bitmap at the best icon URL for
|
| + // {@link fetchedInfo} (but not the other icon URLs.)
|
| + String fetchedBestIconMurmur2Hash = fetchedInfo.iconUrlToMurmur2HashMap().get(bestIconUrl);
|
| + String bestIconMurmur2Hash =
|
| + findMurmur2HashForUrlIgnoringFragment(mInfo.iconUrlToMurmur2HashMap(), bestIconUrl);
|
| +
|
| + return !TextUtils.equals(bestIconMurmur2Hash, fetchedBestIconMurmur2Hash)
|
| + || !urlsMatchIgnoringFragments(
|
| + mInfo.scopeUri().toString(), fetchedInfo.scopeUri().toString())
|
| + || !urlsMatchIgnoringFragments(
|
| + mInfo.manifestStartUrl(), fetchedInfo.manifestStartUrl())
|
| + || !TextUtils.equals(mInfo.shortName(), fetchedInfo.shortName())
|
| + || !TextUtils.equals(mInfo.name(), fetchedInfo.name())
|
| + || mInfo.backgroundColor() != fetchedInfo.backgroundColor()
|
| + || mInfo.themeColor() != fetchedInfo.themeColor()
|
| + || mInfo.orientation() != fetchedInfo.orientation()
|
| + || mInfo.displayMode() != fetchedInfo.displayMode();
|
| + }
|
| +
|
| + /**
|
| + * Returns the Murmur2 hash for entry in {@link iconUrlToMurmur2HashMap} whose canonical
|
| + * representation, ignoring fragments, matches {@link iconUrlToMatch}.
|
| + */
|
| + private String findMurmur2HashForUrlIgnoringFragment(
|
| + Map<String, String> iconUrlToMurmur2HashMap, String iconUrlToMatch) {
|
| + for (Map.Entry<String, String> entry : iconUrlToMurmur2HashMap.entrySet()) {
|
| + if (urlsMatchIgnoringFragments(entry.getKey(), iconUrlToMatch)) {
|
| + return entry.getValue();
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Returns whether the urls match ignoring fragments. Canonicalizes the URLs prior to doing the
|
| + * comparison.
|
| + */
|
| + protected boolean urlsMatchIgnoringFragments(String url1, String url2) {
|
| + return UrlUtilities.urlsMatchIgnoringFragments(url1, url2);
|
| + }
|
| +
|
| + /**
|
| * Called after either a request to update the WebAPK has been sent or the update process
|
| * fails.
|
| */
|
|
|