Commit 78cf6596 authored by dominickn's avatar dominickn Committed by Commit bot

Refactor WebappRegistry into a singleton instance.

This CL refactors WebappRegistry and WebappDataStorage to make most of
the methods synchronous. WebappRegistry is now a singleton instance that
is instantiated at browser startup. This allows all SharedPreferences files to
be pre-warmed before the class is used; new web apps open new
SharedPreferences on a background thread when registered, after which the
preferences are cached automatically.

Most static methods on WebappRegistry and WebappDataStorage have been
converted to instance methods or removed. This makes the code much
cleaner and more efficient; each static method had to independently open
their SharedPreferences, which minimally performs a stat() on the
underlying XML file to see if it has changed. Now the singleton
WebappRegistry caches all WebappDataStorage objects on startup and
whenever new ones are added. This reduces disk IO overhead.

This CL allows all calls to SharedPreferences.Editor.apply() in
WebappRegistry and WebappDataStorage to occur on the main thread,
mostly removing the need for unwieldy callback interfaces and bare
pointer passing across the JNI.

BUG=633791

Review-Url: https://codereview.chromium.org/2351113005
Cr-Commit-Position: refs/heads/master@{#422703}
parent d6b7b063
......@@ -48,6 +48,7 @@ import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager
import org.chromium.chrome.browser.share.ShareHelper;
import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
import org.chromium.chrome.browser.webapps.WebApkVersionManager;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.content.browser.ChildProcessLauncher;
import java.util.ArrayList;
......@@ -175,6 +176,10 @@ public class DeferredStartupHandler {
mDeferredTasks.add(new Runnable() {
@Override
public void run() {
// Initialize the WebappRegistry if it's not already initialized. Must be done on
// the main thread.
WebappRegistry.getInstance();
// Punt all tasks that may block on disk off onto a background thread.
initAsyncDiskTask();
......@@ -278,11 +283,21 @@ public class DeferredStartupHandler {
SystemClock.uptimeMillis() - asyncTaskStartTime,
TimeUnit.MILLISECONDS);
// Warm up all web app shared prefs. This must be run after the WebappRegistry
// instance is initialized.
WebappRegistry.warmUpSharedPrefs();
return null;
} finally {
TraceEvent.end("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
}
}
@Override
protected void onPostExecute(Void params) {
// Must be run on the UI thread after the WebappRegistry has been completely warmed.
WebappRegistry.getInstance().unregisterOldWebapps(System.currentTimeMillis());
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
......
......@@ -16,7 +16,6 @@ import org.chromium.chrome.browser.tabmodel.document.AsyncTabCreationParams;
import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.chrome.browser.webapps.WebappRegistry.FetchWebappDataStorageCallback;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.common.Referrer;
......@@ -74,49 +73,46 @@ public class ServiceTabLauncher {
// 2. Launch WebappActivity if one matches the target URL and was opened recently.
// Otherwise, open the URL in a tab.
FetchWebappDataStorageCallback callback = new FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(final WebappDataStorage storage) {
// If we do not find a WebappDataStorage corresponding to this URL, or if it hasn't
// been opened recently enough, open the URL in a tab.
if (storage == null || !storage.wasLaunchedRecently()) {
LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.LINK);
loadUrlParams.setPostData(postData);
loadUrlParams.setVerbatimHeaders(extraHeaders);
loadUrlParams.setReferrer(new Referrer(referrerUrl, referrerPolicy));
final WebappDataStorage storage =
WebappRegistry.getInstance().getWebappDataStorageForUrl(url);
AsyncTabCreationParams asyncParams = new AsyncTabCreationParams(loadUrlParams,
requestId);
tabDelegate.createNewTab(asyncParams, TabLaunchType.FROM_CHROME_UI,
Tab.INVALID_TAB_ID);
} else {
// The URL is within the scope of a recently launched standalone-capable web app
// on the home screen, so open it a standalone web app frame. An AsyncTask is
// used because WebappDataStorage.createWebappLaunchIntent contains a Bitmap
// decode operation and should not be run on the UI thread.
//
// This currently assumes that the only source is notifications; any future use
// which adds a different source will need to change this.
new AsyncTask<Void, Void, Intent>() {
@Override
protected final Intent doInBackground(Void... nothing) {
return storage.createWebappLaunchIntent();
}
// If we do not find a WebappDataStorage corresponding to this URL, or if it hasn't
// been opened recently enough, open the URL in a tab.
if (storage == null || !storage.wasLaunchedRecently()) {
LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.LINK);
loadUrlParams.setPostData(postData);
loadUrlParams.setVerbatimHeaders(extraHeaders);
loadUrlParams.setReferrer(new Referrer(referrerUrl, referrerPolicy));
@Override
protected final void onPostExecute(Intent intent) {
// Replace the web app URL with the URL from the notification. This is
// within the webapp's scope, so it is valid.
intent.putExtra(ShortcutHelper.EXTRA_URL, url);
intent.putExtra(ShortcutHelper.EXTRA_SOURCE,
ShortcutSource.NOTIFICATION);
tabDelegate.createNewStandaloneFrame(intent);
}
}.execute();
AsyncTabCreationParams asyncParams = new AsyncTabCreationParams(loadUrlParams,
requestId);
tabDelegate.createNewTab(asyncParams, TabLaunchType.FROM_CHROME_UI,
Tab.INVALID_TAB_ID);
} else {
// The URL is within the scope of a recently launched standalone-capable web app
// on the home screen, so open it a standalone web app frame. An AsyncTask is
// used because WebappDataStorage.createWebappLaunchIntent contains a Bitmap
// decode operation and should not be run on the UI thread.
//
// This currently assumes that the only source is notifications; any future use
// which adds a different source will need to change this.
new AsyncTask<Void, Void, Intent>() {
@Override
protected final Intent doInBackground(Void... nothing) {
return storage.createWebappLaunchIntent();
}
}
};
WebappRegistry.getWebappDataStorageForUrl(url, callback);
@Override
protected final void onPostExecute(Intent intent) {
// Replace the web app URL with the URL from the notification. This is
// within the webapp's scope, so it is valid.
intent.putExtra(ShortcutHelper.EXTRA_URL, url);
intent.putExtra(ShortcutHelper.EXTRA_SOURCE,
ShortcutSource.NOTIFICATION);
tabDelegate.createNewStandaloneFrame(intent);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
/**
......
......@@ -168,7 +168,7 @@ public class ShortcutHelper {
// Store the webapp data so that it is accessible without the intent. Once this
// process is complete, call back to native code to start the splash image
// download.
WebappRegistry.registerWebapp(
WebappRegistry.getInstance().register(
id, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
......@@ -228,7 +228,7 @@ public class ShortcutHelper {
}
/**
* Creates a storage location and stores the data for a web app using {@link WebappDataStorage}.
* Stores the specified bitmap as the splash screen for a web app.
* @param id ID of the web app which is storing data.
* @param splashImage Image which should be displayed on the splash screen of
* the web app. This can be null of there is no image to show.
......@@ -236,16 +236,8 @@ public class ShortcutHelper {
@SuppressWarnings("unused")
@CalledByNative
private static void storeWebappSplashImage(final String id, final Bitmap splashImage) {
WebappRegistry.getWebappDataStorage(
id, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
if (storage == null) return;
storage.updateSplashScreenImage(splashImage);
}
});
WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(id);
if (storage != null) storage.updateSplashScreenImage(splashImage);
}
/**
......
......@@ -8,12 +8,14 @@ import android.app.IntentService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.StrictMode;
import android.util.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
import org.chromium.chrome.browser.webapps.WebappRegistry;
/**
* The Notification service receives intents fired as responses to user actions issued on Android
......@@ -76,6 +78,18 @@ public class NotificationService extends IntentService {
try {
ChromeBrowserInitializer.getInstance(this).handleSynchronousStartup();
// Warm up the WebappRegistry, as we need to check if this notification should launch a
// standalone web app. This no-ops if the registry is already initialized and warmed,
// but triggers a strict mode violation otherwise (i.e. the browser isn't running).
// Temporarily disable strict mode to work around the violation.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
WebappRegistry.getInstance();
WebappRegistry.warmUpSharedPrefs();
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
// Now that the browser process is initialized, we pass forward the call to the
// NotificationPlatformBridge which will take care of delivering the appropriate events.
if (!NotificationPlatformBridge.dispatchNotificationEvent(intent)) {
......
......@@ -51,7 +51,7 @@ public class WebApkActivity extends WebappActivity {
// Register the WebAPK. It is possible that a WebAPK's meta data was deleted when user
// cleared Chrome's data. When it is launched again, we know that the WebAPK is still
// installed, so re-register it.
WebappRegistry.registerWebapp(
WebappRegistry.getInstance().register(
mWebappInfo.id(), new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
......
......@@ -13,7 +13,6 @@ import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.chrome.browser.webapps.WebappRegistry.FetchWebappDataStorageCallback;
import org.chromium.webapk.lib.client.WebApkVersion;
import org.chromium.webapk.lib.common.WebApkConstants;
import org.chromium.webapk.lib.common.WebApkMetaDataKeys;
......@@ -67,32 +66,24 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
mUpgradeDetector = new ManifestUpgradeDetector(tab, info, metadata, this);
WebappRegistry.FetchWebappDataStorageCallback callback =
new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
if (forceUpgrade(storage)) {
mForceUpgrade = true;
}
// 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 check for updated
// Web Manifest should be updated after the detector finds the
// Web Manifest, not when the detector is started.
storage.updateTimeOfLastCheckForUpdatedWebManifest();
}
}
}
};
WebappRegistry.getWebappDataStorage(info.id(), callback);
WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(info.id());
if (forceUpgrade(storage)) mForceUpgrade = true;
// 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 check for updated
// Web Manifest should be updated after the detector finds the
// Web Manifest, not when the detector is started.
storage.updateTimeOfLastCheckForUpdatedWebManifest();
}
}
}
@Override
......@@ -160,16 +151,12 @@ public class WebApkUpdateManager implements ManifestUpgradeDetector.Callback {
*/
@CalledByNative
private static void onBuiltWebApk(final boolean success, String webapkPackage) {
WebappRegistry.getWebappDataStorage(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.updateTimeOfLastWebApkUpdateRequestCompletion();
storage.updateDidLastWebApkUpdateRequestSucceed(success);
}
});
WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(
WebApkConstants.WEBAPK_ID_PREFIX + webapkPackage);
// Update the request time and result together. It prevents getting a
// correct request time but a result from the previous request.
storage.updateTimeOfLastWebApkUpdateRequestCompletion();
storage.updateDidLastWebApkUpdateRequestSucceed(success);
}
private static native void nativeUpdateAsync(String startUrl, String scope, String name,
......
......@@ -60,8 +60,6 @@ public class WebappActivity extends FullScreenActivity {
protected WebappInfo mWebappInfo;
private boolean mOldWebappCleanupStarted;
private ViewGroup mSplashScreen;
private WebappUrlBar mUrlBar;
......@@ -126,7 +124,23 @@ public class WebappActivity extends FullScreenActivity {
@Override
public void preInflationStartup() {
WebappInfo info = WebappInfo.create(getIntent());
if (info != null) mWebappInfo = info;
String id = "";
if (info != null) {
mWebappInfo = info;
id = info.id();
}
// Initialize the WebappRegistry and warm up the shared preferences for this web app. No-ops
// if the registry and this web app are already initialized. Must override Strict Mode to
// avoid a violation.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
WebappRegistry.getInstance();
WebappRegistry.warmUpSharedPrefsForId(id);
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
ScreenOrientationProvider.lockOrientation((byte) mWebappInfo.orientation(), this);
super.preInflationStartup();
......@@ -195,13 +209,6 @@ public class WebappActivity extends FullScreenActivity {
updateTaskDescription();
}
super.onResume();
// Kick off the old web app cleanup (if we haven't already) now that we have queued the
// current web app's storage to be opened.
if (!mOldWebappCleanupStarted) {
WebappRegistry.unregisterOldWebapps(System.currentTimeMillis());
mOldWebappCleanupStarted = true;
}
}
@Override
......@@ -262,25 +269,20 @@ public class WebappActivity extends FullScreenActivity {
}
protected void initializeSplashScreenWidgets(final int backgroundColor) {
WebappRegistry.getWebappDataStorage(
mWebappInfo.id(), new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
if (storage == null) {
onStorageIsNull(backgroundColor);
return;
}
updateStorage(storage);
// Retrieve the splash image if it exists.
storage.getSplashScreenImage(new WebappDataStorage.FetchCallback<Bitmap>() {
@Override
public void onDataRetrieved(Bitmap splashImage) {
initializeSplashScreenWidgets(backgroundColor, splashImage);
}
});
}
});
WebappDataStorage storage =
WebappRegistry.getInstance().getWebappDataStorage(mWebappInfo.id());
if (storage == null) {
onStorageIsNull(backgroundColor);
return;
}
updateStorage(storage);
storage.getSplashScreenImage(new WebappDataStorage.FetchCallback<Bitmap>() {
@Override
public void onDataRetrieved(Bitmap splashImage) {
initializeSplashScreenWidgets(backgroundColor, splashImage);
}
});
}
protected void onStorageIsNull(int backgroundColor) {}
......
......@@ -1369,6 +1369,7 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/webapps/ActivityAssignerTest.java",
"javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenDialogTest.java",
"javatests/src/org/chromium/chrome/browser/webapps/AddToHomescreenManagerTest.java",
"javatests/src/org/chromium/chrome/browser/webapps/TestFetchStorageCallback.java",
"javatests/src/org/chromium/chrome/browser/webapps/ManifestUpgradeDetectorFetcherTest.java",
"javatests/src/org/chromium/chrome/browser/webapps/ManifestUpgradeDetectorTest.java",
"javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java",
......
......@@ -14,7 +14,7 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.PrefServiceBridge.OnClearBrowsingDataListener;
import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.TestFetchStorageCallback;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.chrome.test.ChromeActivityTestCaseBase;
import org.chromium.content.browser.test.util.Criteria;
......@@ -24,7 +24,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Integration tests for the native BrowsingDataRemover.
......@@ -67,18 +66,12 @@ public class BrowsingDataRemoverIntegrationTest extends ChromeActivityTestCaseBa
return ShortcutHelper.createWebappShortcutIntentForTesting(webappId, webappUrl);
}
};
final Intent shortcutIntent = shortcutIntentTask.execute().get();
WebappRegistry.registerWebapp(
webappId, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
storage.updateFromShortcutIntent(shortcutIntent);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
final Intent shortcutIntent = shortcutIntentTask.execute().get();
TestFetchStorageCallback callback = new TestFetchStorageCallback();
WebappRegistry.getInstance().register(webappId, callback);
callback.waitForCallback(0);
callback.getStorage().updateFromShortcutIntent(shortcutIntent);
}
/**
......@@ -98,16 +91,7 @@ public class BrowsingDataRemoverIntegrationTest extends ChromeActivityTestCaseBa
for (final Map.Entry<String, String> app : apps.entrySet()) {
registerWebapp(app.getKey(), app.getValue());
}
// Wait for the registration to finish.
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertEquals(apps.keySet(), ids);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertEquals(apps.keySet(), WebappRegistry.getRegisteredWebappIdsForTesting());
// Clear cookies and site data excluding the registrable domain "google.com".
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
......@@ -131,14 +115,8 @@ public class BrowsingDataRemoverIntegrationTest extends ChromeActivityTestCaseBa
CriteriaHelper.pollUiThread(new CallbackCriteria());
// The last two webapps should have been unregistered.
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertEquals(new HashSet<String>(Arrays.asList("webapp1")), ids);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertEquals(new HashSet<String>(Arrays.asList("webapp1")),
WebappRegistry.getRegisteredWebappIdsForTesting());
// Clear cookies and site data with no url filter.
ThreadUtils.runOnUiThreadBlocking(new Runnable() {
......@@ -158,13 +136,6 @@ public class BrowsingDataRemoverIntegrationTest extends ChromeActivityTestCaseBa
CriteriaHelper.pollUiThread(new CallbackCriteria());
// All webapps should have been unregistered.
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertTrue(ids.isEmpty());
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
}
}
......@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.preferences.ButtonPreference;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.Preferences;
import org.chromium.chrome.browser.preferences.privacy.ClearBrowsingDataPreferences.DialogOption;
import org.chromium.chrome.browser.webapps.TestFetchStorageCallback;
import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.chrome.test.ChromeActivityTestCaseBase;
......@@ -39,7 +40,6 @@ import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Integration tests for ClearBrowsingDataPreferences.
......@@ -48,22 +48,6 @@ import java.util.Set;
public class ClearBrowsingDataPreferencesTest
extends ChromeActivityTestCaseBase<ChromeActivity> {
private EmbeddedTestServer mTestServer;
private boolean mCallbackCalled;
private class CallbackCriteria extends Criteria {
public CallbackCriteria() {
mCallbackCalled = false;
}
@Override
public boolean isSatisfied() {
if (mCallbackCalled) {
mCallbackCalled = false;
return true;
}
return false;
}
}
@Override
protected void setUp() throws Exception {
......@@ -104,15 +88,11 @@ public class ClearBrowsingDataPreferencesTest
*/
@MediumTest
public void testClearingSiteDataClearsWebapps() throws Exception {
WebappRegistry.registerWebapp("first", null);
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertEquals(new HashSet<String>(Arrays.asList("first")), ids);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
TestFetchStorageCallback callback = new TestFetchStorageCallback();
WebappRegistry.getInstance().register("first", callback);
callback.waitForCallback(0);
assertEquals(new HashSet<String>(Arrays.asList("first")),
WebappRegistry.getRegisteredWebappIdsForTesting());
setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_COOKIES_AND_SITE_DATA));
final ClearBrowsingDataPreferences preferences =
......@@ -131,14 +111,7 @@ public class ClearBrowsingDataPreferencesTest
});
waitForProgressToComplete(preferences);
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertTrue(ids.isEmpty());
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertTrue(WebappRegistry.getRegisteredWebappIdsForTesting().isEmpty());
}
/**
......@@ -155,23 +128,13 @@ public class ClearBrowsingDataPreferencesTest
};
final Intent shortcutIntent = shortcutIntentTask.execute().get();
WebappRegistry.registerWebapp("first", new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
storage.updateFromShortcutIntent(shortcutIntent);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
TestFetchStorageCallback callback = new TestFetchStorageCallback();
WebappRegistry.getInstance().register("first", callback);
callback.waitForCallback(0);
callback.getStorage().updateFromShortcutIntent(shortcutIntent);
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertEquals(new HashSet<String>(Arrays.asList("first")), ids);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertEquals(new HashSet<String>(Arrays.asList("first")),
WebappRegistry.getRegisteredWebappIdsForTesting());
setDataTypesToClear(Arrays.asList(DialogOption.CLEAR_HISTORY));
final ClearBrowsingDataPreferences preferences =
......@@ -190,45 +153,14 @@ public class ClearBrowsingDataPreferencesTest
});
waitForProgressToComplete(preferences);
// The web app should still exist in the registry.
WebappRegistry.getRegisteredWebappIds(new WebappRegistry.FetchCallback() {
@Override
public void onWebappIdsRetrieved(Set<String> ids) {
assertEquals(new HashSet<String>(Arrays.asList("first")), ids);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
assertEquals(new HashSet<String>(Arrays.asList("first")),
WebappRegistry.getRegisteredWebappIdsForTesting());
// URL and scope should be empty.
WebappDataStorage.getScope("first", new WebappDataStorage.FetchCallback<String>() {
@Override
public void onDataRetrieved(String readObject) {
assertEquals(readObject, "");
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
WebappDataStorage.getUrl("first", new WebappDataStorage.FetchCallback<String>() {
@Override
public void onDataRetrieved(String readObject) {
assertEquals(readObject, "");
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
// The last used time should be 0.
WebappDataStorage.getLastUsedTime("first", new WebappDataStorage.FetchCallback<Long>() {
@Override
public void onDataRetrieved(Long readObject) {
long lastUsed = readObject;
assertEquals(lastUsed, 0);
mCallbackCalled = true;
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
// URL and scope should be empty, and last used time should be 0.
WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage("first");
assertEquals("", storage.getScope());
assertEquals("", storage.getUrl());
assertEquals(0, storage.getLastUsedTime());
}
/**
......
// 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 org.chromium.content.browser.test.util.CallbackHelper;
/**
* CallbackHelper subclass which implements WebappRegistry.FetchWebappDataStorageCallback for tests.
*/
public class TestFetchStorageCallback
extends CallbackHelper implements WebappRegistry.FetchWebappDataStorageCallback {
protected WebappDataStorage mStorage;
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
mStorage = storage;
notifyCalled();
}
public WebappDataStorage getStorage() {
return mStorage;
}
}
......@@ -95,7 +95,8 @@ public abstract class WebappActivityTestBase extends ChromeActivityTestCaseBase<
// Register the webapp so when the data storage is opened, the test doesn't crash. There is
// no race condition with the retrieval as AsyncTasks are run sequentially on the background
// thread.
WebappRegistry.registerWebapp(
WebappRegistry.refreshSharedPrefsForTesting();
WebappRegistry.getInstance().register(
WEBAPP_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
......
......@@ -93,11 +93,12 @@ public class WebappModeTest extends MultiActivityTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
WebappRegistry.refreshSharedPrefsForTesting();
// Register the webapps so when the data storage is opened, the test doesn't crash. There is
// no race condition with the retrieval as AsyncTasks are run sequentially on the background
// thread.
WebappRegistry.registerWebapp(
WebappRegistry.getInstance().register(
WEBAPP_1_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
......@@ -105,7 +106,7 @@ public class WebappModeTest extends MultiActivityTestBase {
WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, WEBAPP_ICON, true));
}
});
WebappRegistry.registerWebapp(
WebappRegistry.getInstance().register(
WEBAPP_2_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
......
......@@ -28,11 +28,31 @@ import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.metrics.WebappUma;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabTestUtils;
import org.chromium.content.browser.test.util.Criteria;
import org.chromium.content.browser.test.util.CriteriaHelper;
/**
* Tests for splash screens.
*/
public class WebappSplashScreenTest extends WebappActivityTestBase {
private boolean mCallbackCalled;
private class CallbackCriteria extends Criteria {
public CallbackCriteria() {
mCallbackCalled = false;
}
@Override
public boolean isSatisfied() {
if (mCallbackCalled) {
mCallbackCalled = false;
return true;
}
return false;
}
}
private int getHistogramTotalCountFor(String histogram, int buckets) {
int count = 0;
......@@ -235,9 +255,18 @@ public class WebappSplashScreenTest extends WebappActivityTestBase {
Context context = getInstrumentation().getTargetContext();
int thresholdSize = context.getResources().getDimensionPixelSize(
R.dimen.webapp_splash_image_size_threshold);
int bitmapSize = thresholdSize + 1;
Bitmap splashBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
WebappDataStorage.open(WEBAPP_ID).updateSplashScreenImage(splashBitmap);
int size = thresholdSize + 1;
final Bitmap splashBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
WebappRegistry.getInstance().register(
WEBAPP_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
mCallbackCalled = true;
storage.updateSplashScreenImage(splashBitmap);
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
startWebappActivity(createIntent());
ViewGroup splashScreen = waitUntilSplashScreenAppears();
......@@ -245,8 +274,8 @@ public class WebappSplashScreenTest extends WebappActivityTestBase {
ImageView splashImage =
(ImageView) splashScreen.findViewById(R.id.webapp_splash_screen_icon);
assertEquals(bitmapSize, splashImage.getMeasuredWidth());
assertEquals(bitmapSize, splashImage.getMeasuredHeight());
assertEquals(size, splashImage.getMeasuredWidth());
assertEquals(size, splashImage.getMeasuredHeight());
TextView splashText = (TextView) splashScreen.findViewById(R.id.webapp_splash_screen_name);
int[] rules = ((RelativeLayout.LayoutParams) splashText.getLayoutParams()).getRules();
......@@ -262,10 +291,19 @@ public class WebappSplashScreenTest extends WebappActivityTestBase {
Context context = getInstrumentation().getTargetContext();
int thresholdSize = context.getResources().getDimensionPixelSize(
R.dimen.webapp_splash_image_size_threshold);
int bitmapSize = context.getResources().getDimensionPixelSize(
int size = context.getResources().getDimensionPixelSize(
R.dimen.webapp_splash_image_size_minimum);
Bitmap splashBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
WebappDataStorage.open(WEBAPP_ID).updateSplashScreenImage(splashBitmap);
final Bitmap splashBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
WebappRegistry.getInstance().register(
WEBAPP_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
mCallbackCalled = true;
storage.updateSplashScreenImage(splashBitmap);
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
startWebappActivity(createIntent());
ViewGroup splashScreen = waitUntilSplashScreenAppears();
......@@ -289,10 +327,19 @@ public class WebappSplashScreenTest extends WebappActivityTestBase {
public void testSplashScreenWithoutImageAppears() throws Exception {
// Register an image that's too small for the splash screen.
Context context = getInstrumentation().getTargetContext();
int bitmapSize = context.getResources().getDimensionPixelSize(
int size = context.getResources().getDimensionPixelSize(
R.dimen.webapp_splash_image_size_minimum) - 1;
Bitmap splashBitmap = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);
WebappDataStorage.open(WEBAPP_ID).updateSplashScreenImage(splashBitmap);
final Bitmap splashBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
WebappRegistry.getInstance().register(
WEBAPP_ID, new WebappRegistry.FetchWebappDataStorageCallback() {
@Override
public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
mCallbackCalled = true;
storage.updateSplashScreenImage(splashBitmap);
}
});
CriteriaHelper.pollUiThread(new CallbackCriteria());
Intent intent = createIntent();
intent.putExtra(ShortcutHelper.EXTRA_IS_ICON_GENERATED, true);
......
......@@ -75,10 +75,10 @@ public class WebappDataStorageTest {
public void setUp() throws Exception {
ContextUtils.initApplicationContextForTests(RuntimeEnvironment.application);
mSharedPreferences = ContextUtils.getApplicationContext().getSharedPreferences(
"webapp_test", Context.MODE_PRIVATE);
WebappDataStorage.SHARED_PREFS_FILE_PREFIX + "test", Context.MODE_PRIVATE);
// Set the last_used as if the web app had been registered by WebappRegistry.
mSharedPreferences.edit().putLong("last_used", 0).apply();
mSharedPreferences.edit().putLong(WebappDataStorage.KEY_LAST_USED, 0).apply();
mCallbackCalled = false;
}
......@@ -111,13 +111,9 @@ public class WebappDataStorageTest {
@Test
@Feature({"Webapp"})
public void testLastUsedRetrieval() throws Exception {
mSharedPreferences.edit().putLong(WebappDataStorage.KEY_LAST_USED, 100L).apply();
WebappDataStorage.getLastUsedTime("test", new FetchCallback<Long>(new Long(100L)));
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertTrue(mCallbackCalled);
long lastUsed = 100;
mSharedPreferences.edit().putLong(WebappDataStorage.KEY_LAST_USED, lastUsed).apply();
assertEquals(lastUsed, new WebappDataStorage("test").getLastUsedTime());
}
@Test
......@@ -127,9 +123,9 @@ public class WebappDataStorageTest {
mSharedPreferences.edit()
.putString(WebappDataStorage.KEY_SPLASH_ICON,
ShortcutHelper.encodeBitmapAsString(expected))
.commit();
WebappDataStorage.open("test")
.getSplashScreenImage(new WebappDataStorage.FetchCallback<Bitmap>() {
.apply();
WebappDataStorage.open("test").getSplashScreenImage(
new WebappDataStorage.FetchCallback<Bitmap>() {
@Override
public void onDataRetrieved(Bitmap actual) {
mCallbackCalled = true;
......@@ -152,6 +148,7 @@ public class WebappDataStorageTest {
final Bitmap expectedImage = createBitmap();
WebappDataStorage.open("test").updateSplashScreenImage(expectedImage);
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertEquals(ShortcutHelper.encodeBitmapAsString(expectedImage),
mSharedPreferences.getString(WebappDataStorage.KEY_SPLASH_ICON, null));
......@@ -160,27 +157,17 @@ public class WebappDataStorageTest {
@Test
@Feature({"Webapp"})
public void testScopeRetrieval() throws Exception {
final String scope = "http://drive.google.com";
String scope = "http://drive.google.com";
mSharedPreferences.edit().putString(WebappDataStorage.KEY_SCOPE, scope).apply();
WebappDataStorage.getScope("test", new FetchCallback<String>(scope));
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertTrue(mCallbackCalled);
assertEquals(scope, new WebappDataStorage("test").getScope());
}
@Test
@Feature({"Webapp"})
public void testUrlRetrieval() throws Exception {
final String url = "https://www.google.com";
String url = "https://www.google.com";
mSharedPreferences.edit().putString(WebappDataStorage.KEY_URL, url).apply();
WebappDataStorage.getUrl("test", new FetchCallback<String>(url));
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertTrue(mCallbackCalled);
assertEquals(url, new WebappDataStorage("test").getUrl());
}
@Test
......@@ -191,14 +178,10 @@ public class WebappDataStorageTest {
// Opening a data storage doesn't count as a launch.
WebappDataStorage storage = WebappDataStorage.open("test");
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertTrue(!storage.wasLaunchedRecently());
// When the last used time is updated, then it is a launch.
storage.updateLastUsedTime();
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertTrue(storage.wasLaunchedRecently());
long lastUsedTime = mSharedPreferences.getLong(WebappDataStorage.KEY_LAST_USED,
......@@ -263,8 +246,6 @@ public class WebappDataStorageTest {
WebappDataStorage storage = WebappDataStorage.open("test");
storage.updateFromShortcutIntent(shortcutIntent);
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertEquals(action, mSharedPreferences.getString(WebappDataStorage.KEY_ACTION, null));
assertEquals(url, mSharedPreferences.getString(WebappDataStorage.KEY_URL, null));
......@@ -312,8 +293,6 @@ public class WebappDataStorageTest {
// Update again from the intent and ensure that the data is restored.
storage.updateFromShortcutIntent(shortcutIntent);
BackgroundShadowAsyncTask.runBackgroundTasks();
ShadowLooper.runUiThreadTasks();
assertEquals(action, mSharedPreferences.getString(WebappDataStorage.KEY_ACTION, null));
assertEquals(url, mSharedPreferences.getString(WebappDataStorage.KEY_URL, null));
......
......@@ -103,7 +103,6 @@
#include "chrome/browser/android/webapk/webapk_installer.h"
#include "chrome/browser/android/webapk/webapk_update_manager.h"
#include "chrome/browser/android/webapps/add_to_homescreen_manager.h"
#include "chrome/browser/android/webapps/webapp_registry.h"
#include "chrome/browser/autofill/android/personal_data_manager_android.h"
#include "chrome/browser/dom_distiller/dom_distiller_service_factory_android.h"
#include "chrome/browser/dom_distiller/tab_utils_android.h"
......@@ -382,7 +381,6 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
{"WarmupManager", RegisterWarmupManager},
{"WebApkInstaller", WebApkInstaller::Register},
{"WebApkUpdateManager", WebApkUpdateManager::Register},
{"WebappRegistry", WebappRegistry::RegisterWebappRegistry},
{"WebContentsFactory", RegisterWebContentsFactory},
{"WebsitePreferenceBridge", RegisterWebsitePreferenceBridge},
{"WebsiteSettingsPopupAndroid",
......
......@@ -4,70 +4,26 @@
#include "chrome/browser/android/webapps/webapp_registry.h"
#include <jni.h>
#include "base/android/context_utils.h"
#include "base/android/jni_android.h"
#include "base/callback.h"
#include "chrome/browser/android/browsing_data/url_filter_bridge.h"
#include "chrome/browser/io_thread.h"
#include "content/public/browser/browser_thread.h"
#include "jni/WebappRegistry_jni.h"
using base::android::JavaParamRef;
void WebappRegistry::UnregisterWebappsForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback) {
JNIEnv* env = base::android::AttachCurrentThread();
// TODO(msramek): Consider implementing a wrapper class that will call and
// destroy this closure from Java, eliminating the need for
// OnWebappsUnregistered() and OnClearedWebappHistory() callbacks.
uintptr_t callback_pointer = reinterpret_cast<uintptr_t>(
new base::Closure(callback));
// We will destroy |filter_bridge| from its Java counterpart before calling
// back OnWebappsUnregistered().
const base::Callback<bool(const GURL&)>& url_filter) {
// |filter_bridge| is destroyed from its Java counterpart.
UrlFilterBridge* filter_bridge = new UrlFilterBridge(url_filter);
Java_WebappRegistry_unregisterWebappsForUrls(env, filter_bridge->j_bridge(),
callback_pointer);
Java_WebappRegistry_unregisterWebappsForUrls(
base::android::AttachCurrentThread(), filter_bridge->j_bridge());
}
void WebappRegistry::ClearWebappHistoryForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback) {
JNIEnv* env = base::android::AttachCurrentThread();
uintptr_t callback_pointer = reinterpret_cast<uintptr_t>(
new base::Closure(callback));
// We will destroy |filter_bridge| from its Java counterpart before calling
// back OnClearedWebappHistory().
const base::Callback<bool(const GURL&)>& url_filter) {
// |filter_bridge| is destroyed from its Java counterpart.
UrlFilterBridge* filter_bridge = new UrlFilterBridge(url_filter);
Java_WebappRegistry_clearWebappHistoryForUrls(env, filter_bridge->j_bridge(),
callback_pointer);
}
// Callback used by Java when all web apps have been unregistered.
void OnWebappsUnregistered(JNIEnv* env,
const JavaParamRef<jclass>& clazz,
jlong jcallback) {
base::Closure* callback = reinterpret_cast<base::Closure*>(jcallback);
callback->Run();
delete callback;
}
// Callback used by Java when all web app last used times have been cleared.
void OnClearedWebappHistory(JNIEnv* env,
const JavaParamRef<jclass>& clazz,
jlong jcallback) {
base::Closure* callback = reinterpret_cast<base::Closure*>(jcallback);
callback->Run();
delete callback;
}
// static
bool WebappRegistry::RegisterWebappRegistry(JNIEnv* env) {
return RegisterNativesImpl(env);
Java_WebappRegistry_clearWebappHistoryForUrls(
base::android::AttachCurrentThread(), filter_bridge->j_bridge());
}
......@@ -5,8 +5,6 @@
#ifndef CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPP_REGISTRY_H_
#define CHROME_BROWSER_ANDROID_WEBAPPS_WEBAPP_REGISTRY_H_
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/callback_forward.h"
#include "base/macros.h"
......@@ -22,19 +20,14 @@ class WebappRegistry {
WebappRegistry() { }
virtual ~WebappRegistry() { }
// Registers JNI hooks.
static bool RegisterWebappRegistry(JNIEnv* env);
// Cleans up data stored by web apps on URLs matching |url_filter|.
virtual void UnregisterWebappsForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback);
const base::Callback<bool(const GURL&)>& url_filter);
// Removes history data (last used time and URLs) stored by web apps with
// URLs matching |url_filter|, whilst leaving other data intact.
virtual void ClearWebappHistoryForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback);
const base::Callback<bool(const GURL&)>& url_filter);
private:
DISALLOW_COPY_AND_ASSIGN(WebappRegistry);
......
......@@ -699,13 +699,8 @@ void BrowsingDataRemover::RemoveImpl(
}
// Clear the history information (last launch time and origin URL) of any
// registered webapps. The webapp_registry makes a JNI call into a Java-side
// AsyncTask, so don't wait for the reply.
waiting_for_clear_webapp_history_ = true;
webapp_registry_->ClearWebappHistoryForUrls(
filter,
base::Bind(&BrowsingDataRemover::OnClearedWebappHistory,
weak_ptr_factory_.GetWeakPtr()));
// registered webapps.
webapp_registry_->ClearWebappHistoryForUrls(filter);
#endif
data_reduction_proxy::DataReductionProxySettings*
......@@ -1149,15 +1144,9 @@ void BrowsingDataRemover::RemoveImpl(
}
#if BUILDFLAG(ANDROID_JAVA_UI)
if (remove_mask & REMOVE_WEBAPP_DATA) {
// Clear all data associated with registered webapps. The webapp_registry
// makes a JNI call into a Java-side AsyncTask, so don't wait for the reply.
waiting_for_clear_webapp_data_ = true;
webapp_registry_->UnregisterWebappsForUrls(
filter,
base::Bind(&BrowsingDataRemover::OnClearedWebappData,
weak_ptr_factory_.GetWeakPtr()));
}
// Clear all data associated with registered webapps.
if (remove_mask & REMOVE_WEBAPP_DATA)
webapp_registry_->UnregisterWebappsForUrls(filter);
// For now we're considering offline pages as cache, so if we're removing
// cache we should remove offline pages as well.
......@@ -1265,8 +1254,6 @@ bool BrowsingDataRemover::AllDone() {
!waiting_for_clear_pnacl_cache_ &&
#if BUILDFLAG(ANDROID_JAVA_UI)
!waiting_for_clear_precache_history_ &&
!waiting_for_clear_webapp_data_ &&
!waiting_for_clear_webapp_history_ &&
!waiting_for_clear_offline_page_data_ &&
#endif
#if defined(ENABLE_WEBRTC)
......@@ -1525,18 +1512,6 @@ void BrowsingDataRemover::OnClearedPrecacheHistory() {
NotifyIfDone();
}
void BrowsingDataRemover::OnClearedWebappData() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
waiting_for_clear_webapp_data_ = false;
NotifyIfDone();
}
void BrowsingDataRemover::OnClearedWebappHistory() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
waiting_for_clear_webapp_history_ = false;
NotifyIfDone();
}
void BrowsingDataRemover::OnClearedOfflinePageData(
offline_pages::OfflinePageModel::DeletePageResult result) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
......
......@@ -463,12 +463,6 @@ class BrowsingDataRemover : public KeyedService
// Callback on UI thread when the precache history has been cleared.
void OnClearedPrecacheHistory();
// Callback on UI thread when the webapp data has been cleared.
void OnClearedWebappData();
// Callback on UI thread when the webapp history has been cleared.
void OnClearedWebappHistory();
// Callback on UI thread when the offline page data has been cleared.
void OnClearedOfflinePageData(
offline_pages::OfflinePageModel::DeletePageResult result);
......@@ -545,8 +539,6 @@ class BrowsingDataRemover : public KeyedService
bool waiting_for_clear_pnacl_cache_ = false;
#if BUILDFLAG(ANDROID_JAVA_UI)
bool waiting_for_clear_precache_history_ = false;
bool waiting_for_clear_webapp_data_ = false;
bool waiting_for_clear_webapp_history_ = false;
bool waiting_for_clear_offline_page_data_ = false;
#endif
bool waiting_for_clear_storage_partition_data_ = false;
......
......@@ -318,19 +318,13 @@ class TestWebappRegistry : public WebappRegistry {
TestWebappRegistry() : WebappRegistry() { }
void UnregisterWebappsForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback) override {
// Mocks out a JNI call and runs the callback as a delayed task.
BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, callback,
base::TimeDelta::FromMilliseconds(10));
const base::Callback<bool(const GURL&)>& url_filter) override {
// Mocks out a JNI call.
}
void ClearWebappHistoryForUrls(
const base::Callback<bool(const GURL&)>& url_filter,
const base::Closure& callback) override {
// Mocks out a JNI call and runs the callback as a delayed task.
BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, callback,
base::TimeDelta::FromMilliseconds(10));
const base::Callback<bool(const GURL&)>& url_filter) override {
// Mocks out a JNI call.
}
};
#endif
......
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