Moves responsibility for showing profile error dialog out of Browser
and into a standalone function. This way we can show the error dialog
if no browser is around (as can happen during startup).

BUG=74639
TEST=none
[email protected],[email protected],[email protected]

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81637 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/history/history.cc b/chrome/browser/history/history.cc
index 4994f3c..4ec7301 100644
--- a/chrome/browser/history/history.cc
+++ b/chrome/browser/history/history.cc
@@ -41,8 +41,7 @@
 #include "chrome/browser/history/top_sites.h"
 #include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/profile_error_dialog.h"
 #include "chrome/browser/visitedlink/visitedlink_master.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/pref_names.h"
@@ -74,21 +73,22 @@
         message_loop_(MessageLoop::current()) {
   }
 
-  virtual void NotifyProfileError(int message_id) {
-    // Send the backend to the history service on the main thread.
+  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {
+    // Send to the history service on the main thread.
     message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
-        &HistoryService::NotifyProfileError, message_id));
+        &HistoryService::NotifyProfileError, init_status));
   }
 
   virtual void SetInMemoryBackend(
-      history::InMemoryHistoryBackend* backend) {
+      history::InMemoryHistoryBackend* backend) OVERRIDE {
     // Send the backend to the history service on the main thread.
     message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
         &HistoryService::SetInMemoryBackend, backend));
   }
 
-  virtual void BroadcastNotifications(NotificationType type,
-                                      history::HistoryDetails* details) {
+  virtual void BroadcastNotifications(
+      NotificationType type,
+      history::HistoryDetails* details) OVERRIDE {
     // Send the notification on the history thread.
     if (NotificationService::current()) {
       Details<history::HistoryDetails> det(details);
@@ -101,12 +101,12 @@
         &HistoryService::BroadcastNotifications, type, details));
   }
 
-  virtual void DBLoaded() {
+  virtual void DBLoaded() OVERRIDE {
     message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
         &HistoryService::OnDBLoaded));
   }
 
-  virtual void StartTopSitesMigration() {
+  virtual void StartTopSitesMigration() OVERRIDE {
     message_loop_->PostTask(FROM_HERE, NewRunnableMethod(history_service_.get(),
         &HistoryService::StartTopSitesMigration));
   }
@@ -722,10 +722,10 @@
   in_memory_backend_->AttachToHistoryService(profile_);
 }
 
-void HistoryService::NotifyProfileError(int message_id) {
-  Source<HistoryService> source(this);
-  NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
-                                         source, Details<int>(&message_id));
+void HistoryService::NotifyProfileError(sql::InitStatus init_status) {
+  ShowProfileErrorDialog(
+      (init_status == sql::INIT_FAILURE) ?
+      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR);
 }
 
 void HistoryService::DeleteURL(const GURL& url) {
diff --git a/chrome/browser/history/history.h b/chrome/browser/history/history.h
index ac7728d..9b8a70a 100644
--- a/chrome/browser/history/history.h
+++ b/chrome/browser/history/history.h
@@ -9,6 +9,7 @@
 #include <set>
 #include <vector>
 
+#include "app/sql/init_status.h"
 #include "base/basictypes.h"
 #include "base/callback.h"
 #include "base/file_path.h"
@@ -680,8 +681,7 @@
   void SetInMemoryBackend(history::InMemoryHistoryBackend* mem_backend);
 
   // Called by our BackendDelegate when there is a problem reading the database.
-  // |message_id| is the relevant message in the string table to display.
-  void NotifyProfileError(int message_id);
+  void NotifyProfileError(sql::InitStatus init_status);
 
   // Call to schedule a given task for running on the history thread with the
   // specified priority. The task will have ownership taken.
diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc
index d067076..6f5d89f 100644
--- a/chrome/browser/history/history_backend.cc
+++ b/chrome/browser/history/history_backend.cc
@@ -530,17 +530,14 @@
 
   // History database.
   db_.reset(new HistoryDatabase());
-  switch (db_->Init(history_name, tmp_bookmarks_file)) {
+  sql::InitStatus status = db_->Init(history_name, tmp_bookmarks_file);
+  switch (status) {
     case sql::INIT_OK:
       break;
     case sql::INIT_FAILURE:
       // A NULL db_ will cause all calls on this object to notice this error
       // and to not continue.
-      delegate_->NotifyProfileError(IDS_COULDNT_OPEN_PROFILE_ERROR);
-      db_.reset();
-      return;
-    case sql::INIT_TOO_NEW:
-      delegate_->NotifyProfileError(IDS_PROFILE_TOO_NEW_ERROR);
+      delegate_->NotifyProfileError(status);
       db_.reset();
       return;
     default:
diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h
index e385001..fd2f0fd 100644
--- a/chrome/browser/history/history_backend.h
+++ b/chrome/browser/history/history_backend.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "app/sql/init_status.h"
 #include "base/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/scoped_ptr.h"
@@ -56,7 +57,7 @@
     virtual ~Delegate() {}
 
     // Called when the database cannot be read correctly for some reason.
-    virtual void NotifyProfileError(int message_id) = 0;
+    virtual void NotifyProfileError(sql::InitStatus init_status) = 0;
 
     // Sets the in-memory history backend. The in-memory backend is created by
     // the main backend. For non-unit tests, this happens on the background
diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc
index 993c8713..effd020 100644
--- a/chrome/browser/history/history_backend_unittest.cc
+++ b/chrome/browser/history/history_backend_unittest.cc
@@ -53,12 +53,12 @@
  public:
   explicit HistoryBackendTestDelegate(HistoryBackendTest* test) : test_(test) {}
 
-  virtual void NotifyProfileError(int message_id) {}
-  virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend);
+  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {}
+  virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend) OVERRIDE;
   virtual void BroadcastNotifications(NotificationType type,
-                                      HistoryDetails* details);
-  virtual void DBLoaded();
-  virtual void StartTopSitesMigration();
+                                      HistoryDetails* details) OVERRIDE;
+  virtual void DBLoaded() OVERRIDE;
+  virtual void StartTopSitesMigration() OVERRIDE;
 
  private:
   // Not owned by us.
diff --git a/chrome/browser/history/history_unittest.cc b/chrome/browser/history/history_unittest.cc
index 068347ab..67a5869 100644
--- a/chrome/browser/history/history_unittest.cc
+++ b/chrome/browser/history/history_unittest.cc
@@ -88,12 +88,12 @@
       : history_test_(history_test) {
   }
 
-  virtual void NotifyProfileError(int message_id);
-  virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend);
+  virtual void NotifyProfileError(sql::InitStatus init_status) OVERRIDE {}
+  virtual void SetInMemoryBackend(InMemoryHistoryBackend* backend) OVERRIDE;
   virtual void BroadcastNotifications(NotificationType type,
-                                      HistoryDetails* details);
-  virtual void DBLoaded() {}
-  virtual void StartTopSitesMigration() {}
+                                      HistoryDetails* details) OVERRIDE;
+  virtual void DBLoaded() OVERRIDE {}
+  virtual void StartTopSitesMigration() OVERRIDE {}
  private:
   HistoryTest* history_test_;
 };
@@ -278,9 +278,6 @@
   HistoryDatabase* db_;  // Cached reference to the backend's database.
 };
 
-void BackendDelegate::NotifyProfileError(int message_id) {
-}
-
 void BackendDelegate::SetInMemoryBackend(InMemoryHistoryBackend* backend) {
   // Save the in-memory backend to the history test object, this happens
   // synchronously, so we don't have to do anything fancy.
diff --git a/chrome/browser/platform_util_win.cc b/chrome/browser/platform_util_win.cc
index 94d82eb..47735c3 100644
--- a/chrome/browser/platform_util_win.cc
+++ b/chrome/browser/platform_util_win.cc
@@ -184,7 +184,8 @@
 void SimpleErrorBox(gfx::NativeWindow parent,
                     const string16& title,
                     const string16& message) {
-  ui::MessageBox(parent, message, title, MB_OK | MB_SETFOREGROUND);
+  ui::MessageBox(parent, message, title,
+                 MB_OK | MB_SETFOREGROUND | MB_ICONWARNING | MB_TOPMOST);
 }
 
 bool SimpleYesNoBox(gfx::NativeWindow parent,
diff --git a/chrome/browser/prefs/pref_service.cc b/chrome/browser/prefs/pref_service.cc
index 0a2f381..abefe070 100644
--- a/chrome/browser/prefs/pref_service.cc
+++ b/chrome/browser/prefs/pref_service.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/prefs/overlay_persistent_pref_store.h"
 #include "chrome/browser/prefs/pref_notifier_impl.h"
 #include "chrome/browser/prefs/pref_value_store.h"
+#include "chrome/browser/ui/profile_error_dialog.h"
 #include "chrome/common/json_pref_store.h"
 #include "content/browser/browser_thread.h"
 #include "content/common/notification_service.h"
@@ -77,9 +78,7 @@
 // Forwards a notification after a PostMessage so that we can wait for the
 // MessageLoop to run.
 void NotifyReadError(PrefService* pref, int message_id) {
-  Source<PrefService> source(pref);
-  NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
-                                         source, Details<int>(&message_id));
+  ShowProfileErrorDialog(message_id);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 8a13c8d..f39854a 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -234,8 +234,6 @@
                  NotificationService::AllSources());
   registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                  NotificationService::AllSources());
-  registrar_.Add(this, NotificationType::PROFILE_ERROR,
-                 NotificationService::AllSources());
 
   // Need to know when to alert the user of theme install delay.
   registrar_.Add(this, NotificationType::EXTENSION_READY_FOR_INSTALL,
@@ -3437,14 +3435,6 @@
       break;
     }
 
-    case NotificationType::PROFILE_ERROR: {
-      if (BrowserList::GetLastActive() != this)
-        break;
-      int* message_id = Details<int>(details).ptr();
-      window()->ShowProfileErrorDialog(*message_id);
-      break;
-    }
-
     case NotificationType::PREF_CHANGED: {
       const std::string& pref_name = *Details<std::string>(details).ptr();
       if (pref_name == prefs::kUseVerticalTabs) {
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index a88b306..83e6308 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -238,11 +238,6 @@
   // Shows the collected cookies dialog box.
   virtual void ShowCollectedCookiesDialog(TabContents* tab_contents) = 0;
 
-  // Shows a dialog to the user that something is wrong with the profile.
-  // |message_id| is the ID for a string in the string table which will be
-  // displayed in the dialog.
-  virtual void ShowProfileErrorDialog(int message_id) = 0;
-
   // Show the bubble that indicates to the user that a theme is being installed.
   virtual void ShowThemeInstallBubble() = 0;
 
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index 48333e7..37455560 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -81,7 +81,6 @@
   virtual DownloadShelf* GetDownloadShelf();
   virtual void ShowRepostFormWarningDialog(TabContents* tab_contents);
   virtual void ShowCollectedCookiesDialog(TabContents* tab_contents);
-  virtual void ShowProfileErrorDialog(int message_id);
   virtual void ShowThemeInstallBubble();
   virtual void ConfirmBrowserCloseWithPendingDownloads();
   virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index de0d680..43fdb57e 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -339,15 +339,6 @@
   new CollectedCookiesMac(GetNativeHandle(), tab_contents);
 }
 
-void BrowserWindowCocoa::ShowProfileErrorDialog(int message_id) {
-  scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
-  [alert addButtonWithTitle:l10n_util::GetNSStringWithFixup(IDS_OK)];
-  [alert setMessageText:l10n_util::GetNSStringWithFixup(IDS_PRODUCT_NAME)];
-  [alert setInformativeText:l10n_util::GetNSStringWithFixup(message_id)];
-  [alert setAlertStyle:NSWarningAlertStyle];
-  [alert runModal];
-}
-
 void BrowserWindowCocoa::ShowThemeInstallBubble() {
   ThemeInstallBubbleView::Show(window());
 }
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index dc18cc2..8ea0fdb 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -926,18 +926,6 @@
   new CollectedCookiesGtk(GetNativeHandle(), tab_contents);
 }
 
-void BrowserWindowGtk::ShowProfileErrorDialog(int message_id) {
-  std::string title = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
-  std::string message = l10n_util::GetStringUTF8(message_id);
-  GtkWidget* dialog = gtk_message_dialog_new(window_,
-      static_cast<GtkDialogFlags>(0), GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
-      "%s", message.c_str());
-  gtk_util::ApplyMessageDialogQuirks(dialog);
-  gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
-  g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
-  gtk_widget_show_all(dialog);
-}
-
 void BrowserWindowGtk::ShowThemeInstallBubble() {
   ThemeInstallBubbleViewGtk::Show(window_);
 }
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 8c8ef49..9093274ff 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -103,7 +103,6 @@
   virtual DownloadShelf* GetDownloadShelf();
   virtual void ShowRepostFormWarningDialog(TabContents* tab_contents);
   virtual void ShowCollectedCookiesDialog(TabContents* tab_contents);
-  virtual void ShowProfileErrorDialog(int message_id);
   virtual void ShowThemeInstallBubble();
   virtual void ConfirmBrowserCloseWithPendingDownloads();
   virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc
index 82e63b5c..a0ce9fc 100644
--- a/chrome/browser/ui/panels/panel.cc
+++ b/chrome/browser/ui/panels/panel.cc
@@ -250,10 +250,6 @@
   NOTIMPLEMENTED();
 }
 
-void Panel::ShowProfileErrorDialog(int message_id) {
-  NOTIMPLEMENTED();
-}
-
 void Panel::ShowThemeInstallBubble() {
   NOTIMPLEMENTED();
 }
diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h
index e692af19..aa8c21c1 100644
--- a/chrome/browser/ui/panels/panel.h
+++ b/chrome/browser/ui/panels/panel.h
@@ -93,7 +93,6 @@
   virtual DownloadShelf* GetDownloadShelf();
   virtual void ShowRepostFormWarningDialog(TabContents* tab_contents);
   virtual void ShowCollectedCookiesDialog(TabContents* tab_contents);
-  virtual void ShowProfileErrorDialog(int message_id);
   virtual void ShowThemeInstallBubble();
   virtual void ConfirmBrowserCloseWithPendingDownloads();
   virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
diff --git a/chrome/browser/ui/profile_error_dialog.cc b/chrome/browser/ui/profile_error_dialog.cc
new file mode 100644
index 0000000..6aa65f7
--- /dev/null
+++ b/chrome/browser/ui/profile_error_dialog.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 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.
+
+#include "chrome/browser/ui/profile_error_dialog.h"
+
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+void ShowProfileErrorDialog(int message_id) {
+  // Parent the dialog to the current browser. During startup there may be no
+  // browser.
+  Browser* browser = BrowserList::GetLastActive();
+  platform_util::SimpleErrorBox(
+      browser ? browser->window()->GetNativeHandle() : NULL,
+      l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
+      l10n_util::GetStringUTF16(message_id));
+}
diff --git a/chrome/browser/ui/profile_error_dialog.h b/chrome/browser/ui/profile_error_dialog.h
new file mode 100644
index 0000000..a418955
--- /dev/null
+++ b/chrome/browser/ui/profile_error_dialog.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2011 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.
+
+#ifndef CHROME_BROWSER_UI_PROFILE_ERROR_DIALOG_H_
+#define CHROME_BROWSER_UI_PROFILE_ERROR_DIALOG_H_
+#pragma once
+
+// Shows an error dialog corresponding to the inability to open some portion of
+// the profile. |message_id| is a string id corresponding to the message to
+// show.
+void ShowProfileErrorDialog(int message_id);
+
+#endif  // CHROME_BROWSER_UI_PROFILE_ERROR_DIALOG_H_
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 0e62385..2bcc9c1 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -961,26 +961,6 @@
   browser::ShowCollectedCookiesDialog(GetNativeHandle(), tab_contents);
 }
 
-void BrowserView::ShowProfileErrorDialog(int message_id) {
-#if defined(OS_WIN)
-  string16 title = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
-  string16 message = l10n_util::GetStringUTF16(message_id);
-  ui::MessageBox(GetNativeHandle(), message, title,
-                 MB_OK | MB_ICONWARNING | MB_TOPMOST);
-#elif defined(OS_LINUX)
-  std::string title = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
-  std::string message = l10n_util::GetStringUTF8(message_id);
-  GtkWidget* dialog = gtk_message_dialog_new(GetNativeHandle(),
-      static_cast<GtkDialogFlags>(0), GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
-      "%s", message.c_str());
-  gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
-  g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL);
-  gtk_widget_show_all(dialog);
-#else
-  NOTIMPLEMENTED();
-#endif
-}
-
 void BrowserView::ShowThemeInstallBubble() {
   TabContents* tab_contents = browser_->GetSelectedTabContents();
   if (!tab_contents)
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index cdeeb62..81171e0 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -278,7 +278,6 @@
   virtual DownloadShelf* GetDownloadShelf() OVERRIDE;
   virtual void ShowRepostFormWarningDialog(TabContents* tab_contents) OVERRIDE;
   virtual void ShowCollectedCookiesDialog(TabContents* tab_contents) OVERRIDE;
-  virtual void ShowProfileErrorDialog(int message_id) OVERRIDE;
   virtual void ShowThemeInstallBubble() OVERRIDE;
   virtual void ConfirmBrowserCloseWithPendingDownloads() OVERRIDE;
   virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
diff --git a/chrome/browser/webdata/web_data_service.cc b/chrome/browser/webdata/web_data_service.cc
index e14cc32..30d3f33 100644
--- a/chrome/browser/webdata/web_data_service.cc
+++ b/chrome/browser/webdata/web_data_service.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/autofill/autofill_profile.h"
 #include "chrome/browser/autofill/credit_card.h"
 #include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/ui/profile_error_dialog.h"
 #include "chrome/browser/webdata/autofill_change.h"
 #include "chrome/browser/webdata/autofill_entry.h"
 #include "chrome/browser/webdata/web_database.h"
@@ -569,11 +570,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 void WebDataService::DBInitFailed(sql::InitStatus init_status) {
-  Source<WebDataService> source(this);
-  int message_id = (init_status == sql::INIT_FAILURE) ?
-      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR;
-  NotificationService::current()->Notify(NotificationType::PROFILE_ERROR,
-                                         source, Details<int>(&message_id));
+  ShowProfileErrorDialog(
+      (init_status == sql::INIT_FAILURE) ?
+      IDS_COULDNT_OPEN_PROFILE_ERROR : IDS_PROFILE_TOO_NEW_ERROR);
 }
 
 void WebDataService::InitializeDatabaseIfNecessary() {