OLD | NEW |
(Empty) | |
| 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" |
| 10 #include "chrome/browser/instant/instant_unload_handler.h" |
| 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" |
| 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 17 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 18 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
| 19 #include "chrome/common/chrome_notification_types.h" |
| 20 #include "chrome/common/pref_names.h" |
| 21 #include "content/public/browser/notification_service.h" |
| 22 #include "content/public/browser/notification_source.h" |
| 23 #include "content/public/browser/web_contents.h" |
| 24 |
| 25 |
| 26 namespace chrome { |
| 27 |
| 28 //////////////////////////////////////////////////////////////////////////////// |
| 29 // BrowserInstantController, public: |
| 30 |
| 31 BrowserInstantController::BrowserInstantController(Browser* browser) |
| 32 : browser_(browser) { |
| 33 profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); |
| 34 profile_pref_registrar_.Add(prefs::kInstantEnabled, this); |
| 35 CreateInstantIfNecessary(); |
| 36 browser_->tab_strip_model()->AddObserver(this); |
| 37 } |
| 38 |
| 39 BrowserInstantController::~BrowserInstantController() { |
| 40 browser_->tab_strip_model()->RemoveObserver(this); |
| 41 } |
| 42 |
| 43 bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { |
| 44 if (!instant() || !instant()->PrepareForCommit() || |
| 45 disposition == NEW_BACKGROUND_TAB) { |
| 46 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't |
| 47 // attempt to use the instant preview. |
| 48 return false; |
| 49 } |
| 50 |
| 51 if (disposition == CURRENT_TAB) { |
| 52 content::NotificationService::current()->Notify( |
| 53 chrome::NOTIFICATION_INSTANT_COMMITTED, |
| 54 content::Source<TabContents>(instant()->CommitCurrentPreview( |
| 55 INSTANT_COMMIT_PRESSED_ENTER)), |
| 56 content::NotificationService::NoDetails()); |
| 57 return true; |
| 58 } |
| 59 if (disposition == NEW_FOREGROUND_TAB) { |
| 60 TabContents* preview_contents = instant()->ReleasePreviewContents( |
| 61 INSTANT_COMMIT_PRESSED_ENTER, NULL); |
| 62 // HideInstant is invoked after release so that InstantController is not |
| 63 // active when HideInstant asks it for its state. |
| 64 HideInstant(); |
| 65 preview_contents->web_contents()->GetController().PruneAllButActive(); |
| 66 browser_->tab_strip_model()->AddTabContents( |
| 67 preview_contents, |
| 68 -1, |
| 69 instant()->last_transition_type(), |
| 70 TabStripModel::ADD_ACTIVE); |
| 71 instant()->CompleteRelease(preview_contents); |
| 72 content::NotificationService::current()->Notify( |
| 73 chrome::NOTIFICATION_INSTANT_COMMITTED, |
| 74 content::Source<TabContents>(preview_contents), |
| 75 content::NotificationService::NoDetails()); |
| 76 return true; |
| 77 } |
| 78 // The omnibox currently doesn't use other dispositions, so we don't attempt |
| 79 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add |
| 80 // support for the new disposition. |
| 81 NOTREACHED(); |
| 82 return false; |
| 83 } |
| 84 |
| 85 //////////////////////////////////////////////////////////////////////////////// |
| 86 // BrowserInstantController, InstantControllerDelegate implementation: |
| 87 |
| 88 void BrowserInstantController::ShowInstant(TabContents* preview_contents) { |
| 89 browser_->window()->ShowInstant(preview_contents); |
| 90 |
| 91 // TODO(beng): investigate if we can avoid this and instead rely on the |
| 92 // visibility of the WebContentsView |
| 93 chrome::GetActiveWebContents(browser_)->WasHidden(); |
| 94 preview_contents->web_contents()->WasRestored(); |
| 95 } |
| 96 |
| 97 void BrowserInstantController::HideInstant() { |
| 98 browser_->window()->HideInstant(); |
| 99 if (chrome::GetActiveWebContents(browser_)) |
| 100 chrome::GetActiveWebContents(browser_)->WasRestored(); |
| 101 if (instant_->GetPreviewContents()) |
| 102 instant_->GetPreviewContents()->web_contents()->WasHidden(); |
| 103 } |
| 104 |
| 105 void BrowserInstantController::CommitInstant(TabContents* preview_contents) { |
| 106 TabContents* tab_contents = chrome::GetActiveTabContents(browser_); |
| 107 int index = browser_->tab_strip_model()->GetIndexOfTabContents(tab_contents); |
| 108 DCHECK_NE(TabStripModel::kNoTab, index); |
| 109 // TabStripModel takes ownership of preview_contents. |
| 110 browser_->tab_strip_model()->ReplaceTabContentsAt(index, preview_contents); |
| 111 // InstantUnloadHandler takes ownership of tab_contents. |
| 112 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index); |
| 113 |
| 114 GURL url = preview_contents->web_contents()->GetURL(); |
| 115 DCHECK(browser_->profile()->GetExtensionService()); |
| 116 if (browser_->profile()->GetExtensionService()->IsInstalledApp(url)) { |
| 117 AppLauncherHandler::RecordAppLaunchType( |
| 118 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); |
| 119 } |
| 120 } |
| 121 |
| 122 void BrowserInstantController::SetSuggestedText( |
| 123 const string16& text, |
| 124 InstantCompleteBehavior behavior) { |
| 125 if (browser_->window()->GetLocationBar()) |
| 126 browser_->window()->GetLocationBar()->SetSuggestedText(text, behavior); |
| 127 } |
| 128 |
| 129 gfx::Rect BrowserInstantController::GetInstantBounds() { |
| 130 return browser_->window()->GetInstantBounds(); |
| 131 } |
| 132 |
| 133 void BrowserInstantController::InstantPreviewFocused() { |
| 134 // NOTE: This is only invoked on aura. |
| 135 browser_->window()->WebContentsFocused( |
| 136 instant_->GetPreviewContents()->web_contents()); |
| 137 } |
| 138 |
| 139 TabContents* BrowserInstantController::GetInstantHostTabContents() const { |
| 140 return chrome::GetActiveTabContents(browser_); |
| 141 } |
| 142 |
| 143 //////////////////////////////////////////////////////////////////////////////// |
| 144 // BrowserInstantController, content::NotificationObserver implementation: |
| 145 |
| 146 void BrowserInstantController::Observe( |
| 147 int type, |
| 148 const content::NotificationSource& source, |
| 149 const content::NotificationDetails& details) { |
| 150 DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED); |
| 151 const std::string& pref_name = |
| 152 *content::Details<std::string>(details).ptr(); |
| 153 DCHECK(pref_name == prefs::kInstantEnabled); |
| 154 if (browser_shutdown::ShuttingDownWithoutClosingBrowsers() || |
| 155 !InstantController::IsEnabled(browser_->profile())) { |
| 156 if (instant()) { |
| 157 instant()->DestroyPreviewContents(); |
| 158 instant_.reset(); |
| 159 instant_unload_handler_.reset(); |
| 160 } |
| 161 } else { |
| 162 CreateInstantIfNecessary(); |
| 163 } |
| 164 } |
| 165 |
| 166 //////////////////////////////////////////////////////////////////////////////// |
| 167 // BrowserInstantController, TabStripModelObserver implementation: |
| 168 |
| 169 void BrowserInstantController::TabDeactivated(TabContents* contents) { |
| 170 if (instant()) |
| 171 instant()->Hide(); |
| 172 } |
| 173 |
| 174 //////////////////////////////////////////////////////////////////////////////// |
| 175 // BrowserInstantController, private: |
| 176 |
| 177 void BrowserInstantController::CreateInstantIfNecessary() { |
| 178 if (browser_->is_type_tabbed() && |
| 179 InstantController::IsEnabled(browser_->profile()) && |
| 180 !browser_->profile()->IsOffTheRecord()) { |
| 181 instant_.reset(new InstantController(this, InstantController::INSTANT)); |
| 182 instant_unload_handler_.reset(new InstantUnloadHandler(browser_)); |
| 183 } |
| 184 } |
| 185 |
| 186 } // namespace chrome |
OLD | NEW |