Commit f21ab9c1 authored by wnwen's avatar wnwen Committed by Commit bot

Move WebappRegistry warmup to async task.

On Android N the constructor results in a StrictMode violation due to
WebappRegistry#openSharedPreferences. Use initialization on demand
holder idiom to avoid synchronization issues.

BUG=656035

Review-Url: https://chromiumcodereview.appspot.com/2421833003
Cr-Commit-Position: refs/heads/master@{#426823}
parent 45fd5f3e
...@@ -174,10 +174,6 @@ public class DeferredStartupHandler { ...@@ -174,10 +174,6 @@ public class DeferredStartupHandler {
mDeferredTasks.add(new Runnable() { mDeferredTasks.add(new Runnable() {
@Override @Override
public void run() { 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. // Punt all tasks that may block on disk off onto a background thread.
initAsyncDiskTask(); initAsyncDiskTask();
...@@ -243,6 +239,11 @@ public class DeferredStartupHandler { ...@@ -243,6 +239,11 @@ public class DeferredStartupHandler {
try { try {
TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground"); TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
long asyncTaskStartTime = SystemClock.uptimeMillis(); long asyncTaskStartTime = SystemClock.uptimeMillis();
// Initialize the WebappRegistry if it's not already initialized. Must be in
// async task due to shared preferences disk access on N.
WebappRegistry.getInstance();
boolean crashDumpDisabled = CommandLine.getInstance().hasSwitch( boolean crashDumpDisabled = CommandLine.getInstance().hasSwitch(
ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD); ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
if (!crashDumpDisabled) { if (!crashDumpDisabled) {
......
...@@ -49,7 +49,11 @@ public class WebappRegistry { ...@@ -49,7 +49,11 @@ public class WebappRegistry {
/** Represents a period of 13 weeks in milliseconds */ /** Represents a period of 13 weeks in milliseconds */
static final long WEBAPP_UNOPENED_CLEANUP_DURATION = TimeUnit.DAYS.toMillis(13L * 7L); static final long WEBAPP_UNOPENED_CLEANUP_DURATION = TimeUnit.DAYS.toMillis(13L * 7L);
private static volatile WebappRegistry sInstance; /** Initialization-on-demand holder. This exists for thread-safe lazy initialization. */
private static class Holder {
// Not final for testing.
private static WebappRegistry sInstance = new WebappRegistry();
}
private HashMap<String, WebappDataStorage> mStorages; private HashMap<String, WebappDataStorage> mStorages;
private SharedPreferences mPreferences; private SharedPreferences mPreferences;
...@@ -62,34 +66,37 @@ public class WebappRegistry { ...@@ -62,34 +66,37 @@ public class WebappRegistry {
void onWebappDataStorageRetrieved(WebappDataStorage storage); void onWebappDataStorageRetrieved(WebappDataStorage storage);
} }
private WebappRegistry() {
mPreferences = openSharedPreferences();
mStorages = new HashMap<>();
}
/** /**
* Returns the singleton WebappRegistry instance. Creates the instance if necessary. * Returns the singleton WebappRegistry instance. Creates the instance on first call.
*/ */
public static WebappRegistry getInstance() { public static WebappRegistry getInstance() {
if (sInstance == null) sInstance = new WebappRegistry(); return Holder.sInstance;
return sInstance;
} }
/** /**
* Warm up the WebappRegistry and a specific WebappDataStorage SharedPreferences. This static * Warm up the WebappRegistry and a specific WebappDataStorage SharedPreferences.
* method can be called on any thread, so it must not initialize sInstance.
* @param id The web app id to warm up in addition to the WebappRegistry. * @param id The web app id to warm up in addition to the WebappRegistry.
*/ */
public static void warmUpSharedPrefsForId(String id) { public static void warmUpSharedPrefsForId(String id) {
sInstance.initStorages(id, false); getInstance().initStorages(id, false);
} }
/** /**
* Warm up the WebappRegistry and all WebappDataStorage SharedPreferences. This static method * Warm up the WebappRegistry and all WebappDataStorage SharedPreferences.
* can be called on any thread, so it must not initialize sInstance.
*/ */
public static void warmUpSharedPrefs() { public static void warmUpSharedPrefs() {
sInstance.initStorages(null, false); getInstance().initStorages(null, false);
} }
@VisibleForTesting
public static void refreshSharedPrefsForTesting() { public static void refreshSharedPrefsForTesting() {
sInstance = new WebappRegistry(); Holder.sInstance = new WebappRegistry();
sInstance.initStorages(null, true); getInstance().initStorages(null, true);
} }
/** /**
...@@ -264,11 +271,6 @@ public class WebappRegistry { ...@@ -264,11 +271,6 @@ public class WebappRegistry {
REGISTRY_FILE_NAME, Context.MODE_PRIVATE); REGISTRY_FILE_NAME, Context.MODE_PRIVATE);
} }
private WebappRegistry() {
mPreferences = openSharedPreferences();
mStorages = new HashMap<String, WebappDataStorage>();
}
private void initStorages(String idToInitialize, boolean replaceExisting) { private void initStorages(String idToInitialize, boolean replaceExisting) {
Set<String> webapps = Set<String> webapps =
mPreferences.getStringSet(KEY_WEBAPP_SET, Collections.<String>emptySet()); mPreferences.getStringSet(KEY_WEBAPP_SET, Collections.<String>emptySet());
......
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