[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "chrome/browser/ui/browser_instant_controller.h" |
| 6 | |
| 7 | #include "chrome/browser/browser_shutdown.h" |
| 8 | #include "chrome/browser/extensions/extension_service.h" |
| 9 | #include "chrome/browser/instant/instant_controller.h" |
[email protected] | fb8fdf1 | 2012-08-21 16:28:20 | [diff] [blame] | 10 | #include "chrome/browser/prefs/pref_service.h" |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 11 | #include "chrome/browser/profiles/profile.h" |
| 12 | #include "chrome/browser/ui/browser.h" |
| 13 | #include "chrome/browser/ui/browser_tabstrip.h" |
| 14 | #include "chrome/browser/ui/browser_window.h" |
| 15 | #include "chrome/browser/ui/omnibox/location_bar.h" |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 16 | #include "chrome/browser/ui/search/search_model.h" |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 17 | #include "chrome/browser/ui/search/search_tab_helper.h" |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 18 | #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 19 | #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 20 | #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
| 21 | #include "chrome/common/chrome_notification_types.h" |
| 22 | #include "chrome/common/pref_names.h" |
| 23 | #include "content/public/browser/notification_service.h" |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 24 | #include "content/public/browser/web_contents.h" |
| 25 | |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 26 | namespace { |
| 27 | |
| 28 | // Returns true iff the search model for |tab| is in an NTP state, that is, a |
| 29 | // state in which the Instant overlay may be showing custom NTP content in |
| 30 | // EXTENDED mode. |
[email protected] | 8e70779 | 2012-11-13 10:32:12 | [diff] [blame] | 31 | bool IsSearchModelNTP(content::WebContents* tab) { |
| 32 | if (!tab) |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 33 | return false; |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 34 | chrome::search::SearchModel* model = |
[email protected] | 8e70779 | 2012-11-13 10:32:12 | [diff] [blame] | 35 | chrome::search::SearchTabHelper::FromWebContents(tab)->model(); |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 36 | return model && model->mode().is_ntp(); |
| 37 | } |
| 38 | |
| 39 | } // namespace |
| 40 | |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 41 | namespace chrome { |
| 42 | |
| 43 | //////////////////////////////////////////////////////////////////////////////// |
| 44 | // BrowserInstantController, public: |
| 45 | |
| 46 | BrowserInstantController::BrowserInstantController(Browser* browser) |
[email protected] | 8a23670 | 2012-09-28 13:30:57 | [diff] [blame] | 47 | : browser_(browser), |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 48 | instant_unload_handler_(browser) { |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 49 | profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); |
| 50 | profile_pref_registrar_.Add(prefs::kInstantEnabled, this); |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 51 | ResetInstant(); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 52 | browser_->tab_strip_model()->AddObserver(this); |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 53 | browser_->search_model()->AddObserver(this); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | BrowserInstantController::~BrowserInstantController() { |
| 57 | browser_->tab_strip_model()->RemoveObserver(this); |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 58 | browser_->search_model()->RemoveObserver(this); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 62 | // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't attempt |
| 63 | // to use the Instant preview. |
| 64 | if (!instant() || !instant_->IsCurrent() || disposition == NEW_BACKGROUND_TAB) |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 65 | return false; |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 66 | |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 67 | // The omnibox currently doesn't use other dispositions, so we don't attempt |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 68 | // to handle them. If you hit this DCHECK file a bug and I'll (sky) add |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 69 | // support for the new disposition. |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 70 | DCHECK(disposition == CURRENT_TAB || |
| 71 | disposition == NEW_FOREGROUND_TAB) << disposition; |
| 72 | |
| 73 | instant_->CommitCurrentPreview(disposition == CURRENT_TAB ? |
| 74 | INSTANT_COMMIT_PRESSED_ENTER : INSTANT_COMMIT_PRESSED_ALT_ENTER); |
| 75 | return true; |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 76 | } |
| 77 | |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 78 | void BrowserInstantController::CommitInstant(TabContents* preview, |
| 79 | bool in_new_tab) { |
| 80 | if (in_new_tab) { |
| 81 | // TabStripModel takes ownership of |preview|. |
| 82 | browser_->tab_strip_model()->AddTabContents(preview, -1, |
| 83 | instant_->last_transition_type(), TabStripModel::ADD_ACTIVE); |
| 84 | } else { |
[email protected] | 59253a65 | 2012-11-20 00:17:26 | [diff] [blame] | 85 | TabContents* active_tab = |
| 86 | browser_->tab_strip_model()->GetActiveTabContents(); |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 87 | int index = browser_->tab_strip_model()->GetIndexOfTabContents(active_tab); |
| 88 | DCHECK_NE(TabStripModel::kNoTab, index); |
| 89 | // TabStripModel takes ownership of |preview|. |
| 90 | browser_->tab_strip_model()->ReplaceTabContentsAt(index, preview); |
| 91 | // InstantUnloadHandler takes ownership of |active_tab|. |
| 92 | instant_unload_handler_.RunUnloadListenersOrDestroy(active_tab, index); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 93 | |
[email protected] | c72226c8 | 2012-10-01 21:02:32 | [diff] [blame] | 94 | GURL url = preview->web_contents()->GetURL(); |
| 95 | DCHECK(browser_->profile()->GetExtensionService()); |
| 96 | if (browser_->profile()->GetExtensionService()->IsInstalledApp(url)) { |
| 97 | AppLauncherHandler::RecordAppLaunchType( |
| 98 | extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); |
| 99 | } |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 100 | } |
| 101 | } |
| 102 | |
[email protected] | 93b7383 | 2012-10-18 20:18:38 | [diff] [blame] | 103 | void BrowserInstantController::SetInstantSuggestion( |
| 104 | const InstantSuggestion& suggestion) { |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 105 | if (browser_->window()->GetLocationBar()) |
[email protected] | 93b7383 | 2012-10-18 20:18:38 | [diff] [blame] | 106 | browser_->window()->GetLocationBar()->SetInstantSuggestion(suggestion); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | gfx::Rect BrowserInstantController::GetInstantBounds() { |
| 110 | return browser_->window()->GetInstantBounds(); |
| 111 | } |
| 112 | |
| 113 | void BrowserInstantController::InstantPreviewFocused() { |
| 114 | // NOTE: This is only invoked on aura. |
| 115 | browser_->window()->WebContentsFocused( |
| 116 | instant_->GetPreviewContents()->web_contents()); |
| 117 | } |
| 118 | |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 119 | TabContents* BrowserInstantController::GetActiveTabContents() const { |
[email protected] | 59253a65 | 2012-11-20 00:17:26 | [diff] [blame] | 120 | return browser_->tab_strip_model()->GetActiveTabContents(); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 124 | // BrowserInstantController, PrefObserver implementation: |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 125 | |
[email protected] | a6a7ced | 2012-11-01 17:24:18 | [diff] [blame] | 126 | void BrowserInstantController::OnPreferenceChanged( |
| 127 | PrefServiceBase* service, |
| 128 | const std::string& pref_name) { |
| 129 | DCHECK_EQ(std::string(prefs::kInstantEnabled), pref_name); |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 130 | ResetInstant(); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 131 | } |
| 132 | |
| 133 | //////////////////////////////////////////////////////////////////////////////// |
| 134 | // BrowserInstantController, TabStripModelObserver implementation: |
| 135 | |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 136 | void BrowserInstantController::ActiveTabChanged( |
[email protected] | 8e70779 | 2012-11-13 10:32:12 | [diff] [blame] | 137 | content::WebContents* old_contents, |
| 138 | content::WebContents* new_contents, |
[email protected] | 9d3d1170 | 2012-11-08 01:01:12 | [diff] [blame] | 139 | int index, |
| 140 | bool user_gesture) { |
| 141 | if (instant()) { |
| 142 | const bool old_is_ntp = IsSearchModelNTP(old_contents); |
| 143 | const bool new_is_ntp = IsSearchModelNTP(new_contents); |
| 144 | // Do not hide Instant if switching from an NTP to another NTP since that |
| 145 | // would cause custom NTP content to flicker. |
| 146 | if (!(old_is_ntp && new_is_ntp)) |
| 147 | instant()->Hide(); |
| 148 | } |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 149 | } |
| 150 | |
[email protected] | 749ce88 | 2012-11-16 04:18:01 | [diff] [blame] | 151 | void BrowserInstantController::TabStripEmpty() { |
| 152 | instant_.reset(); |
| 153 | } |
| 154 | |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 155 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 156 | // BrowserInstantController, search::SearchModelObserver implementation: |
| 157 | |
| 158 | void BrowserInstantController::ModeChanged(const search::Mode& old_mode, |
| 159 | const search::Mode& new_mode) { |
[email protected] | 2989f00 | 2012-11-15 05:33:20 | [diff] [blame] | 160 | if (instant()) |
| 161 | instant_->OnActiveTabModeChanged(new_mode); |
[email protected] | 0b10c9ff | 2012-10-09 17:31:55 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | //////////////////////////////////////////////////////////////////////////////// |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 165 | // BrowserInstantController, private: |
| 166 | |
[email protected] | c55e3b8 | 2012-08-09 15:27:05 | [diff] [blame] | 167 | void BrowserInstantController::ResetInstant() { |
[email protected] | b67d0a4 | 2012-09-04 20:57:35 | [diff] [blame] | 168 | instant_.reset( |
| 169 | !browser_shutdown::ShuttingDownWithoutClosingBrowsers() && |
| 170 | browser_->is_type_tabbed() ? |
| 171 | InstantController::CreateInstant(browser_->profile(), this) : NULL); |
[email protected] | e4e15dc | 2012-10-18 03:22:50 | [diff] [blame] | 172 | |
| 173 | // Notify any observers that they need to reset. |
| 174 | content::NotificationService::current()->Notify( |
| 175 | chrome::NOTIFICATION_BROWSER_INSTANT_RESET, |
| 176 | content::Source<BrowserInstantController>(this), |
| 177 | content::NotificationService::NoDetails()); |
[email protected] | 7acfaf9 | 2012-07-11 15:51:59 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | } // namespace chrome |