This CL implements alternative asynchronous methods for profile and preferences loading.

BUG=chromium-os:11104
TEST=UserProfileGotten (see "/tmp/login-times-sent") time doesn't increase, while UI jankness decreases.

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=81394 (patch set <= 25), but reverted.

Review URL: http://codereview.chromium.org/6716025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@82096 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc
index 3beff39..aa71108 100644
--- a/chrome/browser/prefs/pref_service.cc
+++ b/chrome/browser/prefs/pref_service.cc
@@ -87,6 +87,15 @@
 PrefService* PrefService::CreatePrefService(const FilePath& pref_filename,
                                             PrefStore* extension_prefs,
                                             Profile* profile) {
+  return CreatePrefServiceAsync(pref_filename, extension_prefs, profile, NULL);
+}
+
+// static
+PrefService* PrefService::CreatePrefServiceAsync(
+    const FilePath& pref_filename,
+    PrefStore* extension_prefs,
+    Profile* profile,
+    PrefService::Delegate* delegate) {
   using policy::ConfigurationPolicyPrefStore;
 
 #if defined(OS_LINUX)
@@ -120,7 +129,7 @@
 
   return new PrefService(managed_platform, managed_cloud, extension_prefs,
                          command_line, user, recommended_platform,
-                         recommended_cloud, default_pref_store);
+                         recommended_cloud, default_pref_store, delegate);
 }
 
 PrefService* PrefService::CreateIncognitoPrefService(
@@ -135,9 +144,11 @@
                          PersistentPrefStore* user_prefs,
                          PrefStore* recommended_platform_prefs,
                          PrefStore* recommended_cloud_prefs,
-                         DefaultPrefStore* default_store)
+                         DefaultPrefStore* default_store,
+                         PrefService::Delegate* delegate)
     : user_pref_store_(user_prefs),
-      default_store_(default_store) {
+      default_store_(default_store),
+      delegate_(delegate) {
   pref_notifier_.reset(new PrefNotifierImpl(this));
   pref_value_store_.reset(
       new PrefValueStore(managed_platform_prefs,
@@ -156,7 +167,8 @@
                          PrefStore* incognito_extension_prefs)
       : user_pref_store_(
             new OverlayPersistentPrefStore(original.user_pref_store_.get())),
-        default_store_(original.default_store_.get()){
+        default_store_(original.default_store_.get()),
+        delegate_(NULL) {
   pref_notifier_.reset(new PrefNotifierImpl(this));
   pref_value_store_.reset(original.pref_value_store_->CloneAndSpecialize(
       NULL, // managed_platform_prefs
@@ -182,27 +194,48 @@
   default_store_ = NULL;
 }
 
-void PrefService::InitFromStorage() {
-  const PersistentPrefStore::PrefReadError error =
-      user_pref_store_->ReadPrefs();
-  if (error == PersistentPrefStore::PREF_READ_ERROR_NONE)
+void PrefService::OnPrefsRead(PersistentPrefStore::PrefReadError error,
+                              bool no_dir) {
+  if (no_dir) {
+    // Bad news. When profile is created, the process that creates the directory
+    // is explicitly started. So if directory is missing it probably means that
+    // Chromium hasn't sufficient privileges.
+    CHECK(delegate_);
+    delegate_->OnPrefsLoaded(this, false);
     return;
-
-  // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
-  // an example problem that this can cause.
-  // Do some diagnosis and try to avoid losing data.
-  int message_id = 0;
-  if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
-    message_id = IDS_PREFERENCES_CORRUPT_ERROR;
-  } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
-    message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
   }
 
-  if (message_id) {
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-        NewRunnableFunction(&NotifyReadError, this, message_id));
+  if (error != PersistentPrefStore::PREF_READ_ERROR_NONE) {
+    // Failing to load prefs on startup is a bad thing(TM). See bug 38352 for
+    // an example problem that this can cause.
+    // Do some diagnosis and try to avoid losing data.
+    int message_id = 0;
+    if (error <= PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE) {
+      message_id = IDS_PREFERENCES_CORRUPT_ERROR;
+    } else if (error != PersistentPrefStore::PREF_READ_ERROR_NO_FILE) {
+      message_id = IDS_PREFERENCES_UNREADABLE_ERROR;
+    }
+
+    if (message_id) {
+      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+          NewRunnableFunction(&NotifyReadError, this, message_id));
+    }
+    UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
   }
-  UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, 20);
+
+  if (delegate_)
+    delegate_->OnPrefsLoaded(this, true);
+}
+
+void PrefService::InitFromStorage() {
+  if (!delegate_) {
+    const PersistentPrefStore::PrefReadError error =
+        user_pref_store_->ReadPrefs();
+    OnPrefsRead(error, false);
+  } else {
+    // todo(altimofeev): move this method to PersistentPrefStore interface.
+    (static_cast<JsonPrefStore*>(user_pref_store_.get()))->ReadPrefs(this);
+  }
 }
 
 bool PrefService::ReloadPersistentPrefs() {