Adds confirm dialog when enabling instant.

BUG=58567
TEST=none

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62197 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index dd54f07a..400f0e37 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4013,15 +4013,21 @@
       </message>
 
       <!-- Instant -->
-      <message name="IDS_INSTANT_OPT_IN_LABEL" desc="Label shown in the omnibox dropdown for enabling instant">
-        Enable Instant for faster searching?
-      </message>
       <message name="IDS_INSTANT_OPT_IN_ENABLE" desc="Button shown in the omnibox dropdown for enabling instant">
         Enable...
       </message>
       <message name="IDS_INSTANT_OPT_IN_NO_THANKS" desc="Button shown in the omnibox dropdodown for not enabling instant">
         No thanks
       </message>
+      <message name="IDS_INSTANT_OPT_IN_LABEL" desc="Label shown in the omnibox dropdown for enabling instant">
+        Enable Instant for faster searching and browsing?
+      </message>
+      <message name="IDS_INSTANT_OPT_IN_TITLE" desc="Title of the instant opt-in dialog">
+        Instant
+      </message>
+      <message name="IDS_INSTANT_OPT_IN_MESSAGE" desc="Message shown in the instant opt-in dialog">
+        Instant lets you view web pages and search results faster than ever!\n\nWith Instant enabled, most web pages begin loading as soon as you type a URL in the omnibox, before you hit Enter. In addition, if supported by your default search engine, search results appear instantly as you type queries in the omnibox, and in-line predictions help guide your search.\n\nBecause new search results are requested each time you press a key, anything you type into the omnibox may be logged as a search query by your default search engine.\n\n
+      </message>
 
       <!-- Click-to-load -->
       <message name="IDS_PLUGIN_LOAD" desc="The link for loading a blocked plug-in, displayed in the click-to-play UI.">
diff --git a/chrome/app/resources/locale_settings.grd b/chrome/app/resources/locale_settings.grd
index 305f0b5b1..bbe300f 100644
--- a/chrome/app/resources/locale_settings.grd
+++ b/chrome/app/resources/locale_settings.grd
@@ -700,6 +700,12 @@
       <message name="IDS_SIMPLE_CONTENT_EXCEPTION_DIALOG_HEIGHT_LINES" use_name_for_id="true">
         16
       </message>
+
+      <!-- The width of the Instant confirm dialog box in characters. -->
+      <message name="IDS_INSTANT_CONFIRM_DIALOG_WIDTH_CHARS" use_name_for_id="true">
+        95
+      </message>
+
       <if expr="pp_ifdef('chromeos')">
         <!-- The width and height of the Languages and Input dialog box in -->
         <!-- characters and lines (See above). -->
diff --git a/chrome/browser/instant/instant_confirm_dialog.cc b/chrome/browser/instant/instant_confirm_dialog.cc
new file mode 100644
index 0000000..680cdf3
--- /dev/null
+++ b/chrome/browser/instant/instant_confirm_dialog.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 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/instant/instant_confirm_dialog.h"
+
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/pref_names.h"
+
+namespace browser {
+
+// TODO: get the right url.
+const char kInstantLearnMoreURL[] = "http://www.google.com";
+
+void ShowInstantConfirmDialogIfNecessary(gfx::NativeWindow parent,
+                                         Profile* profile) {
+  PrefService* prefs = profile->GetPrefs();
+  if (!prefs)
+    return;
+
+  if (prefs->GetBoolean(prefs::kInstantConfirmDialogShown)) {
+    prefs->SetBoolean(prefs::kInstantEnabled, true);
+    return;
+  }
+
+  prefs->SetBoolean(prefs::kInstantConfirmDialogShown, true);
+  ShowInstantConfirmDialog(parent, profile);
+}
+
+#if !defined(TOOLKIT_VIEWS)
+void ShowInstantConfirmDialog(gfx::NativeWindow parent,
+                              Profile* profile) {
+  NOTIMPLEMENTED();
+}
+#endif
+
+}  // namespace browser
diff --git a/chrome/browser/instant/instant_confirm_dialog.h b/chrome/browser/instant/instant_confirm_dialog.h
new file mode 100644
index 0000000..54daaf5
--- /dev/null
+++ b/chrome/browser/instant/instant_confirm_dialog.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 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_INSTANT_INSTANT_CONFIRM_DIALOG_H_
+#define CHROME_BROWSER_INSTANT_INSTANT_CONFIRM_DIALOG_H_
+#pragma once
+
+#include "gfx/native_widget_types.h"
+
+class Profile;
+
+namespace browser {
+
+// URL for learning more about instant.
+extern const char kInstantLearnMoreURL[];
+
+// Invoked from the opt-in and preferences when the user toggles instant. If the
+// instant confirm dialog hasn't been shown, it's shown. If the instant dialog
+// has already been shown the dialog is not shown but the preference is toggled.
+void ShowInstantConfirmDialogIfNecessary(gfx::NativeWindow parent,
+                                         Profile* profile);
+
+// Shows the platform specific dialog to confirm if the user really wants to
+// enable opt-in.
+void ShowInstantConfirmDialog(gfx::NativeWindow parent,
+                              Profile* profile);
+
+}  // namespace browser
+
+#endif  // CHROME_BROWSER_INSTANT_INSTANT_CONFIRM_DIALOG_H_
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index cc4afa4..3c30c44 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -9,18 +9,27 @@
 #include "chrome/browser/instant/instant_delegate.h"
 #include "chrome/browser/instant/instant_loader.h"
 #include "chrome/browser/instant/instant_loader_manager.h"
+#include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profile.h"
 #include "chrome/browser/search_engines/template_url.h"
 #include "chrome/browser/search_engines/template_url_model.h"
 #include "chrome/browser/tab_contents/tab_contents.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
 
 // Number of ms to delay between loading urls.
 static const int kUpdateDelayMS = 200;
 
 // static
+void InstantController::RegisterUserPrefs(PrefService* prefs) {
+  prefs->RegisterBooleanPref(prefs::kInstantConfirmDialogShown, false);
+  prefs->RegisterBooleanPref(prefs::kInstantEnabled, false);
+}
+
+// static
 bool InstantController::IsEnabled() {
+  // TODO: convert to kInstantEnabled once pref lands.
   static bool enabled = false;
   static bool checked = false;
   if (!checked) {
diff --git a/chrome/browser/instant/instant_controller.h b/chrome/browser/instant/instant_controller.h
index 992d927..84a15a2 100644
--- a/chrome/browser/instant/instant_controller.h
+++ b/chrome/browser/instant/instant_controller.h
@@ -22,6 +22,7 @@
 struct AutocompleteMatch;
 class InstantDelegate;
 class InstantLoaderManager;
+class PrefService;
 class TabContents;
 class TemplateURL;
 
@@ -38,6 +39,9 @@
   explicit InstantController(InstantDelegate* delegate);
   ~InstantController();
 
+  // Registers instant related preferences.
+  static void RegisterUserPrefs(PrefService* prefs);
+
   // Is InstantController enabled?
   static bool IsEnabled();
 
diff --git a/chrome/browser/instant/instant_opt_in.cc b/chrome/browser/instant/instant_opt_in.cc
index 611625a..02648813 100644
--- a/chrome/browser/instant/instant_opt_in.cc
+++ b/chrome/browser/instant/instant_opt_in.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/instant/instant_opt_in.h"
 
+#include "chrome/browser/instant/instant_confirm_dialog.h"
 #include "chrome/browser/profile.h"
 
 namespace browser {
@@ -13,8 +14,12 @@
   return false;
 }
 
-void UserPickedInstantOptIn(Profile* profile, bool opt_in) {
-  // TODO(sky): implement me.
+void UserPickedInstantOptIn(gfx::NativeWindow parent,
+                            Profile* profile,
+                            bool opt_in) {
+  // TODO: set pref so don't show opt-in again.
+  if (opt_in)
+    browser::ShowInstantConfirmDialogIfNecessary(parent, profile);
 }
 
 }  // namespace browser
diff --git a/chrome/browser/instant/instant_opt_in.h b/chrome/browser/instant/instant_opt_in.h
index a6505fb..55c62fb 100644
--- a/chrome/browser/instant/instant_opt_in.h
+++ b/chrome/browser/instant/instant_opt_in.h
@@ -6,7 +6,7 @@
 #define CHROME_BROWSER_INSTANT_INSTANT_OPT_IN_H_
 #pragma once
 
-#include "base/basictypes.h"
+#include "gfx/native_widget_types.h"
 
 class Profile;
 
@@ -16,7 +16,9 @@
 bool ShouldShowInstantOptIn(Profile* profile);
 
 // Invoked if the user clicks on the opt-in promo.
-void UserPickedInstantOptIn(Profile* profile, bool opt_in);
+void UserPickedInstantOptIn(gfx::NativeWindow parent,
+                            Profile* profile,
+                            bool opt_in);
 
 }  // namespace browser
 
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index a015d457..c27ad252 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -25,6 +25,7 @@
 #include "chrome/browser/host_content_settings_map.h"
 #include "chrome/browser/host_zoom_map.h"
 #include "chrome/browser/intranet_redirect_detector.h"
+#include "chrome/browser/instant/instant_controller.h"
 #include "chrome/browser/labs.h"
 #include "chrome/browser/metrics/metrics_log.h"
 #include "chrome/browser/metrics/metrics_service.h"
@@ -143,6 +144,7 @@
   BackgroundContentsService::RegisterUserPrefs(user_prefs);
   SigninManager::RegisterUserPrefs(user_prefs);
   TemplateURLModel::RegisterUserPrefs(user_prefs);
+  InstantController::RegisterUserPrefs(user_prefs);
 }
 
 }  // namespace browser
diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
index a3b6071..34ddcb5 100644
--- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
+++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
@@ -22,6 +22,7 @@
 #include "gfx/color_utils.h"
 #include "gfx/insets.h"
 #include "gfx/path.h"
+#include "grit/chromium_strings.h"
 #include "grit/generated_resources.h"
 #include "grit/theme_resources.h"
 #include "third_party/skia/include/core/SkShader.h"
@@ -30,6 +31,7 @@
 #include "views/grid_layout.h"
 #include "views/standard_layout.h"
 #include "views/widget/widget.h"
+#include "views/window/window.h"
 
 #if defined(OS_WIN)
 #include <objidl.h>
@@ -193,7 +195,7 @@
     views::TextButton* button =
         new views::TextButton(this, l10n_util::GetString(id));
     button->SetNormalHasBorder(true);
-    button->set_tag(IDS_INSTANT_OPT_IN_NO_THANKS);
+    button->set_tag(id);
     button->SetFont(font);
     button->set_animate_on_state_change(false);
     return button;
@@ -1141,6 +1143,7 @@
 void AutocompletePopupContentsView::UserPressedOptIn(bool opt_in) {
   delete opt_in_view_;
   opt_in_view_ = NULL;
-  browser::UserPickedInstantOptIn(model_->profile(), opt_in);
+  browser::UserPickedInstantOptIn(location_bar_->GetWindow()->GetNativeWindow(),
+                                  model_->profile(), opt_in);
   UpdatePopupAppearance();
 }
diff --git a/chrome/browser/views/instant_confirm_view.cc b/chrome/browser/views/instant_confirm_view.cc
new file mode 100644
index 0000000..02ac089
--- /dev/null
+++ b/chrome/browser/views/instant_confirm_view.cc
@@ -0,0 +1,95 @@
+// Copyright (c) 2010 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/views/instant_confirm_view.h"
+
+#include "app/l10n_util.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/instant/instant_confirm_dialog.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/common/pref_names.h"
+#include "grit/generated_resources.h"
+#include "grit/locale_settings.h"
+#include "views/controls/label.h"
+#include "views/grid_layout.h"
+#include "views/layout_manager.h"
+#include "views/standard_layout.h"
+#include "views/window/window.h"
+
+InstantConfirmView::InstantConfirmView(Profile* profile) : profile_(profile) {
+  views::Label* description_label = new views::Label(
+      l10n_util::GetString(IDS_INSTANT_OPT_IN_MESSAGE));
+  description_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+  description_label->SetMultiLine(true);
+
+  views::Link* learn_more_link = new views::Link(
+      l10n_util::GetString(IDS_LEARN_MORE));
+  learn_more_link->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+  learn_more_link->SetController(this);
+
+  views::GridLayout* layout = CreatePanelGridLayout(this);
+  SetLayoutManager(layout);
+
+  const int first_column_set = 1;
+  views::ColumnSet* column_set = layout->AddColumnSet(first_column_set);
+  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
+                        views::GridLayout::USE_PREF, 0, 0);
+  layout->StartRow(0, first_column_set);
+  layout->AddView(description_label);
+  layout->StartRow(0, first_column_set);
+  layout->AddView(learn_more_link);
+}
+
+bool InstantConfirmView::Accept(bool window_closing) {
+  return Accept();
+}
+
+bool InstantConfirmView::Accept() {
+  PrefService* prefs = profile_->GetPrefs();
+  if (prefs)
+    prefs->SetBoolean(prefs::kInstantEnabled, true);
+  return true;
+}
+
+bool InstantConfirmView::Cancel() {
+  return true;
+}
+
+views::View* InstantConfirmView::GetContentsView() {
+  return this;
+}
+
+std::wstring InstantConfirmView::GetWindowTitle() const {
+  return l10n_util::GetString(IDS_INSTANT_OPT_IN_TITLE);
+}
+
+gfx::Size InstantConfirmView::GetPreferredSize() {
+  DCHECK(GetLayoutManager());
+  int pref_width = views::Window::GetLocalizedContentsWidth(
+      IDS_INSTANT_CONFIRM_DIALOG_WIDTH_CHARS);
+  int pref_height =
+      GetLayoutManager()->GetPreferredHeightForWidth(this, pref_width);
+  return gfx::Size(pref_width, pref_height);
+}
+
+bool InstantConfirmView::IsModal() const {
+  return true;
+}
+
+void InstantConfirmView::LinkActivated(views::Link* source, int event_flags) {
+  Browser* browser = BrowserList::GetLastActive();
+  browser->OpenURL(GURL(browser::kInstantLearnMoreURL), GURL(),
+                   NEW_FOREGROUND_TAB, PageTransition::TYPED);
+}
+
+namespace browser {
+
+void ShowInstantConfirmDialog(gfx::NativeWindow parent, Profile* profile) {
+  views::Window::CreateChromeWindow(parent, gfx::Rect(),
+                                    new InstantConfirmView(profile))->Show();
+}
+
+}  // namespace browser
diff --git a/chrome/browser/views/instant_confirm_view.h b/chrome/browser/views/instant_confirm_view.h
new file mode 100644
index 0000000..958837c
--- /dev/null
+++ b/chrome/browser/views/instant_confirm_view.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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_VIEWS_INSTANT_CONFIRM_VIEW_H_
+#define CHROME_BROWSER_VIEWS_INSTANT_CONFIRM_VIEW_H_
+#pragma once
+
+#include "views/controls/label.h"
+#include "views/controls/link.h"
+#include "views/view.h"
+#include "views/window/dialog_delegate.h"
+
+class Profile;
+
+// The view shown in the instant confirm dialog.
+class InstantConfirmView : public views::View,
+                           public views::DialogDelegate,
+                           public views::LinkController {
+ public:
+  explicit InstantConfirmView(Profile* profile);
+
+  // DialogDelegate overrides:
+  virtual bool Accept(bool window_closing);
+  virtual bool Accept();
+  virtual bool Cancel();
+  virtual views::View* GetContentsView();
+  virtual std::wstring GetWindowTitle() const;
+  virtual gfx::Size GetPreferredSize();
+  virtual bool IsModal() const;
+
+  // LinkController overrides:
+  virtual void LinkActivated(views::Link* source, int event_flags);
+
+ private:
+  Profile* profile_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstantConfirmView);
+};
+
+#endif  // CHROME_BROWSER_VIEWS_INSTANT_CONFIRM_VIEW_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 5ab781f..8df0be89 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2080,6 +2080,8 @@
         'browser/input_window_dialog_gtk.cc',
         'browser/input_window_dialog_win.cc',
         'browser/instant/instant_commit_type.h',
+        'browser/instant/instant_confirm_dialog.cc',
+        'browser/instant/instant_confirm_dialog.h',
         'browser/instant/instant_controller.cc',
         'browser/instant/instant_controller.h',
         'browser/instant/instant_delegate.h',
@@ -3051,6 +3053,8 @@
         'browser/views/infobars/translate_infobar_base.h',
         'browser/views/infobars/translate_message_infobar.cc',
         'browser/views/infobars/translate_message_infobar.h',
+        'browser/views/instant_confirm_view.cc',
+        'browser/views/instant_confirm_view.h',
         'browser/views/js_modal_dialog_views.cc',
         'browser/views/js_modal_dialog_views.h',
         'browser/views/keyword_editor_view.cc',
@@ -3739,6 +3743,8 @@
                 ['include', '^browser/views/info_bubble.h'],
                 ['include', '^browser/views/html_dialog_view.cc'],
                 ['include', '^browser/views/html_dialog_view.h'],
+                ['include', '^browser/views/instant_confirm_view.cc'],
+                ['include', '^browser/views/instant_confirm_view.h'],
                 ['include', '^browser/views/js_modal_dialog_views.cc'],
                 ['include', '^browser/views/js_modal_dialog_views.h'],
                 ['include', '^browser/views/location_bar/click_handler.cc'],
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 6fc57def..e0a0844 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -198,6 +198,12 @@
 // Is the cookie prompt expanded?
 const char kCookiePromptExpanded[] = "cookieprompt.expanded";
 
+// Boolean pref indicating whether the instant confirm dialog has been shown.
+const char kInstantConfirmDialogShown[] = "instant.confirm_dialog_shown";
+
+// Boolean pref indicating if instant is enabled.
+const char kInstantEnabled[] = "instant.enabled";
+
 #if defined(USE_NSS)
 // Prefs for SSLConfigServicePref.  Currently, these are only present on
 // and used by NSS-using OSes.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 08e1433..41ee3ed6 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -71,6 +71,8 @@
 extern const char kDnsStartupPrefetchList[];
 extern const char kDnsHostReferralList[];
 extern const char kCookiePromptExpanded[];
+extern const char kInstantConfirmDialogShown[];
+extern const char kInstantEnabled[];
 #if defined(USE_NSS)
 extern const char kCertRevocationCheckingEnabled[];
 extern const char kSSL2Enabled[];