Chromium Code Reviews| 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 |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..a274cfb8b764770105c96a226e6d81a5188249e5 |
| --- /dev/null |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java |
| @@ -0,0 +1,148 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.webapps; |
| + |
| +import android.content.pm.PackageInfo; |
| +import android.content.pm.PackageManager; |
| +import android.graphics.Bitmap; |
| +import android.os.Bundle; |
| + |
| +import org.chromium.base.ContextUtils; |
| +import org.chromium.base.annotations.CalledByNative; |
| +import org.chromium.chrome.browser.webapps.WebappRegistry.FetchWebappDataStorageCallback; |
| +import org.chromium.webapk.lib.common.WebApkConstants; |
| + |
| +import java.util.concurrent.TimeUnit; |
| + |
| +/** |
| + * WebApkUpdateManager manages when to check the Web Manifest updates of the WebAPK, and |
| + * sends request to the WebAPK Minting Server when a WebAPK needs update. |
| + */ |
| +public class WebApkUpdateManager { |
| + /** |
| + * The names of <meta-data> in the WebAPK's AndroidManifest.xml, must stay in sync with |
| + * {@linkorg.chromium.webapk.lib.runtime_library.HostBrowserLauncher}. |
| + */ |
| + private static final String META_DATA_WEB_MANIFEST_URL = |
| + "org.chromium.webapk.shell_apk.webmanifestUrl"; |
| + |
| + /** Represents a period of 3 days in milliseconds */ |
| + static final long FULL_CHECK_UPDATE_DURATION = TimeUnit.DAYS.toMillis(3L); |
| + |
| + /** Represents a period of 12 hours in milliseconds */ |
| + static final long RETRY_UPDATE_DURATION = TimeUnit.HOURS.toMillis(12L); |
| + |
| + private static class UpdateRequestData { |
| + private String mWebManifestUrl; |
| + private int mVersion; |
| + |
| + private UpdateRequestData(String webManifestUrl, int version) { |
| + mVersion = version; |
| + mWebManifestUrl = webManifestUrl; |
| + } |
| + |
| + public String webManifesUrl() { |
| + return mWebManifestUrl; |
| + } |
| + |
| + public int version() { |
| + return mVersion; |
| + } |
| + } |
| + /** |
| + * Check Web Manifest updates if we haven't checked updates for at least |
| + * {@link FULL_CHECK_UPDATE_DURATION}. |
| + * If a request to update the WebAPK has been sent to the WebAPK Minting Server recently |
| + * {@link RETRY_UPDATE_DURATION} but failed, resends the update request to the server. |
| + * @param webApkId The ID of the WebAPK. |
| + * @param detector The ManfiestUpgradeDetector owned by the WebAPK. |
| + */ |
| + public static void checkUpdate(String webApkId, final ManifestUpgradeDetector detector) { |
| + WebappRegistry.getWebappDataStorage(ContextUtils.getApplicationContext(), webApkId, |
| + new WebappRegistry.FetchWebappDataStorageCallback() { |
| + @Override |
| + public void onWebappDataStorageRetrieved(WebappDataStorage storage) { |
| + if (storage == null) { |
| + checkUpdate(storage, detector); |
| + return; |
| + } |
| + |
| + long sinceLastCheckDuration = System.currentTimeMillis() |
| + - storage.getLastCheckForWebManifestUpdateTime(); |
| + if (sinceLastCheckDuration > FULL_CHECK_UPDATE_DURATION) { |
|
pkotwicz
2016/08/03 19:09:34
Can we use |sinceLastRequestDuration| for this che
Xi Han
2016/08/03 20:22:46
Done.
|
| + checkUpdate(storage, detector); |
| + return; |
| + } |
| + |
| + long sinceLastRequestDuration = System.currentTimeMillis() |
| + - storage.getLastRequestForNewShellApkVersionTime(); |
| + if (sinceLastRequestDuration > RETRY_UPDATE_DURATION |
| + && !storage.getDoesLastRequestForNewShellApkVersionSucceed()) { |
| + checkUpdate(storage, detector); |
| + } |
| + } |
| + }); |
| + } |
| + |
| + private static void checkUpdate(WebappDataStorage storage, ManifestUpgradeDetector detector) { |
| + storage.updateLastCheckForWebManifestUpdateTime(); |
| + detector.start(); |
| + } |
| + |
| + /** |
| + * Sends request to WebAPK Minting Server to update WebAPK. |
| + * @param webappInfo The new fetched Web Manifest data of the WebAPK. |
| + */ |
| + public static void updateAsync(WebappInfo webappInfo) { |
| + UpdateRequestData data = getMetaData(webappInfo.webApkPackageName()); |
| + if (data == null) return; |
| + nativeUpdateAsync(webappInfo.webApkPackageName(), webappInfo.uri().toString(), |
| + webappInfo.scopeUri().toString(), webappInfo.name(), webappInfo.shortName(), |
| + webappInfo.displayMode(), webappInfo.orientation(), webappInfo.themeColor(), |
| + webappInfo.backgroundColor(), data.webManifesUrl(), "", |
|
pkotwicz
2016/08/03 19:09:34
Can you get the manifest URL from WebappInfo? I kn
Xi Han
2016/08/03 20:22:46
Done.
|
| + webappInfo.icon(), data.version()); |
| + } |
| + |
| + private static UpdateRequestData getMetaData(String webApkPackage) { |
| + try { |
| + PackageManager packageManager = |
| + ContextUtils.getApplicationContext().getPackageManager(); |
| + Bundle metaData = packageManager.getApplicationInfo( |
| + webApkPackage, PackageManager.GET_META_DATA).metaData; |
| + String webManifestUrl = metaData.getString(META_DATA_WEB_MANIFEST_URL); |
| + |
| + PackageInfo info = packageManager.getPackageInfo(webApkPackage, 0); |
| + int version = info.versionCode; |
| + UpdateRequestData data = new UpdateRequestData(webManifestUrl, version); |
| + return data; |
| + } catch (PackageManager.NameNotFoundException e) { |
| + e.printStackTrace(); |
| + } |
| + return null; |
| + } |
| + |
| + /** |
| + * Called after the either a request to update the WebAPK has been sent or the creation |
| + * process of a new WebAPK fails. |
| + */ |
| + @CalledByNative |
| + public static void onBuiltWebApk(final boolean success, String webapkPackage) { |
| + WebappRegistry.getWebappDataStorage(ContextUtils.getApplicationContext(), |
| + WebApkConstants.WEBAPK_ID_PREFIX + webapkPackage, |
| + new FetchWebappDataStorageCallback() { |
| + @Override |
| + public void onWebappDataStorageRetrieved(WebappDataStorage storage) { |
| + // Update the request time and result together. It prevents getting a |
| + // correct request time but a result from the previous request. |
| + storage.updateLastRequestForNewShellApkVersionTime(); |
| + storage.updateDoesLastRequestForNewShellApkVersionSucceed(success); |
| + } |
| + }); |
| + } |
| + |
| + private static native void nativeUpdateAsync(String webApkPackage, String url, String scope, |
| + String name, String shortName, int displayMode, int orientation, long themeColor, |
| + long backgroundColor, String manifestUrl, String iconUrl, Bitmap icon, int version); |
| +} |