OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 android.content.Context; | 7 import android.content.Context; |
8 import android.content.Intent; | 8 import android.content.Intent; |
9 import android.content.SharedPreferences; | 9 import android.content.SharedPreferences; |
10 import android.graphics.Bitmap; | 10 import android.graphics.Bitmap; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 // updates less frequently. crbug.com/680128. | 77 // updates less frequently. crbug.com/680128. |
78 public static final long RELAXED_UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(30
L); | 78 public static final long RELAXED_UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(30
L); |
79 | 79 |
80 // Number of milliseconds to wait before re-requesting an updated WebAPK fro
m the WebAPK | 80 // Number of milliseconds to wait before re-requesting an updated WebAPK fro
m the WebAPK |
81 // server if the previous update attempt failed. | 81 // server if the previous update attempt failed. |
82 public static final long RETRY_UPDATE_DURATION = TimeUnit.HOURS.toMillis(12L
); | 82 public static final long RETRY_UPDATE_DURATION = TimeUnit.HOURS.toMillis(12L
); |
83 | 83 |
84 // The default shell Apk version of WebAPKs. | 84 // The default shell Apk version of WebAPKs. |
85 static final int DEFAULT_SHELL_APK_VERSION = 1; | 85 static final int DEFAULT_SHELL_APK_VERSION = 1; |
86 | 86 |
87 // Unset/invalid constants for last used times and URLs. 0 is used as the nu
ll last used time as | 87 // Invalid constants for timestamps and URLs. '0' is used as the invalid tim
estamp as |
88 // WebappRegistry assumes that this is always a valid timestamp. | 88 // WebappRegistry and WebApkUpdateManager assume that timestamps are always
valid. |
89 static final long LAST_USED_UNSET = 0; | 89 static final long TIMESTAMP_INVALID = 0; |
90 static final long LAST_USED_INVALID = -1; | |
91 static final String URL_INVALID = ""; | 90 static final String URL_INVALID = ""; |
92 static final int VERSION_INVALID = 0; | 91 static final int VERSION_INVALID = 0; |
93 | 92 |
94 // We use a heuristic to determine whether a web app is still installed on t
he home screen, as | 93 // We use a heuristic to determine whether a web app is still installed on t
he home screen, as |
95 // there is no way to do so directly. Any web app which has been opened in t
he last ten days | 94 // there is no way to do so directly. Any web app which has been opened in t
he last ten days |
96 // is considered to be still on the home screen. | 95 // is considered to be still on the home screen. |
97 static final long WEBAPP_LAST_OPEN_MAX_TIME = TimeUnit.DAYS.toMillis(10L); | 96 static final long WEBAPP_LAST_OPEN_MAX_TIME = TimeUnit.DAYS.toMillis(10L); |
98 | 97 |
99 private static Clock sClock = new Clock(); | 98 private static Clock sClock = new Clock(); |
100 private static Factory sFactory = new Factory(); | 99 private static Factory sFactory = new Factory(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 */ | 131 */ |
133 public long currentTimeMillis() { | 132 public long currentTimeMillis() { |
134 return System.currentTimeMillis(); | 133 return System.currentTimeMillis(); |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 /** | 137 /** |
139 * Opens an instance of WebappDataStorage for the web app specified. | 138 * Opens an instance of WebappDataStorage for the web app specified. |
140 * @param webappId The ID of the web app. | 139 * @param webappId The ID of the web app. |
141 */ | 140 */ |
142 static WebappDataStorage open(final String webappId) { | 141 static WebappDataStorage open(String webappId) { |
143 final WebappDataStorage storage = sFactory.create(webappId); | 142 return sFactory.create(webappId); |
144 if (storage.getLastUsedTime() == LAST_USED_INVALID) { | |
145 // If the last used time is invalid then ensure that there is no dat
a in the | |
146 // WebappDataStorage which needs to be cleaned up. | |
147 assert storage.isEmpty(); | |
148 } | |
149 return storage; | |
150 } | 143 } |
151 | 144 |
152 /** | 145 /** |
153 * Sets the clock used to get the current time. | 146 * Sets the clock used to get the current time. |
154 */ | 147 */ |
155 @VisibleForTesting | 148 @VisibleForTesting |
156 public static void setClockForTests(Clock clock) { | 149 public static void setClockForTests(Clock clock) { |
157 sClock = clock; | 150 sClock = clock; |
158 } | 151 } |
159 | 152 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 mPreferences.edit().clear().apply(); | 307 mPreferences.edit().clear().apply(); |
315 } | 308 } |
316 | 309 |
317 /** | 310 /** |
318 * Deletes the URL and scope, and sets all timestamps to 0 in SharedPreferen
ces. | 311 * Deletes the URL and scope, and sets all timestamps to 0 in SharedPreferen
ces. |
319 * This does not remove the stored splash screen image (if any) for the app. | 312 * This does not remove the stored splash screen image (if any) for the app. |
320 */ | 313 */ |
321 void clearHistory() { | 314 void clearHistory() { |
322 SharedPreferences.Editor editor = mPreferences.edit(); | 315 SharedPreferences.Editor editor = mPreferences.edit(); |
323 | 316 |
324 // The last used time is set to 0 to ensure that a valid value is always
present. | 317 editor.remove(KEY_LAST_USED); |
325 // If the web app is not launched prior to the next cleanup, then its re
maining data will be | |
326 // removed. Otherwise, the next launch from home screen will update the
last used time. | |
327 editor.putLong(KEY_LAST_USED, LAST_USED_UNSET); | |
328 editor.remove(KEY_URL); | 318 editor.remove(KEY_URL); |
329 editor.remove(KEY_SCOPE); | 319 editor.remove(KEY_SCOPE); |
330 editor.remove(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME); | 320 editor.remove(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME); |
331 editor.remove(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME); | 321 editor.remove(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME); |
332 editor.remove(KEY_DID_LAST_UPDATE_REQUEST_SUCCEED); | 322 editor.remove(KEY_DID_LAST_UPDATE_REQUEST_SUCCEED); |
333 editor.remove(KEY_UPDATE_REQUESTED); | 323 editor.remove(KEY_UPDATE_REQUESTED); |
334 editor.remove(KEY_RELAX_UPDATES); | 324 editor.remove(KEY_RELAX_UPDATES); |
335 editor.remove(KEY_DISMISSED_DISCLOSURE); | 325 editor.remove(KEY_DISMISSED_DISCLOSURE); |
336 editor.apply(); | 326 editor.apply(); |
337 } | 327 } |
(...skipping 19 matching lines...) Expand all Loading... |
357 | 347 |
358 /** Updates the source. */ | 348 /** Updates the source. */ |
359 public void updateSource(int source) { | 349 public void updateSource(int source) { |
360 mPreferences.edit().putInt(KEY_SOURCE, source).apply(); | 350 mPreferences.edit().putInt(KEY_SOURCE, source).apply(); |
361 } | 351 } |
362 | 352 |
363 /** | 353 /** |
364 * Returns the last used time of this object, or -1 if it is not stored. | 354 * Returns the last used time of this object, or -1 if it is not stored. |
365 */ | 355 */ |
366 public long getLastUsedTime() { | 356 public long getLastUsedTime() { |
367 return mPreferences.getLong(KEY_LAST_USED, LAST_USED_INVALID); | 357 return mPreferences.getLong(KEY_LAST_USED, TIMESTAMP_INVALID); |
368 } | 358 } |
369 | 359 |
370 /** | 360 /** |
371 * Update the information associated with the web app with the specified dat
a. Used for testing. | 361 * Update the information associated with the web app with the specified dat
a. Used for testing. |
372 * @param splashScreenImage The image encoded as a string which should be sh
own on the splash | 362 * @param splashScreenImage The image encoded as a string which should be sh
own on the splash |
373 * screen of the web app. | 363 * screen of the web app. |
374 */ | 364 */ |
375 @VisibleForTesting | 365 @VisibleForTesting |
376 void updateSplashScreenImageForTests(String splashScreenImage) { | 366 void updateSplashScreenImageForTests(String splashScreenImage) { |
377 mPreferences.edit().putString(KEY_SPLASH_ICON, splashScreenImage).apply(
); | 367 mPreferences.edit().putString(KEY_SPLASH_ICON, splashScreenImage).apply(
); |
(...skipping 21 matching lines...) Expand all Loading... |
399 mPreferences.edit() | 389 mPreferences.edit() |
400 .putLong(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME, sClock.current
TimeMillis()) | 390 .putLong(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME, sClock.current
TimeMillis()) |
401 .apply(); | 391 .apply(); |
402 } | 392 } |
403 | 393 |
404 /** | 394 /** |
405 * Returns the completion time of the last check for whether the WebAPK's We
b Manifest was | 395 * Returns the completion time of the last check for whether the WebAPK's We
b Manifest was |
406 * updated. This time needs to be set when the WebAPK is registered. | 396 * updated. This time needs to be set when the WebAPK is registered. |
407 */ | 397 */ |
408 private long getLastCheckForWebManifestUpdateTime() { | 398 private long getLastCheckForWebManifestUpdateTime() { |
409 return mPreferences.getLong(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME, LAS
T_USED_INVALID); | 399 return mPreferences.getLong(KEY_LAST_CHECK_WEB_MANIFEST_UPDATE_TIME, TIM
ESTAMP_INVALID); |
410 } | 400 } |
411 | 401 |
412 /** | 402 /** |
413 * Updates when the last WebAPK update request finished (successfully or uns
uccessfully). | 403 * Updates when the last WebAPK update request finished (successfully or uns
uccessfully). |
414 */ | 404 */ |
415 void updateTimeOfLastWebApkUpdateRequestCompletion() { | 405 void updateTimeOfLastWebApkUpdateRequestCompletion() { |
416 mPreferences.edit() | 406 mPreferences.edit() |
417 .putLong(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME, sClock.currentTi
meMillis()) | 407 .putLong(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME, sClock.currentTi
meMillis()) |
418 .apply(); | 408 .apply(); |
419 } | 409 } |
420 | 410 |
421 /** | 411 /** |
422 * Returns when the last WebAPK update request completed (successfully or un
successfully). | 412 * Returns when the last WebAPK update request completed (successfully or un
successfully). |
423 * This time needs to be set when the WebAPK is registered. | 413 * This time needs to be set when the WebAPK is registered. |
424 */ | 414 */ |
425 long getLastWebApkUpdateRequestCompletionTime() { | 415 long getLastWebApkUpdateRequestCompletionTime() { |
426 return mPreferences.getLong(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME, LAST_
USED_INVALID); | 416 return mPreferences.getLong(KEY_LAST_UPDATE_REQUEST_COMPLETE_TIME, TIMES
TAMP_INVALID); |
427 } | 417 } |
428 | 418 |
429 /** | 419 /** |
430 * Updates whether the last update request to WebAPK Server succeeded. | 420 * Updates whether the last update request to WebAPK Server succeeded. |
431 */ | 421 */ |
432 void updateDidLastWebApkUpdateRequestSucceed(boolean success) { | 422 void updateDidLastWebApkUpdateRequestSucceed(boolean success) { |
433 mPreferences.edit().putBoolean(KEY_DID_LAST_UPDATE_REQUEST_SUCCEED, succ
ess).apply(); | 423 mPreferences.edit().putBoolean(KEY_DID_LAST_UPDATE_REQUEST_SUCCEED, succ
ess).apply(); |
434 } | 424 } |
435 | 425 |
436 /** | 426 /** |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 int getLastRequestedShellApkVersion() { | 468 int getLastRequestedShellApkVersion() { |
479 return mPreferences.getInt(KEY_LAST_REQUESTED_SHELL_APK_VERSION, DEFAULT
_SHELL_APK_VERSION); | 469 return mPreferences.getInt(KEY_LAST_REQUESTED_SHELL_APK_VERSION, DEFAULT
_SHELL_APK_VERSION); |
480 } | 470 } |
481 | 471 |
482 /** | 472 /** |
483 * Returns whether the previous WebAPK update attempt succeeded. Returns tru
e if there has not | 473 * Returns whether the previous WebAPK update attempt succeeded. Returns tru
e if there has not |
484 * been any update attempts. | 474 * been any update attempts. |
485 */ | 475 */ |
486 boolean didPreviousUpdateSucceed() { | 476 boolean didPreviousUpdateSucceed() { |
487 long lastUpdateCompletionTime = getLastWebApkUpdateRequestCompletionTime
(); | 477 long lastUpdateCompletionTime = getLastWebApkUpdateRequestCompletionTime
(); |
488 if (lastUpdateCompletionTime == WebappDataStorage.LAST_USED_INVALID) { | 478 if (lastUpdateCompletionTime == TIMESTAMP_INVALID) { |
489 return true; | 479 return true; |
490 } | 480 } |
491 return getDidLastWebApkUpdateRequestSucceed(); | 481 return getDidLastWebApkUpdateRequestSucceed(); |
492 } | 482 } |
493 | 483 |
494 /** Sets whether we should check for updates less frequently. */ | 484 /** Sets whether we should check for updates less frequently. */ |
495 void setRelaxedUpdates(boolean relaxUpdates) { | 485 void setRelaxedUpdates(boolean relaxUpdates) { |
496 mPreferences.edit().putBoolean(KEY_RELAX_UPDATES, relaxUpdates).apply(); | 486 mPreferences.edit().putBoolean(KEY_RELAX_UPDATES, relaxUpdates).apply(); |
497 } | 487 } |
498 | 488 |
(...skipping 13 matching lines...) Expand all Loading... |
512 long sinceLastUpdateRequestDurationMs = now - getLastWebApkUpdateRequest
CompletionTime(); | 502 long sinceLastUpdateRequestDurationMs = now - getLastWebApkUpdateRequest
CompletionTime(); |
513 return sinceLastUpdateRequestDurationMs >= RETRY_UPDATE_DURATION | 503 return sinceLastUpdateRequestDurationMs >= RETRY_UPDATE_DURATION |
514 && !didPreviousUpdateSucceed(); | 504 && !didPreviousUpdateSucceed(); |
515 } | 505 } |
516 | 506 |
517 protected WebappDataStorage(String webappId) { | 507 protected WebappDataStorage(String webappId) { |
518 mId = webappId; | 508 mId = webappId; |
519 mPreferences = ContextUtils.getApplicationContext().getSharedPreferences
( | 509 mPreferences = ContextUtils.getApplicationContext().getSharedPreferences
( |
520 SHARED_PREFS_FILE_PREFIX + webappId, Context.MODE_PRIVATE); | 510 SHARED_PREFS_FILE_PREFIX + webappId, Context.MODE_PRIVATE); |
521 } | 511 } |
522 | |
523 private boolean isEmpty() { | |
524 return mPreferences.getAll().isEmpty(); | |
525 } | |
526 } | 512 } |
OLD | NEW |