| 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 6f15044d71949d9599f4704a4c647fbe2793a83d..7aae095dfc8374a4d09b92c8f8b407e2e20a14ee 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
|
| @@ -29,30 +29,26 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| private static final String TAG = "WebApkUpdateManager";
|
|
|
| /** Number of milliseconds between checks for whether the WebAPK's Web Manifest has changed. */
|
| - private static final long FULL_CHECK_UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(3L);
|
| + public static final long FULL_CHECK_UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(3L);
|
|
|
| /**
|
| * Number of milliseconds to wait before re-requesting an updated WebAPK from the WebAPK
|
| * server if the previous update attempt failed.
|
| */
|
| - private static final long RETRY_UPDATE_DURATION = TimeUnit.HOURS.toMillis(12L);
|
| + public static final long RETRY_UPDATE_DURATION = TimeUnit.HOURS.toMillis(12L);
|
|
|
| /**
|
| * Id of WebAPK data in WebappDataStorage
|
| */
|
| private String mId;
|
|
|
| - /** Version number of //chrome/android/webapk/shell_apk code. */
|
| - private int mShellApkVersion;
|
| -
|
| /** Android version code of WebAPK. */
|
| private int mVersionCode;
|
|
|
| /**
|
| - * Whether a request to upgrade the WebAPK should be sent regardless of whether the Web Manifest
|
| - * has changed.
|
| + * Whether the previous WebAPK update succeeded. True if there has not been any update attempts.
|
| */
|
| - private boolean mForceUpgrade;
|
| + private boolean mPreviousUpdateSucceeded;
|
|
|
| private ManifestUpgradeDetector mUpgradeDetector;
|
|
|
| @@ -71,41 +67,57 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| mId = info.id();
|
| mVersionCode = packageInfo.versionCode;
|
| final Bundle metadata = packageInfo.applicationInfo.metaData;
|
| - mShellApkVersion =
|
| + int shellApkVersion =
|
| IntentUtils.safeGetInt(metadata, WebApkMetaDataKeys.SHELL_APK_VERSION, 0);
|
|
|
| - mUpgradeDetector = new ManifestUpgradeDetector(tab, info, metadata, this);
|
| -
|
| - WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(info.id());
|
| - if (forceUpgrade(storage)) mForceUpgrade = true;
|
| + WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(mId);
|
| + mPreviousUpdateSucceeded = didPreviousUpdateSucceed(storage);
|
|
|
| // TODO(pkotwicz|hanxi): Request upgrade if ShellAPK version changes if
|
| // ManifestUpgradeDetector cannot fetch the Web Manifest. For instance, the web developer
|
| // may have removed the Web Manifest from their site. (http://crbug.com/639536)
|
|
|
| - long sinceLastCheckDuration = System.currentTimeMillis()
|
| - - storage.getLastCheckForWebManifestUpdateTime();
|
| - if (sinceLastCheckDuration > FULL_CHECK_UPDATE_INTERVAL || mForceUpgrade) {
|
| - if (mUpgradeDetector.start()) {
|
| - // crbug.com/636525. The timestamp of the last manifest update check should be
|
| - // updated after the detector finds the manifest, not when the detector is started.
|
| - storage.updateTimeOfLastCheckForUpdatedWebManifest();
|
| - }
|
| + if (!shouldCheckIfWebManifestUpdated(storage, shellApkVersion, mPreviousUpdateSucceeded)) {
|
| + return;
|
| }
|
| +
|
| + mUpgradeDetector = buildManifestUpgradeDetector(tab, info, metadata);
|
| + if (!mUpgradeDetector.start()) return;
|
| +
|
| + // crbug.com/636525. The timestamp of the last manifest update check should be updated after
|
| + // the detector finds the manifest, not when the detector is started.
|
| + storage.updateTimeOfLastCheckForUpdatedWebManifest();
|
| }
|
|
|
| @Override
|
| public void onUpgradeNeededCheckFinished(boolean needsUpgrade,
|
| ManifestUpgradeDetector.FetchedManifestData data) {
|
| - needsUpgrade = (needsUpgrade || mForceUpgrade);
|
| - Log.v(TAG, "WebAPK upgrade needed: " + needsUpgrade);
|
| - if (needsUpgrade) {
|
| - updateAsync(data);
|
| - }
|
| if (mUpgradeDetector != null) {
|
| mUpgradeDetector.destroy();
|
| }
|
| mUpgradeDetector = null;
|
| +
|
| + Log.v(TAG, "WebAPK upgrade needed: " + needsUpgrade);
|
| +
|
| + if (!needsUpgrade) {
|
| + if (!mPreviousUpdateSucceeded) {
|
| + recordUpdateInWebappDataStorage(mId, true);
|
| + }
|
| + return;
|
| + }
|
| +
|
| + // Set WebAPK update as having failed in case that Chrome is killed prior to
|
| + // {@link onBuiltWebApk} being called.
|
| + recordUpdateInWebappDataStorage(mId, false);
|
| + updateAsync(data);
|
| + }
|
| +
|
| + /**
|
| + * Builds {@link ManifestUpgradeDetector}. In a separate function for the sake of tests.
|
| + */
|
| + protected ManifestUpgradeDetector buildManifestUpgradeDetector(
|
| + Tab tab, WebappInfo info, Bundle metaData) {
|
| + return new ManifestUpgradeDetector(tab, info, metaData, this);
|
| }
|
|
|
| /**
|
| @@ -126,6 +138,11 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| mUpgradeDetector = null;
|
| }
|
|
|
| + /** Returns the current time. In a separate function for the sake of testing. */
|
| + protected long currentTimeMillis() {
|
| + return System.currentTimeMillis();
|
| + }
|
| +
|
| /**
|
| * Reads the WebAPK's PackageInfo from the Android Manifest.
|
| */
|
| @@ -141,31 +158,50 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| }
|
|
|
| /**
|
| - * Returns whether an upgrade should be requested regardless of whether the Web Manifest has
|
| - * changed.
|
| + * Returns whether the previous WebAPK update attempt succeeded. Returns true if there has not
|
| + * been any update attempts.
|
| + */
|
| + private static boolean didPreviousUpdateSucceed(WebappDataStorage storage) {
|
| + long lastUpdateCompletionTime = storage.getLastWebApkUpdateRequestCompletionTime();
|
| + if (lastUpdateCompletionTime == WebappDataStorage.LAST_USED_INVALID
|
| + || lastUpdateCompletionTime == WebappDataStorage.LAST_USED_UNSET) {
|
| + return true;
|
| + }
|
| + return storage.getDidLastWebApkUpdateRequestSucceed();
|
| + }
|
| +
|
| + /**
|
| + * Returns whether the Web Manifest should be refetched to check whether it has been updated.
|
| + * TODO: Make this method static once there is a static global clock class.
|
| + * @param storage WebappDataStorage with the WebAPK's cached data.
|
| + * @param shellApkVersion Version number of //chrome/android/webapk/shell_apk code.
|
| + * @param previousUpdateSucceeded Whether the previous update attempt succeeded.
|
| + * True if there has not been any update attempts.
|
| */
|
| - private boolean forceUpgrade(WebappDataStorage storage) {
|
| + private boolean shouldCheckIfWebManifestUpdated(
|
| + WebappDataStorage storage, int shellApkVersion, boolean previousUpdateSucceeded) {
|
| if (CommandLine.getInstance().hasSwitch(
|
| ChromeSwitches.CHECK_FOR_WEB_MANIFEST_UPDATE_ON_STARTUP)) {
|
| return true;
|
| }
|
|
|
| - long sinceLastUpdateRequestDuration =
|
| - System.currentTimeMillis() - storage.getLastWebApkUpdateRequestCompletionTime();
|
| - if (sinceLastUpdateRequestDuration <= RETRY_UPDATE_DURATION) {
|
| - return false;
|
| - }
|
| + if (shellApkVersion < WebApkVersion.CURRENT_SHELL_APK_VERSION) return true;
|
|
|
| - return mShellApkVersion < WebApkVersion.CURRENT_SHELL_APK_VERSION
|
| - || !storage.getDidLastWebApkUpdateRequestSucceed();
|
| + long now = currentTimeMillis();
|
| + long sinceLastCheckDurationMs = now - storage.getLastCheckForWebManifestUpdateTime();
|
| + if (sinceLastCheckDurationMs >= FULL_CHECK_UPDATE_INTERVAL) return true;
|
| +
|
| + long sinceLastUpdateRequestDurationMs =
|
| + now - storage.getLastWebApkUpdateRequestCompletionTime();
|
| + return sinceLastUpdateRequestDurationMs >= RETRY_UPDATE_DURATION
|
| + && !previousUpdateSucceeded;
|
| }
|
|
|
| /**
|
| - * Called after either a request to update the WebAPK has been sent or the update process
|
| - * fails.
|
| + * Updates {@link WebappDataStorage} with the time of the latest WebAPK update and whether the
|
| + * WebAPK update succeeded.
|
| */
|
| - @CalledByNative
|
| - private static void onBuiltWebApk(String id, final boolean success) {
|
| + private static void recordUpdateInWebappDataStorage(String id, boolean success) {
|
| WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(id);
|
| // Update the request time and result together. It prevents getting a correct request time
|
| // but a result from the previous request.
|
| @@ -173,6 +209,15 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
|
| storage.updateDidLastWebApkUpdateRequestSucceed(success);
|
| }
|
|
|
| + /**
|
| + * Called after either a request to update the WebAPK has been sent or the update process
|
| + * fails.
|
| + */
|
| + @CalledByNative
|
| + private static void onBuiltWebApk(String id, boolean success) {
|
| + recordUpdateInWebappDataStorage(id, success);
|
| + }
|
| +
|
| private static native void nativeUpdateAsync(String id, String startUrl, String scope,
|
| String name, String shortName, String iconUrl, String iconMurmur2Hash, Bitmap icon,
|
| int displayMode, int orientation, long themeColor, long backgroundColor,
|
|
|