Commit be1e4f7a authored by Peter Kotwicz's avatar Peter Kotwicz Committed by Commit Bot

[Android WebAPK] Make WebappInfo/WebApkInfo use CustomTabIntentDataProvider 2/4

This CL:
- Introduces WebappIntentDataProvider and WebApkIntentDataProvider
which extend BrowserServicesIntentDataProvider
- Refactors WebappInfo and WebApkInfo to be backed by
WebappIntentDataProvider/WebApkIntentDataProvider
- Adds more JUnit tests for WebAPK updates now that WebApkInfo is backed
by a much more complex object

BUG=993651

Change-Id: I1ddd6a7c2e96d06639aa6d398d481d0581c6de07
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1770001
Commit-Queue: Peter Kotwicz <pkotwicz@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692344}
parent 03a033a0
......@@ -1717,6 +1717,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/webapps/WebApkActivity8.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkActivity9.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkInfo.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkIntentDataProvider.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkHandlerDelegate.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkInstallService.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java",
......@@ -1749,10 +1750,13 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/webapps/WebappDelegateFactory.java",
"java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java",
"java/src/org/chromium/chrome/browser/webapps/WebappDisclosureSnackbarController.java",
"java/src/org/chromium/chrome/browser/webapps/WebappExtras.java",
"java/src/org/chromium/chrome/browser/webapps/WebappIcon.java",
"java/src/org/chromium/chrome/browser/webapps/WebappInfo.java",
"java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java",
"java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java",
"java/src/org/chromium/chrome/browser/webapps/WebappManagedActivity.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkExtras.java",
"java/src/org/chromium/chrome/browser/webapps/WebApkOfflineDialog.java",
"java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java",
"java/src/org/chromium/chrome/browser/webapps/WebappScopePolicy.java",
......
......@@ -19,6 +19,8 @@ import androidx.browser.trusted.sharing.ShareData;
import androidx.browser.trusted.sharing.ShareTarget;
import org.chromium.chrome.browser.customtabs.CustomButtonParams;
import org.chromium.chrome.browser.webapps.WebApkExtras;
import org.chromium.chrome.browser.webapps.WebappExtras;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
......@@ -46,19 +48,12 @@ public class BrowserServicesIntentDataProvider {
int OFFLINE_PAGE = 6;
}
private final Intent mIntent;
public BrowserServicesIntentDataProvider(Intent intent) {
mIntent = intent;
}
/**
* @return the Intent this instance was created with.
*
* Not final so that it can be mocked in JUnit tests.
*/
@Nullable
public Intent getIntent() {
return mIntent;
return null;
}
/**
......@@ -384,6 +379,22 @@ public class BrowserServicesIntentDataProvider {
return null;
}
/**
* Returns {@link WebappExtras} if the intent targets a webapp, and null otherwise.
*/
@Nullable
public WebappExtras getWebappExtras() {
return null;
}
/**
* Returns {@link WebApkExtras} if the intent targets a WebAPK, and null otherwise.
*/
@Nullable
public WebApkExtras getWebApkExtras() {
return null;
}
/**
* @return Whether the bottom bar should be shown.
*/
......
......@@ -187,6 +187,7 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
+ "To make locally-built Chrome a first-party app, sign with release-test "
+ "signing keys and run on userdebug devices. See use_signing_keys GN arg.";
private final Intent mIntent;
private final CustomTabsSessionToken mSession;
private final boolean mIsTrustedIntent;
private final Intent mKeepAliveServiceIntent;
......@@ -270,8 +271,8 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
* CustomTabIntentDataProvider object must be created.
*/
public CustomTabIntentDataProvider(Intent intent, Context context, int colorScheme) {
super(intent);
if (intent == null) assert false;
mIntent = intent;
mSession = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
mIsTrustedIntent = IntentHandler.notSecureIsIntentChromeOrFirstParty(intent);
......@@ -628,6 +629,12 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid
return url;
}
@Override
@Nullable
public Intent getIntent() {
return mIntent;
}
@Override
@Nullable
public CustomTabsSessionToken getSession() {
......
// Copyright 2019 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 org.chromium.chrome.browser.webapps.WebApkInfo.ShareData;
import org.chromium.chrome.browser.webapps.WebApkInfo.ShareTarget;
import java.util.Map;
/**
* Stores WebAPK specific information on behalf of {@link BrowserServicesIntentDataProvider}.
*/
public class WebApkExtras {
/**
* The package of the WebAPK.
*/
public final String webApkPackageName;
/**
* Badge icon to use for notifications.
*/
public final WebappIcon badgeIcon;
/**
* Icon to use for the splash screen.
*/
public final WebappIcon splashIcon;
/**
* Version of the code in //chrome/android/webapk/shell_apk.
*/
public final int shellApkVersion;
/**
* URL of the Web Manifest.
*/
public final String manifestUrl;
/**
* URL that the WebAPK should navigate to when launched from the homescreen.
*/
public final String manifestStartUrl;
/** The source from where the WebAPK is installed. */
public final @WebApkDistributor int distributor;
/**
* Map of the WebAPK's icon URLs to Murmur2 hashes of the icon untransformed bytes.
*/
public final Map<String, String> iconUrlToMurmur2HashMap;
/**
* ShareTarget data for {@link shareTargetActivityName}
* TODO(pkotwicz): Remove this property in favor of
* {@link BrowserServicesIntentDataProvider#shareTarget()}
*/
public final ShareTarget shareTarget;
/**
* Name of activity or activity alias in WebAPK which handles share intents.
*/
public final String shareTargetActivityName;
/**
* Whether the WebAPK
* (1) Launches an internal activity to display the splash screen
* AND
* (2) Has a content provider which provides a screenshot of the splash screen.
*/
public final boolean isSplashProvidedByWebApk;
/**
* Shared information from the share intent.
* TODO(pkotwicz): Remove this property in favor of
* {@link BrowserServicesIntentDataProvider#shareData()}
*/
public final ShareData shareData;
/**
* WebAPK's version code.
*/
public final int webApkVersionCode;
public static WebApkExtras createEmpty() {
return new WebApkExtras(null /* webApkPackageName */, new WebappIcon(), new WebappIcon(),
0 /* shellApkVersion */, null /* manifestUrl */, null /* manifestStartUrl */,
WebApkDistributor.OTHER, null /* iconUrlToMurmur2HashMap */, new ShareTarget(),
null /* shareTargetActivityName */, false /* isSplashProvidedByWebApk */,
null /* shareData */, 0 /* webApkVersionCode */);
}
public WebApkExtras(String webApkPackageName, WebappIcon badgeIcon, WebappIcon splashIcon,
int shellApkVersion, String manifestUrl, String manifestStartUrl,
@WebApkDistributor int distributor, Map<String, String> iconUrlToMurmur2HashMap,
ShareTarget shareTarget, String shareTargetActivityName,
boolean isSplashProvidedByWebApk, ShareData shareData, int webApkVersionCode) {
this.webApkPackageName = webApkPackageName;
this.badgeIcon = badgeIcon;
this.splashIcon = splashIcon;
this.shellApkVersion = shellApkVersion;
this.manifestUrl = manifestUrl;
this.manifestStartUrl = manifestStartUrl;
this.distributor = distributor;
this.iconUrlToMurmur2HashMap = iconUrlToMurmur2HashMap;
this.shareTarget = shareTarget;
this.shareTargetActivityName = shareTargetActivityName;
this.isSplashProvidedByWebApk = isSplashProvidedByWebApk;
this.shareData = shareData;
this.webApkVersionCode = webApkVersionCode;
}
}
......@@ -159,7 +159,7 @@ public class WebappActivity extends SingleTabActivity {
super.onNewIntent(intent);
WebappInfo newWebappInfo = popWebappInfo(WebappInfo.idFromIntent(intent));
WebappInfo newWebappInfo = popWebappInfo(WebappIntentDataProvider.idFromIntent(intent));
if (newWebappInfo == null) newWebappInfo = createWebappInfo(intent);
if (newWebappInfo == null) {
......@@ -263,7 +263,7 @@ public class WebappActivity extends SingleTabActivity {
@Override
public void performPreInflationStartup() {
Intent intent = getIntent();
String id = WebappInfo.idFromIntent(intent);
String id = WebappIntentDataProvider.idFromIntent(intent);
WebappInfo info = popWebappInfo(id);
// When WebappActivity is killed by the Android OS, and an entry stays in "Android Recents"
// (The user does not swipe it away), when WebappActivity is relaunched it is relaunched
......
// Copyright 2019 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.graphics.Color;
import org.chromium.blink_public.platform.WebDisplayMode;
import org.chromium.chrome.browser.ShortcutSource;
import org.chromium.content_public.common.ScreenOrientationValues;
/**
* Stores webapp specific information on behalf of {@link BrowserServicesIntentDataProvider}.
*/
public class WebappExtras {
public final String id;
/**
* The URL to navigate to.
*/
public final String url;
/**
* The navigation scope of the webapp's application context.
*/
public final String scopeUrl;
/**
* The webapp's launcher icon.
*/
public final WebappIcon icon;
/**
* The webapp's name as it is usually displayed to the user.
*/
public final String name;
/**
* Short version of the webapp's name.
*/
public final String shortName;
public final @WebDisplayMode int displayMode;
/**
* The screen orientation to lock the webapp to.
*/
public final @ScreenOrientationValues int orientation;
/**
* If the webapp was launched from the home screen or the app list: source where the webapp was
* added from.
* Otherwise: reason that the webapp was launched (e.g. deep link).
*/
public final @ShortcutSource int source;
/**
* Theme color of the webapp.
* TODO(pkotwicz): Remove this property in favor of
* {@link BrowserServicesIntentDataProvider#getToolbarColor()}
*/
public final Integer themeColor;
/**
* Background color for webapp's splash screen.
*/
public final Integer backgroundColor;
/**
* Background color to use if the Web Manifest does not provide a background color.
*/
public final int defaultBackgroundColor;
/**
* Whether {@link icon} was generated by Chromium.
*/
public final boolean isIconGenerated;
/**
* Whether {@link #icon} should be used as an Android Adaptive icon.
*/
public final boolean isIconAdaptive;
/**
* Whether the webapp should be navigated to {@link #url} if the webapp is already open.
*/
public final boolean shouldForceNavigation;
public static WebappExtras createEmpty() {
return new WebappExtras(null /* id */, null /* url */, null /* scopeUrl */,
new WebappIcon(), null /* name */, null /* shortName */, WebDisplayMode.UNDEFINED,
ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, null /* themeColor */,
null /* backgroundColor */, Color.WHITE /* defaultBackgroundColor */,
false /* isIconGenerated */, false /* isIconAdaptive */,
false /* shouldForceNavigation */);
}
public WebappExtras(String id, String url, String scopeUrl, WebappIcon icon, String name,
String shortName, @WebDisplayMode int displayMode, int orientation, int source,
Integer themeColor, Integer backgroundColor, int defaultBackgroundColor,
boolean isIconGenerated, boolean isIconAdaptive, boolean shouldForceNavigation) {
this.id = id;
this.url = url;
this.scopeUrl = scopeUrl;
this.icon = icon;
this.name = name;
this.shortName = shortName;
this.displayMode = displayMode;
this.orientation = orientation;
this.source = source;
this.themeColor = themeColor;
this.backgroundColor = backgroundColor;
this.defaultBackgroundColor = defaultBackgroundColor;
this.isIconGenerated = isIconGenerated;
this.isIconAdaptive = isIconAdaptive;
this.shouldForceNavigation = shouldForceNavigation;
}
}
// Copyright 2019 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.Intent;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.blink_public.platform.WebDisplayMode;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.ShortcutSource;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.content_public.common.ScreenOrientationValues;
import org.chromium.webapk.lib.common.splash.SplashLayout;
/**
* Stores info about a web app.
*/
public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider {
private static final String TAG = "WebappInfo";
private WebappExtras mWebappExtras;
public static WebappIntentDataProvider createEmpty() {
return new WebappIntentDataProvider(WebappExtras.createEmpty());
}
/**
* Converts color from signed Integer where an unspecified color is represented as null to
* to unsigned long where an unspecified color is represented as
* {@link ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING}.
*/
public static long longColorFromIntegerColor(Integer color) {
if (color != null) {
// Convert signed int to unsigned long.
return (color.intValue() & 0xffffffffL);
}
return ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING;
}
/**
* Converts color from unsigned long where an unspecified color is represented as
* {@link ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING} to a signed Integer where an
* unspecified color is represented as null.
*/
public static Integer integerColorFromLongColor(long longColor) {
return (longColor == ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING)
? null
: Integer.valueOf((int) longColor);
}
public static String idFromIntent(Intent intent) {
return IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_ID);
}
private static int sourceFromIntent(Intent intent) {
int source = IntentUtils.safeGetIntExtra(
intent, ShortcutHelper.EXTRA_SOURCE, ShortcutSource.UNKNOWN);
if (source >= ShortcutSource.COUNT) {
source = ShortcutSource.UNKNOWN;
}
return source;
}
private static String titleFromIntent(Intent intent) {
// The reference to title has been kept for reasons of backward compatibility. For intents
// and shortcuts which were created before we utilized the concept of name and shortName,
// we set the name and shortName to be the title.
String title = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_TITLE);
return title == null ? "" : title;
}
private static String nameFromIntent(Intent intent) {
String name = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_NAME);
return name == null ? titleFromIntent(intent) : name;
}
private static String shortNameFromIntent(Intent intent) {
String shortName = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_SHORT_NAME);
return shortName == null ? titleFromIntent(intent) : shortName;
}
/**
* Construct a WebappIntentDataProvider.
* @param intent Intent containing info about the app.
*/
public static WebappIntentDataProvider create(Intent intent) {
String id = idFromIntent(intent);
String url = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_URL);
if (id == null || url == null) {
Log.e(TAG, "Incomplete data provided: " + id + ", " + url);
return null;
}
String icon = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_ICON);
String scope = IntentUtils.safeGetStringExtra(intent, ShortcutHelper.EXTRA_SCOPE);
if (TextUtils.isEmpty(scope)) {
scope = ShortcutHelper.getScopeFromUrl(url);
}
@WebDisplayMode
int displayMode = IntentUtils.safeGetIntExtra(
intent, ShortcutHelper.EXTRA_DISPLAY_MODE, WebDisplayMode.STANDALONE);
int orientation = IntentUtils.safeGetIntExtra(
intent, ShortcutHelper.EXTRA_ORIENTATION, ScreenOrientationValues.DEFAULT);
int source = sourceFromIntent(intent);
Integer themeColor = integerColorFromLongColor(
IntentUtils.safeGetLongExtra(intent, ShortcutHelper.EXTRA_THEME_COLOR,
ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING));
Integer backgroundColor = integerColorFromLongColor(
IntentUtils.safeGetLongExtra(intent, ShortcutHelper.EXTRA_BACKGROUND_COLOR,
ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING));
boolean isIconGenerated = IntentUtils.safeGetBooleanExtra(
intent, ShortcutHelper.EXTRA_IS_ICON_GENERATED, false);
boolean isIconAdaptive = IntentUtils.safeGetBooleanExtra(
intent, ShortcutHelper.EXTRA_IS_ICON_ADAPTIVE, false);
boolean forceNavigation = IntentUtils.safeGetBooleanExtra(
intent, ShortcutHelper.EXTRA_FORCE_NAVIGATION, false);
String name = nameFromIntent(intent);
String shortName = shortNameFromIntent(intent);
int defaultBackgroundColor =
SplashLayout.getDefaultBackgroundColor(ContextUtils.getApplicationContext());
WebappExtras webappExtras = new WebappExtras(id, url, scope, new WebappIcon(icon), name,
shortName, displayMode, orientation, source, themeColor, backgroundColor,
defaultBackgroundColor, isIconGenerated, isIconAdaptive, forceNavigation);
return new WebappIntentDataProvider(webappExtras);
}
private WebappIntentDataProvider(WebappExtras webappExtras) {
mWebappExtras = webappExtras;
}
@Override
@Nullable
public WebappExtras getWebappExtras() {
return mWebappExtras;
}
}
......@@ -370,10 +370,10 @@ public class WebApkInfoTest {
String name = "WebAPK name";
String shortName = "WebAPK short name";
FakeResources res = new FakeResources();
res.addStringForTesting(WebApkInfo.RESOURCE_NAME, WebApkInfo.RESOURCE_STRING_TYPE,
WEBAPK_PACKAGE_NAME, 1, name);
res.addStringForTesting(WebApkInfo.RESOURCE_SHORT_NAME, WebApkInfo.RESOURCE_STRING_TYPE,
WEBAPK_PACKAGE_NAME, 2, shortName);
res.addStringForTesting(WebApkIntentDataProvider.RESOURCE_NAME,
WebApkIntentDataProvider.RESOURCE_STRING_TYPE, WEBAPK_PACKAGE_NAME, 1, name);
res.addStringForTesting(WebApkIntentDataProvider.RESOURCE_SHORT_NAME,
WebApkIntentDataProvider.RESOURCE_STRING_TYPE, WEBAPK_PACKAGE_NAME, 2, shortName);
WebApkTestHelper.setResource(WEBAPK_PACKAGE_NAME, res);
Intent intent = new Intent();
......
......@@ -896,6 +896,17 @@ public class WebApkUpdateManagerUnitTest {
assertTrue(checkUpdateNeededForFetchedManifest(fetchedV1ShareTarget, oldNoShareTarget));
}
/** Test that an upgrade is requested when the Web Manifest 'scope' changes. */
@Test
public void testManifestScopeChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
// webapk_installer.cc sets the scope to the default scope if the scope is empty.
oldData.scopeUrl = "/scope1/";
ManifestData fetchedData = defaultManifestData();
fetchedData.scopeUrl = "/scope2/";
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/**
* Test that an upgrade is not requested when the Web Manifest did not change and the Web
* Manifest scope is empty.
......@@ -1039,6 +1050,62 @@ public class WebApkUpdateManagerUnitTest {
assertFalse(checkUpdateNeededForFetchedManifest(androidManifestData, fetchedManifestData));
}
/** Test that an upgrade is requested when the Web Manifest 'short_name' changes. */
@Test
public void testManifestShortNameChangedShouldUpgrade() {
ManifestData fetchedData = defaultManifestData();
fetchedData.shortName = SHORT_NAME + "2";
assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fetchedData));
}
/** Test that an upgrade is requested when the Web Manifest 'name' changes. */
@Test
public void testManifestNameChangedShouldUpgrade() {
ManifestData fetchedData = defaultManifestData();
fetchedData.name = NAME + "2";
assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fetchedData));
}
/** Test that an upgrade is requested when the Web Manifest 'display' changes. */
@Test
public void testManifestDisplayModeChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
oldData.displayMode = WebDisplayMode.STANDALONE;
ManifestData fetchedData = defaultManifestData();
fetchedData.displayMode = WebDisplayMode.FULLSCREEN;
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/** Test that an upgrade is requested when the Web Manifest 'orientation' changes. */
@Test
public void testManifestOrientationChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
oldData.orientation = ScreenOrientationValues.LANDSCAPE;
ManifestData fetchedData = defaultManifestData();
fetchedData.orientation = ScreenOrientationValues.PORTRAIT;
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/** Test that an upgrade is requested when the Web Manifest 'theme_color' changes. */
@Test
public void testManifestThemeColorChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
oldData.themeColor = 1L;
ManifestData fetchedData = defaultManifestData();
fetchedData.themeColor = 2L;
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/** Test that an upgrade is requested when the Web Manifest 'background_color' changes. */
@Test
public void testManifestBackgroundColorChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
oldData.backgroundColor = 1L;
ManifestData fetchedData = defaultManifestData();
fetchedData.backgroundColor = 2L;
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/**
* Test that an upgrade is not requested if the AndroidManifest does not have a valid background
* color and the default background color in the WebAPK's resources is different than
......@@ -1046,7 +1113,7 @@ public class WebApkUpdateManagerUnitTest {
* {@link SplashLayout#getDefaultBackgroundColor()} in a new Chrome version).
*/
@Test
public void testDefaultBackgroundColorHasChangedShouldUpgrade() {
public void testDefaultBackgroundColorHasChangedShouldNotUpgrade() {
int oldDefaultBackgroundColor = 3;
int splashLayoutDefaultBackgroundColor =
SplashLayout.getDefaultBackgroundColor(RuntimeEnvironment.application);
......@@ -1063,6 +1130,16 @@ public class WebApkUpdateManagerUnitTest {
assertFalse(checkUpdateNeededForFetchedManifest(androidManifestData, fetchedManifestData));
}
/** Test that an upgrade is requested when the Web Manifest 'start_url' changes. */
@Test
public void testManifestStartUrlChangedShouldUpgrade() {
ManifestData oldData = defaultManifestData();
oldData.startUrl = "/old_start_url.html";
ManifestData fetchedData = defaultManifestData();
fetchedData.startUrl = "/new_start_url.html";
assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
}
/**
* Tests that a WebAPK update is requested immediately if:
* the Shell APK is out of date,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment