Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java

Issue 2460253002: Update WebAPKs even if the WebAPK start URL has no Web Manifest part 2/3 (Closed)
Patch Set: Merge branch 'master' into update_fail_refactor0 Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.webapps; 5 package org.chromium.chrome.browser.webapps;
6 6
7 import static org.junit.Assert.assertEquals; 7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertFalse; 8 import static org.junit.Assert.assertFalse;
9 import static org.junit.Assert.assertTrue; 9 import static org.junit.Assert.assertTrue;
10 10
11 import android.content.Intent;
12 import android.graphics.Bitmap;
13 import android.graphics.Color;
14 import android.os.Bundle;
11 import android.provider.Settings; 15 import android.provider.Settings;
16 import android.text.TextUtils;
12 17
13 import org.junit.Before; 18 import org.junit.Before;
14 import org.junit.Test; 19 import org.junit.Test;
15 import org.junit.runner.RunWith; 20 import org.junit.runner.RunWith;
16 import org.robolectric.RuntimeEnvironment; 21 import org.robolectric.RuntimeEnvironment;
17 import org.robolectric.annotation.Config; 22 import org.robolectric.annotation.Config;
18 import org.robolectric.shadows.ShadowApplication; 23 import org.robolectric.shadows.ShadowApplication;
24 import org.robolectric.shadows.ShadowBitmap;
19 25
20 import org.chromium.base.CommandLine; 26 import org.chromium.base.CommandLine;
21 import org.chromium.base.ContextUtils; 27 import org.chromium.base.ContextUtils;
22 import org.chromium.blink_public.platform.WebDisplayMode; 28 import org.chromium.blink_public.platform.WebDisplayMode;
23 import org.chromium.chrome.browser.ShortcutHelper; 29 import org.chromium.chrome.browser.ShortcutHelper;
24 import org.chromium.chrome.browser.ShortcutSource;
25 import org.chromium.chrome.browser.tab.Tab; 30 import org.chromium.chrome.browser.tab.Tab;
26 import org.chromium.content_public.common.ScreenOrientationValues; 31 import org.chromium.content_public.common.ScreenOrientationValues;
27 import org.chromium.testing.local.LocalRobolectricTestRunner; 32 import org.chromium.testing.local.LocalRobolectricTestRunner;
28 import org.chromium.webapk.lib.client.WebApkVersion; 33 import org.chromium.webapk.lib.client.WebApkVersion;
34 import org.chromium.webapk.lib.common.WebApkConstants;
35 import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
29 import org.chromium.webapk.test.WebApkTestHelper; 36 import org.chromium.webapk.test.WebApkTestHelper;
30 37
31 import java.util.HashMap; 38 import java.util.HashMap;
39 import java.util.Map;
32 40
33 /** 41 /**
34 * Unit tests for WebApkUpdateManager. 42 * Unit tests for WebApkUpdateManager.
35 */ 43 */
36 @RunWith(LocalRobolectricTestRunner.class) 44 @RunWith(LocalRobolectricTestRunner.class)
37 @Config(manifest = Config.NONE) 45 @Config(manifest = Config.NONE)
38 public class WebApkUpdateManagerTest { 46 public class WebApkUpdateManagerTest {
39 /** WebAPK's id in {@link WebAppDataStorage}. */ 47 /** WebAPK's id in {@link WebAppDataStorage}. */
40 private static final String WEBAPK_ID = "id"; 48 private static final String WEBAPK_ID =
49 WebApkConstants.WEBAPK_ID_PREFIX + WebApkTestHelper.WEBAPK_PACKAGE_N AME;
41 50
42 /** Value of the "name" <meta-data> tag in the Android Manifest. */ 51 /** Web Manifest URL */
43 private static final String ANDROID_MANIFEST_NAME = "Android Manifest name"; 52 private static final String WEB_MANIFEST_URL = "manifest.json";
44 53
45 /** Value of the "name" property in the Web Manifest. */ 54 private static final String START_URL = "/start_url.html";
46 private static final String WEB_MANIFEST_NAME = "Web Manifest name"; 55 private static final String SCOPE_URL = "/";
56 private static final String NAME = "Long Name";
57 private static final String SHORT_NAME = "Short Name";
58 private static final String ICON_URL = "/icon.png";
59 private static final String ICON_MURMUR2_HASH = "3";
60 private static final int DISPLAY_MODE = WebDisplayMode.Undefined;
61 private static final int ORIENTATION = ScreenOrientationValues.DEFAULT;
62 private static final long THEME_COLOR = 1L;
63 private static final long BACKGROUND_COLOR = 2L;
64
65 /** Different name than the one used in {@link defaultManifestData()}. */
66 private static final String DIFFERENT_NAME = "Different Name";
47 67
48 /** {@link WebappDataStorage#Clock} subclass which enables time to be manual ly advanced. */ 68 /** {@link WebappDataStorage#Clock} subclass which enables time to be manual ly advanced. */
49 private static class MockClock extends WebappDataStorage.Clock { 69 private static class MockClock extends WebappDataStorage.Clock {
50 // 0 has a special meaning: {@link WebappDataStorage#LAST_USED_UNSET}. 70 // 0 has a special meaning: {@link WebappDataStorage#LAST_USED_UNSET}.
51 private long mTimeMillis = 1; 71 private long mTimeMillis = 1;
52 72
53 public void advance(long millis) { 73 public void advance(long millis) {
54 mTimeMillis += millis; 74 mTimeMillis += millis;
55 } 75 }
56 76
57 @Override 77 @Override
58 public long currentTimeMillis() { 78 public long currentTimeMillis() {
59 return mTimeMillis; 79 return mTimeMillis;
60 } 80 }
61 } 81 }
62 82
63 /** Mock {@link ManifestUpgradeDetector}. */ 83 /** Mock {@link WebApkUpdateDataFetcher}. */
64 private static class TestManifestUpgradeDetector extends ManifestUpgradeDete ctor { 84 private static class TestWebApkUpdateDataFetcher extends WebApkUpdateDataFet cher {
65 private boolean mStarted; 85 private boolean mStarted;
66 86
67 public TestManifestUpgradeDetector(
68 Tab tab, WebApkInfo info, ManifestUpgradeDetector.Callback callb ack) {
69 super(tab, info, callback);
70 }
71
72 public boolean wasStarted() { 87 public boolean wasStarted() {
73 return mStarted; 88 return mStarted;
74 } 89 }
75 90
76 @Override 91 @Override
77 public boolean start() { 92 public boolean start(Tab tab, WebApkInfo oldInfo, Observer observer) {
78 mStarted = true; 93 mStarted = true;
79 return true; 94 return true;
80 } 95 }
81 } 96 }
82 97
83 private static class TestWebApkUpdateManager extends WebApkUpdateManager { 98 private static class TestWebApkUpdateManager extends WebApkUpdateManager {
84 private WebappDataStorage.Clock mClock; 99 private WebappDataStorage.Clock mClock;
85 private TestManifestUpgradeDetector mUpgradeDetector; 100 private TestWebApkUpdateDataFetcher mFetcher;
86 private int mNumUpdatesRequested; 101 private boolean mUpdateRequested;
87 private String mUpdateName; 102 private String mUpdateName;
88 private boolean mDestroyedManifestUpgradeDetector; 103 private boolean mDestroyedFetcher;
89 104
90 public TestWebApkUpdateManager(WebappDataStorage.Clock clock) { 105 public TestWebApkUpdateManager(WebappDataStorage.Clock clock) {
91 mClock = clock; 106 mClock = clock;
92 } 107 }
93 108
94 /** 109 /**
95 * Returns whether the is-update-needed check has been triggered. 110 * Returns whether the is-update-needed check has been triggered.
96 */ 111 */
97 public boolean updateCheckStarted() { 112 public boolean updateCheckStarted() {
98 return mUpgradeDetector != null && mUpgradeDetector.wasStarted(); 113 return mFetcher != null && mFetcher.wasStarted();
99 } 114 }
100 115
101 /** 116 /**
102 * Returns whether an update has been requested. 117 * Returns whether an update has been requested.
103 */ 118 */
104 public boolean updateRequested() { 119 public boolean updateRequested() {
105 return mNumUpdatesRequested > 0; 120 return mUpdateRequested;
106 } 121 }
107 122
108 /** 123 /**
109 * Returns the number of updates which have been requested.
110 */
111 public int numUpdatesRequested() {
112 return mNumUpdatesRequested;
113 }
114
115 /**
116 * Returns the "name" from the requested update. Null if an update has n ot been requested. 124 * Returns the "name" from the requested update. Null if an update has n ot been requested.
117 */ 125 */
118 public String requestedUpdateName() { 126 public String requestedUpdateName() {
119 return mUpdateName; 127 return mUpdateName;
120 } 128 }
121 129
122 public boolean destroyedManifestUpgradeDetector() { 130 public boolean destroyedFetcher() {
123 return mDestroyedManifestUpgradeDetector; 131 return mDestroyedFetcher;
124 } 132 }
125 133
126 @Override 134 @Override
127 protected ManifestUpgradeDetector buildManifestUpgradeDetector(Tab tab, WebApkInfo info) { 135 protected WebApkUpdateDataFetcher buildFetcher() {
128 mUpgradeDetector = new TestManifestUpgradeDetector(tab, info, this); 136 mFetcher = new TestWebApkUpdateDataFetcher();
129 return mUpgradeDetector; 137 return mFetcher;
130 } 138 }
131 139
132 @Override 140 @Override
133 protected void updateAsync(WebApkInfo info, String bestIconUrl) { 141 protected void updateAsync(WebApkInfo info, String bestIconUrl) {
134 ++mNumUpdatesRequested; 142 mUpdateRequested = true;
135 mUpdateName = info.name(); 143 mUpdateName = info.name();
136 } 144 }
137 145
138 @Override 146 @Override
139 protected void destroyUpgradeDetector() { 147 protected void destroyFetcher() {
140 mUpgradeDetector = null; 148 mFetcher = null;
141 mDestroyedManifestUpgradeDetector = true; 149 mDestroyedFetcher = true;
142 } 150 }
143 151
144 @Override 152 @Override
145 protected long currentTimeMillis() { 153 protected long currentTimeMillis() {
146 return mClock.currentTimeMillis(); 154 return mClock.currentTimeMillis();
147 } 155 }
156
157 // Stubbed out because real implementation uses native.
158 @Override
159 protected boolean urlsMatchIgnoringFragments(String url1, String url2) {
160 return TextUtils.equals(url1, url2);
161 }
162 }
163
164 private static class ManifestData {
165 public String startUrl;
166 public String scopeUrl;
167 public String name;
168 public String shortName;
169 public Map<String, String> iconUrlToMurmur2HashMap;
170 public String bestIconUrl;
171 public Bitmap bestIcon;
172 public int displayMode;
173 public int orientation;
174 public long themeColor;
175 public long backgroundColor;
148 } 176 }
149 177
150 private MockClock mClock; 178 private MockClock mClock;
151 private int mShellApkVersion;
152
153 /** Sets the version of the code in //chrome/android/webapk/shell_apk. */
154 public void setShellApkVersion(int shellApkVersion) {
155 mShellApkVersion = shellApkVersion;
156 }
157 179
158 private WebappDataStorage getStorage() { 180 private WebappDataStorage getStorage() {
159 return WebappRegistry.getInstance().getWebappDataStorage(WEBAPK_ID); 181 return WebappRegistry.getInstance().getWebappDataStorage(WEBAPK_ID);
160 } 182 }
161 183
162 private WebApkInfo infoWithName(String name) { 184 /**
163 return WebApkInfo.create(WEBAPK_ID, "", "", null, name, "", WebDisplayMo de.Standalone, 185 * Registers WebAPK with default package name. Overwrites previous registrat ions.
164 ScreenOrientationValues.DEFAULT, ShortcutSource.UNKNOWN, 186 * @param manifestData <meta-data> values for WebAPK's Android Manife st.
165 ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, 187 * @param shellApkVersionCode WebAPK's version of the //chrome/android/webap k/shell_apk code.
166 ShortcutHelper.MANIFEST_COLOR_INVALID_OR_MISSING, 188 */
167 WebApkTestHelper.WEBAPK_PACKAGE_NAME, mShellApkVersion, "", "", 189 private void registerWebApk(ManifestData manifestData, int shellApkVersionCo de) {
168 new HashMap<String, String>()); 190 Bundle metaData = new Bundle();
191 metaData.putInt(
192 WebApkMetaDataKeys.SHELL_APK_VERSION, shellApkVersionCode);
193 metaData.putString(WebApkMetaDataKeys.START_URL, manifestData.startUrl);
194 metaData.putString(WebApkMetaDataKeys.SCOPE, manifestData.scopeUrl);
195 metaData.putString(WebApkMetaDataKeys.NAME, manifestData.name);
196 metaData.putString(WebApkMetaDataKeys.SHORT_NAME, manifestData.shortName );
197 metaData.putString(WebApkMetaDataKeys.THEME_COLOR, manifestData.themeCol or + "L");
198 metaData.putString(WebApkMetaDataKeys.BACKGROUND_COLOR, manifestData.bac kgroundColor + "L");
199 metaData.putString(WebApkMetaDataKeys.WEB_MANIFEST_URL, WEB_MANIFEST_URL );
200
201 String iconUrlsAndIconMurmur2Hashes = "";
202 for (Map.Entry<String, String> mapEntry : manifestData.iconUrlToMurmur2H ashMap.entrySet()) {
203 String murmur2Hash = mapEntry.getValue();
204 if (murmur2Hash == null) {
205 murmur2Hash = "0";
206 }
207 iconUrlsAndIconMurmur2Hashes += " " + mapEntry.getKey() + " " + murm ur2Hash;
208 }
209 iconUrlsAndIconMurmur2Hashes = iconUrlsAndIconMurmur2Hashes.trim();
210 metaData.putString(WebApkMetaDataKeys.ICON_URLS_AND_ICON_MURMUR2_HASHES,
211 iconUrlsAndIconMurmur2Hashes);
212
213 WebApkTestHelper.registerWebApkWithMetaData(metaData);
169 } 214 }
170 215
171 private WebApkInfo fetchedWebApkInfo() { 216 private static ManifestData defaultManifestData() {
172 return infoWithName(WEB_MANIFEST_NAME); 217 ManifestData manifestData = new ManifestData();
218 manifestData.startUrl = START_URL;
219 manifestData.scopeUrl = SCOPE_URL;
220 manifestData.name = NAME;
221 manifestData.shortName = SHORT_NAME;
222
223 manifestData.iconUrlToMurmur2HashMap = new HashMap<String, String>();
224 manifestData.iconUrlToMurmur2HashMap.put(ICON_URL, ICON_MURMUR2_HASH);
225
226 manifestData.bestIconUrl = ICON_URL;
227 manifestData.bestIcon = createBitmap(Color.GREEN);
228 manifestData.displayMode = DISPLAY_MODE;
229 manifestData.orientation = ORIENTATION;
230 manifestData.themeColor = THEME_COLOR;
231 manifestData.backgroundColor = BACKGROUND_COLOR;
232 return manifestData;
173 } 233 }
174 234
175 private void updateIfNeeded(WebApkUpdateManager updateManager) { 235 private static WebApkInfo infoFromManifestData(ManifestData manifestData) {
176 WebApkInfo info = infoWithName(ANDROID_MANIFEST_NAME); 236 if (manifestData == null) return null;
237
238 return WebApkInfo.create("", "", manifestData.scopeUrl,
239 new WebApkInfo.Icon(manifestData.bestIcon), manifestData.name,
240 manifestData.shortName, manifestData.displayMode, manifestData.o rientation, -1,
241 manifestData.themeColor, manifestData.backgroundColor,
242 WebApkTestHelper.WEBAPK_PACKAGE_NAME, -1, WEB_MANIFEST_URL,
243 manifestData.startUrl, manifestData.iconUrlToMurmur2HashMap);
244 }
245
246 /**
247 * Creates 1x1 bitmap.
248 * @param color The bitmap color.
249 */
250 private static Bitmap createBitmap(int color) {
251 int colors[] = { color };
252 return ShadowBitmap.createBitmap(colors, 1, 1, Bitmap.Config.ALPHA_8);
253 }
254
255 private static void updateIfNeeded(WebApkUpdateManager updateManager) {
256 // Use the intent version of {@link WebApkInfo#create()} in order to tes t default values
257 // set by the intent version of {@link WebApkInfo#create()}.
258 Intent intent = new Intent();
259 intent.putExtra(ShortcutHelper.EXTRA_URL, "");
260 intent.putExtra(
261 ShortcutHelper.EXTRA_WEBAPK_PACKAGE_NAME, WebApkTestHelper.WEBAP K_PACKAGE_NAME);
262 WebApkInfo info = WebApkInfo.create(intent);
263
177 updateManager.updateIfNeeded(null, info); 264 updateManager.updateIfNeeded(null, info);
178 } 265 }
179 266
180 private void onGotWebApkCompatibleWebManifestForInitialUrl( 267 private static void onGotUnchangedWebManifestForInitialUrl(WebApkUpdateManag er updateManager) {
181 WebApkUpdateManager updateManager, boolean needsUpdate) { 268 onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifes tData());
269 }
270
271 private static void onFinishedFetchingWebManifestForInitialUrl(
272 WebApkUpdateManager updateManager, ManifestData fetchedManifestData) {
273 String bestIconUrl = randomIconUrl(fetchedManifestData);
182 updateManager.onFinishedFetchingWebManifestForInitialUrl( 274 updateManager.onFinishedFetchingWebManifestForInitialUrl(
183 needsUpdate, fetchedWebApkInfo(), null); 275 infoFromManifestData(fetchedManifestData), bestIconUrl);
276 }
277
278 private static void onGotManifestData(WebApkUpdateManager updateManager,
279 ManifestData fetchedManifestData) {
280 String bestIconUrl = randomIconUrl(fetchedManifestData);
281 updateManager.onGotManifestData(infoFromManifestData(fetchedManifestData ), bestIconUrl);
282 }
283
284 private static String randomIconUrl(ManifestData fetchedManifestData) {
285 if (fetchedManifestData == null || fetchedManifestData.iconUrlToMurmur2H ashMap.isEmpty()) {
286 return null;
287 }
288 return fetchedManifestData.iconUrlToMurmur2HashMap.keySet().iterator().n ext();
184 } 289 }
185 290
186 /** 291 /**
187 * Runs {@link WebApkUpdateManager#updateIfNeeded()} and returns whether an 292 * Runs {@link WebApkUpdateManager#updateIfNeeded()} and returns whether an
188 * is-update-needed check has been triggered. 293 * is-update-needed check has been triggered.
189 */ 294 */
190 private boolean updateIfNeededChecksForUpdatedWebManifest() { 295 private boolean updateIfNeededChecksForUpdatedWebManifest() {
191 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 296 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
192 updateIfNeeded(updateManager); 297 updateIfNeeded(updateManager);
193 return updateManager.updateCheckStarted(); 298 return updateManager.updateCheckStarted();
194 } 299 }
195 300
301 /**
302 * Checks whether the WebAPK is updated given data from the WebAPK's Android Manifest and data
303 * from the fetched Web Manifest.
304 */
305 private boolean checkUpdateNeededForFetchedManifest(
306 ManifestData androidManifestData, ManifestData fetchedManifestData) {
307 registerWebApk(androidManifestData, WebApkVersion.CURRENT_SHELL_APK_VERS ION);
308 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
309
310 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
311 updateIfNeeded(updateManager);
312 assertTrue(updateManager.updateCheckStarted());
313 updateManager.onFinishedFetchingWebManifestForInitialUrl(
314 infoFromManifestData(fetchedManifestData), fetchedManifestData.b estIconUrl);
315 return updateManager.updateRequested();
316 }
317
196 @Before 318 @Before
197 public void setUp() { 319 public void setUp() {
198 ContextUtils.initApplicationContextForTests(RuntimeEnvironment.applicati on); 320 ContextUtils.initApplicationContextForTests(RuntimeEnvironment.applicati on);
199 CommandLine.init(null); 321 CommandLine.init(null);
200 322
323 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE RSION);
201 Settings.Secure.putInt(RuntimeEnvironment.application.getContentResolver (), 324 Settings.Secure.putInt(RuntimeEnvironment.application.getContentResolver (),
202 Settings.Secure.INSTALL_NON_MARKET_APPS, 1); 325 Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
203 326
204 mClock = new MockClock(); 327 mClock = new MockClock();
205 WebappDataStorage.setClockForTests(mClock); 328 WebappDataStorage.setClockForTests(mClock);
206 329
207 mShellApkVersion = WebApkVersion.CURRENT_SHELL_APK_VERSION;
208
209 WebappRegistry.getInstance().register( 330 WebappRegistry.getInstance().register(
210 WEBAPK_ID, new WebappRegistry.FetchWebappDataStorageCallback() { 331 WEBAPK_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
211 @Override 332 @Override
212 public void onWebappDataStorageRetrieved(WebappDataStorage s torage) {} 333 public void onWebappDataStorageRetrieved(WebappDataStorage s torage) {}
213 }); 334 });
214 ShadowApplication.getInstance().runBackgroundTasks(); 335 ShadowApplication.getInstance().runBackgroundTasks();
215 336
216 WebappDataStorage storage = getStorage(); 337 WebappDataStorage storage = getStorage();
217 storage.updateTimeOfLastCheckForUpdatedWebManifest(); 338 storage.updateTimeOfLastCheckForUpdatedWebManifest();
218 storage.updateTimeOfLastWebApkUpdateRequestCompletion(); 339 storage.updateTimeOfLastWebApkUpdateRequestCompletion();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 } 406 }
286 407
287 // Chrome is killed. 408 // Chrome is killed.
288 // {@link WebApkUpdateManager#onFinishedFetchingWebManifestForInitialUrl ()} is never called. 409 // {@link WebApkUpdateManager#onFinishedFetchingWebManifestForInitialUrl ()} is never called.
289 410
290 { 411 {
291 // Relaunching the WebAPK should do an is-update-needed check. 412 // Relaunching the WebAPK should do an is-update-needed check.
292 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager( mClock); 413 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager( mClock);
293 updateIfNeeded(updateManager); 414 updateIfNeeded(updateManager);
294 assertTrue(updateManager.updateCheckStarted()); 415 assertTrue(updateManager.updateCheckStarted());
295 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); 416 onGotUnchangedWebManifestForInitialUrl(updateManager);
296 } 417 }
297 418
298 { 419 {
299 // Relaunching the WebAPK should not do an is-update-needed-check. 420 // Relaunching the WebAPK should not do an is-update-needed-check.
300 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager( mClock); 421 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager( mClock);
301 updateIfNeeded(updateManager); 422 updateIfNeeded(updateManager);
302 assertFalse(updateManager.updateCheckStarted()); 423 assertFalse(updateManager.updateCheckStarted());
303 } 424 }
304 } 425 }
305 426
306 /** 427 /**
307 * Test that the completion time of the previous WebAPK update is not modifi ed if: 428 * Test that the completion time of the previous WebAPK update is not modifi ed if:
308 * - The previous WebAPK update succeeded. 429 * - The previous WebAPK update succeeded.
309 * AND 430 * AND
310 * - A WebAPK update is not required. 431 * - A WebAPK update is not required.
311 */ 432 */
312 @Test 433 @Test
313 public void testUpdateNotNeeded() { 434 public void testUpdateNotNeeded() {
314 long initialTime = mClock.currentTimeMillis(); 435 long initialTime = mClock.currentTimeMillis();
315 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 436 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
316 437
317 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 438 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
318 updateIfNeeded(updateManager); 439 updateIfNeeded(updateManager);
319 assertTrue(updateManager.updateCheckStarted()); 440 assertTrue(updateManager.updateCheckStarted());
320 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); 441 onGotUnchangedWebManifestForInitialUrl(updateManager);
321 assertFalse(updateManager.updateRequested()); 442 assertFalse(updateManager.updateRequested());
322 443
323 WebappDataStorage storage = getStorage(); 444 WebappDataStorage storage = getStorage();
324 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); 445 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed());
325 assertEquals(initialTime, storage.getLastWebApkUpdateRequestCompletionTi me()); 446 assertEquals(initialTime, storage.getLastWebApkUpdateRequestCompletionTi me());
326 } 447 }
327 448
328 /** 449 /**
329 * Test that the last WebAPK update is marked as having succeeded if: 450 * Test that the last WebAPK update is marked as having succeeded if:
330 * - The previous WebAPK update failed. 451 * - The previous WebAPK update failed.
331 * AND 452 * AND
332 * - A WebAPK update is no longer required. 453 * - A WebAPK update is no longer required.
333 */ 454 */
334 @Test 455 @Test
335 public void testMarkUpdateAsSucceededIfUpdateNoLongerNeeded() { 456 public void testMarkUpdateAsSucceededIfUpdateNoLongerNeeded() {
336 WebappDataStorage storage = getStorage(); 457 WebappDataStorage storage = getStorage();
337 storage.updateDidLastWebApkUpdateRequestSucceed(false); 458 storage.updateDidLastWebApkUpdateRequestSucceed(false);
338 mClock.advance(WebApkUpdateManager.RETRY_UPDATE_DURATION); 459 mClock.advance(WebApkUpdateManager.RETRY_UPDATE_DURATION);
339 460
340 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 461 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
341 updateIfNeeded(updateManager); 462 updateIfNeeded(updateManager);
342 assertTrue(updateManager.updateCheckStarted()); 463 assertTrue(updateManager.updateCheckStarted());
343 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, false); 464 onGotUnchangedWebManifestForInitialUrl(updateManager);
344 assertFalse(updateManager.updateRequested()); 465 assertFalse(updateManager.updateRequested());
345 466
346 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); 467 assertTrue(storage.getDidLastWebApkUpdateRequestSucceed());
347 assertEquals( 468 assertEquals(
348 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo mpletionTime()); 469 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo mpletionTime());
349 } 470 }
350 471
351 /** 472 /**
352 * Test that the WebAPK update is marked as having failed if Chrome is kille d prior to the 473 * Test that the WebAPK update is marked as having failed if Chrome is kille d prior to the
353 * WebAPK update completing. 474 * WebAPK update completing.
354 */ 475 */
355 @Test 476 @Test
356 public void testMarkUpdateAsFailedIfClosePriorToUpdateCompleting() { 477 public void testMarkUpdateAsFailedIfClosePriorToUpdateCompleting() {
357 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 478 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
358 479
359 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 480 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
360 updateIfNeeded(updateManager); 481 updateIfNeeded(updateManager);
361 assertTrue(updateManager.updateCheckStarted()); 482 assertTrue(updateManager.updateCheckStarted());
362 onGotWebApkCompatibleWebManifestForInitialUrl(updateManager, true); 483 ManifestData manifestData = defaultManifestData();
484 manifestData.name = DIFFERENT_NAME;
485 onFinishedFetchingWebManifestForInitialUrl(updateManager, manifestData);
363 assertTrue(updateManager.updateRequested()); 486 assertTrue(updateManager.updateRequested());
364 487
365 // Chrome is killed. {@link WebApkUpdateManager#onBuiltWebApk} is never called. 488 // Chrome is killed. {@link WebApkUpdateManager#onBuiltWebApk} is never called.
366 489
367 // Check {@link WebappDataStorage} state. 490 // Check {@link WebappDataStorage} state.
368 WebappDataStorage storage = getStorage(); 491 WebappDataStorage storage = getStorage();
369 assertFalse(storage.getDidLastWebApkUpdateRequestSucceed()); 492 assertFalse(storage.getDidLastWebApkUpdateRequestSucceed());
370 assertEquals( 493 assertEquals(
371 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo mpletionTime()); 494 mClock.currentTimeMillis(), storage.getLastWebApkUpdateRequestCo mpletionTime());
372 } 495 }
373 496
374 /** 497 /**
375 * Test that an update with data from the WebAPK's Android manifest is done if: 498 * Test that an update with data from the WebAPK's Android manifest is done if:
376 * - WebAPK's code is out of date 499 * - WebAPK's code is out of date
377 * AND 500 * AND
378 * - WebAPK's start_url does not refer to a Web Manifest. 501 * - WebAPK's start_url does not refer to a Web Manifest.
379 * 502 *
380 * It is good to minimize the number of users with out of date WebAPKs. We t ry to keep WebAPKs 503 * It is good to minimize the number of users with out of date WebAPKs. We t ry to keep WebAPKs
381 * up to date even if the web developer has removed the Web Manifest from th eir site. 504 * up to date even if the web developer has removed the Web Manifest from th eir site.
382 */ 505 */
383 @Test 506 @Test
384 public void testShellApkOutOfDateNoWebManifest() { 507 public void testShellApkOutOfDateNoWebManifest() {
385 setShellApkVersion(WebApkVersion.CURRENT_SHELL_APK_VERSION - 1); 508 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE RSION - 1);
386 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 509 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
387 510
388 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 511 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
389 updateIfNeeded(updateManager); 512 updateIfNeeded(updateManager);
390 assertTrue(updateManager.updateCheckStarted()); 513 assertTrue(updateManager.updateCheckStarted());
391 514
392 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu ll); 515 onFinishedFetchingWebManifestForInitialUrl(updateManager, null);
393 assertTrue(updateManager.updateRequested()); 516 assertTrue(updateManager.updateRequested());
394 assertEquals(ANDROID_MANIFEST_NAME, updateManager.requestedUpdateName()) ; 517 assertEquals(NAME, updateManager.requestedUpdateName());
395 518
396 // Check that the {@link ManifestUpgradeDetector} has been destroyed. Th is prevents 519 // Check that the {@link ManifestUpgradeDetector} has been destroyed. Th is prevents
397 // {@link #onFinishedFetchingWebManifestForInitialUrl()} and {@link #onG otManifestData()} 520 // {@link #onFinishedFetchingWebManifestForInitialUrl()} and {@link #onG otManifestData()}
398 // from getting called. 521 // from getting called.
399 assertTrue(updateManager.destroyedManifestUpgradeDetector()); 522 assertTrue(updateManager.destroyedFetcher());
400 } 523 }
401 524
402 /** 525 /**
403 * Test that an update with data from the fetched Web Manifest is done if th e WebAPK's code is 526 * Test that an update with data from the fetched Web Manifest is done if th e WebAPK's code is
404 * out of date and the WebAPK's start_url refers to a Web Manifest. 527 * out of date and the WebAPK's start_url refers to a Web Manifest.
405 */ 528 */
406 @Test 529 @Test
407 public void testShellApkOutOfDateStillHasWebManifest() { 530 public void testShellApkOutOfDateStillHasWebManifest() {
408 setShellApkVersion(WebApkVersion.CURRENT_SHELL_APK_VERSION - 1); 531 registerWebApk(defaultManifestData(), WebApkVersion.CURRENT_SHELL_APK_VE RSION - 1);
409 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 532 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
410 533
411 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 534 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
412 updateIfNeeded(updateManager); 535 updateIfNeeded(updateManager);
413 assertTrue(updateManager.updateCheckStarted()); 536 assertTrue(updateManager.updateCheckStarted());
414 537
415 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, fetchedW ebApkInfo(), null); 538 onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifes tData());
416 assertTrue(updateManager.updateRequested()); 539 assertTrue(updateManager.updateRequested());
417 assertEquals(WEB_MANIFEST_NAME, updateManager.requestedUpdateName()); 540 assertEquals(NAME, updateManager.requestedUpdateName());
418 541
419 assertTrue(updateManager.destroyedManifestUpgradeDetector()); 542 assertTrue(updateManager.destroyedFetcher());
420 } 543 }
421 544
422 /** 545 /**
423 * Test that an update is requested if: 546 * Test that an update is requested if:
424 * - start_url does not refer to a Web Manifest. 547 * - start_url does not refer to a Web Manifest.
425 * AND 548 * AND
426 * - The user eventually navigates to a page pointing to a Web Manifest with the correct URL. 549 * - The user eventually navigates to a page pointing to a Web Manifest with the correct URL.
427 * AND 550 * AND
428 * - The Web Manifest has changed. 551 * - The Web Manifest has changed.
429 * 552 *
430 * This scenario can occur if the WebAPK's start_url is a Javascript redirec t. 553 * This scenario can occur if the WebAPK's start_url is a Javascript redirec t.
431 */ 554 */
432 @Test 555 @Test
433 public void testStartUrlRedirectsToPageWithUpdatedWebManifest() { 556 public void testStartUrlRedirectsToPageWithUpdatedWebManifest() {
434 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 557 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
435 558
436 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 559 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
437 updateIfNeeded(updateManager); 560 updateIfNeeded(updateManager);
438 assertTrue(updateManager.updateCheckStarted()); 561 assertTrue(updateManager.updateCheckStarted());
439 562
440 // start_url does not have a Web Manifest. No update should be requested . 563 // start_url does not have a Web Manifest. No update should be requested .
441 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu ll); 564 onFinishedFetchingWebManifestForInitialUrl(updateManager, null);
442 assertFalse(updateManager.updateRequested()); 565 assertFalse(updateManager.updateRequested());
443 // {@link ManifestUpgradeDetector} should still be alive so that it can get 566 // {@link ManifestUpgradeDetector} should still be alive so that it can get
444 // {@link #onGotManifestData} when page with the Web Manifest finishes l oading. 567 // {@link #onGotManifestData} when page with the Web Manifest finishes l oading.
445 assertFalse(updateManager.destroyedManifestUpgradeDetector()); 568 assertFalse(updateManager.destroyedFetcher());
446 569
447 // start_url redirects to page with Web Manifest. 570 // start_url redirects to page with Web Manifest.
448 571
449 updateManager.onGotManifestData(true, fetchedWebApkInfo(), null); 572 ManifestData manifestData = defaultManifestData();
573 manifestData.name = DIFFERENT_NAME;
574 onGotManifestData(updateManager, manifestData);
450 assertTrue(updateManager.updateRequested()); 575 assertTrue(updateManager.updateRequested());
451 assertEquals(WEB_MANIFEST_NAME, updateManager.requestedUpdateName()); 576 assertEquals(DIFFERENT_NAME, updateManager.requestedUpdateName());
452 577
453 assertTrue(updateManager.destroyedManifestUpgradeDetector()); 578 assertTrue(updateManager.destroyedFetcher());
454 } 579 }
455 580
456 /** 581 /**
457 * Test than an update is not requested if: 582 * Test that an update is not requested if:
458 * - start_url does not refer to a Web Manifest. 583 * - start_url does not refer to a Web Manifest.
459 * AND 584 * AND
460 * - The user eventually navigates to a page pointing to a Web Manifest with the correct URL. 585 * - The user eventually navigates to a page pointing to a Web Manifest with the correct URL.
461 * AND 586 * AND
462 * - The Web Manifest has not changed. 587 * - The Web Manifest has not changed.
463 */ 588 */
464 @Test 589 @Test
465 public void testStartUrlRedirectsToPageWithUnchangedWebManifest() { 590 public void testStartUrlRedirectsToPageWithUnchangedWebManifest() {
466 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL); 591 mClock.advance(WebApkUpdateManager.FULL_CHECK_UPDATE_INTERVAL);
467 592
468 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck); 593 TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClo ck);
469 updateIfNeeded(updateManager); 594 updateIfNeeded(updateManager);
470 updateManager.onFinishedFetchingWebManifestForInitialUrl(false, null, nu ll); 595 onFinishedFetchingWebManifestForInitialUrl(updateManager, null);
471 updateManager.onGotManifestData(false, fetchedWebApkInfo(), null); 596 onGotManifestData(updateManager, defaultManifestData());
472 assertFalse(updateManager.updateRequested()); 597 assertFalse(updateManager.updateRequested());
473 598
474 // We got the Web Manifest. The {@link ManifestUpgradeDetector} should b e destroyed to stop 599 // We got the Web Manifest. The {@link ManifestUpgradeDetector} should b e destroyed to stop
475 // it from fetching the Web Manifest for subsequent page loads. 600 // it from fetching the Web Manifest for subsequent page loads.
476 assertTrue(updateManager.destroyedManifestUpgradeDetector()); 601 assertTrue(updateManager.destroyedFetcher());
602 }
603
604 @Test
605 public void testManifestDoesNotUpgrade() {
606 assertFalse(
607 checkUpdateNeededForFetchedManifest(defaultManifestData(), defau ltManifestData()));
608 }
609
610 /**
611 * Test that an upgrade is not requested when the Web Manifest did not chang e and the Web
612 * Manifest scope is empty.
613 */
614 @Test
615 public void testManifestEmptyScopeShouldNotUpgrade() {
616 ManifestData oldData = defaultManifestData();
617 // webapk_installer.cc sets the scope to the default scope if the scope is empty.
618 oldData.scopeUrl = ShortcutHelper.getScopeFromUrl(oldData.startUrl);
619 ManifestData fetchedData = defaultManifestData();
620 fetchedData.scopeUrl = "";
621 assertTrue(!oldData.scopeUrl.equals(fetchedData.scopeUrl));
622 assertFalse(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
623 }
624
625 /**
626 * Test that an upgrade is requested when the Web Manifest is updated from u sing a non-empty
627 * scope to an empty scope.
628 */
629 @Test
630 public void testManifestNonEmptyScopeToEmptyScopeShouldUpgrade() {
631 ManifestData oldData = defaultManifestData();
632 oldData.startUrl = "/fancy/scope/special/snowflake.html";
633 oldData.scopeUrl = "/fancy/scope/";
634 assertTrue(
635 !oldData.scopeUrl.equals(ShortcutHelper.getScopeFromUrl(oldData. startUrl)));
636 ManifestData fetchedData = defaultManifestData();
637 fetchedData.startUrl = "/fancy/scope/special/snowflake.html";
638 fetchedData.scopeUrl = "";
639
640 assertTrue(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
641 }
642
643 /**
644 * Test that an upgrade is requested when:
645 * - WebAPK was generated using icon at {@link ICON_URL} from Web Manifest.
646 * - Bitmap at {@link ICON_URL} has changed.
647 */
648 @Test
649 public void testHomescreenIconChangeShouldUpgrade() {
650 ManifestData fetchedData = defaultManifestData();
651 fetchedData.iconUrlToMurmur2HashMap.put(fetchedData.bestIconUrl, ICON_MU RMUR2_HASH + "1");
652 fetchedData.bestIcon = createBitmap(Color.BLUE);
653 assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fe tchedData));
654 }
655
656 /**
657 * Test that an upgrade is requested when:
658 * - WebAPK is generated using icon at {@link ICON_URL} from Web Manifest.
659 * - Web Manifest is updated to refer to different icon.
660 */
661 @Test
662 public void testHomescreenBestIconUrlChangeShouldUpgrade() {
663 ManifestData fetchedData = defaultManifestData();
664 fetchedData.iconUrlToMurmur2HashMap.clear();
665 fetchedData.iconUrlToMurmur2HashMap.put("/icon2.png", "22");
666 fetchedData.bestIconUrl = "/icon2.png";
667 assertTrue(checkUpdateNeededForFetchedManifest(defaultManifestData(), fe tchedData));
668 }
669
670 /**
671 * Test that an upgrade is not requested if:
672 * - icon URL is added to the Web Manifest
673 * AND
674 * - "best" icon URL for the launcher icon did not change.
675 */
676 @Test
677 public void testIconUrlsChangeShouldNotUpgradeIfTheBestIconUrlDoesNotChange( ) {
678 ManifestData fetchedData = defaultManifestData();
679 fetchedData.iconUrlToMurmur2HashMap.clear();
680 fetchedData.iconUrlToMurmur2HashMap.put(ICON_URL, ICON_MURMUR2_HASH);
681 fetchedData.iconUrlToMurmur2HashMap.put("/icon2.png", null);
682 assertFalse(checkUpdateNeededForFetchedManifest(defaultManifestData(), f etchedData));
683 }
684
685 /**
686 * Test than upgrade is requested if:
687 * - the WebAPK's meta data has murmur2 hashes for all of the icons.
688 * AND
689 * - the Web Manifest has not changed
690 * AND
691 * - the computed best icon URL is different from the one stored in the WebA PK's meta data.
692 */
693 @Test
694 public void testWebManifestSameButBestIconUrlChangedShouldNotUpgrade() {
695 String iconUrl1 = "/icon1.png";
696 String iconUrl2 = "/icon2.png";
697 String hash1 = "11";
698 String hash2 = "22";
699
700 ManifestData oldData = defaultManifestData();
701 oldData.bestIconUrl = iconUrl1;
702 oldData.iconUrlToMurmur2HashMap.clear();
703 oldData.iconUrlToMurmur2HashMap.put(iconUrl1, hash1);
704 oldData.iconUrlToMurmur2HashMap.put(iconUrl2, hash2);
705
706 ManifestData fetchedData = defaultManifestData();
707 fetchedData.bestIconUrl = iconUrl2;
708 fetchedData.iconUrlToMurmur2HashMap.clear();
709 fetchedData.iconUrlToMurmur2HashMap.put(iconUrl1, null);
710 fetchedData.iconUrlToMurmur2HashMap.put(iconUrl2, hash2);
711
712 assertFalse(checkUpdateNeededForFetchedManifest(oldData, fetchedData));
477 } 713 }
478 } 714 }
OLDNEW
« no previous file with comments | « chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java ('k') | chrome/browser/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698