| // Copyright (c) 2012 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/browser_instant_controller.h" |
| |
| #include "chrome/browser/browser_shutdown.h" |
| #include "chrome/browser/extensions/extension_service.h" |
| #include "chrome/browser/instant/instant_controller.h" |
| #include "chrome/browser/instant/instant_unload_handler.h" |
| #include "chrome/browser/prefs/pref_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/browser/ui/omnibox/location_bar.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" |
| #include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/pref_names.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/web_contents.h" |
| |
| namespace chrome { |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserInstantController, public: |
| |
| BrowserInstantController::BrowserInstantController(Browser* browser) |
| : browser_(browser) { |
| profile_pref_registrar_.Init(browser_->profile()->GetPrefs()); |
| profile_pref_registrar_.Add(prefs::kInstantEnabled, this); |
| ResetInstant(); |
| browser_->tab_strip_model()->AddObserver(this); |
| } |
| |
| BrowserInstantController::~BrowserInstantController() { |
| browser_->tab_strip_model()->RemoveObserver(this); |
| } |
| |
| bool BrowserInstantController::OpenInstant(WindowOpenDisposition disposition) { |
| // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't attempt |
| // to use the Instant preview. |
| if (!instant() || !instant_->IsCurrent() || disposition == NEW_BACKGROUND_TAB) |
| return false; |
| |
| if (disposition == CURRENT_TAB) { |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_INSTANT_COMMITTED, |
| content::Source<TabContents>(instant_->CommitCurrentPreview( |
| INSTANT_COMMIT_PRESSED_ENTER)), |
| content::NotificationService::NoDetails()); |
| return true; |
| } |
| |
| if (disposition == NEW_FOREGROUND_TAB) { |
| TabContents* preview = instant_->ReleasePreviewContents( |
| INSTANT_COMMIT_PRESSED_ENTER); |
| preview->web_contents()->GetController().PruneAllButActive(); |
| browser_->tab_strip_model()->AddTabContents(preview, -1, |
| instant_->last_transition_type(), TabStripModel::ADD_ACTIVE); |
| content::NotificationService::current()->Notify( |
| chrome::NOTIFICATION_INSTANT_COMMITTED, |
| content::Source<TabContents>(preview), |
| content::NotificationService::NoDetails()); |
| return true; |
| } |
| |
| // The omnibox currently doesn't use other dispositions, so we don't attempt |
| // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add |
| // support for the new disposition. |
| NOTREACHED(); |
| return false; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserInstantController, InstantControllerDelegate implementation: |
| |
| void BrowserInstantController::ShowInstant(int height, InstantSizeUnits units) { |
| browser_->window()->ShowInstant(instant_->GetPreviewContents(), |
| height, units); |
| } |
| |
| void BrowserInstantController::HideInstant() { |
| browser_->window()->HideInstant(); |
| } |
| |
| void BrowserInstantController::CommitInstant(TabContents* preview) { |
| TabContents* active_tab = chrome::GetActiveTabContents(browser_); |
| int index = browser_->tab_strip_model()->GetIndexOfTabContents(active_tab); |
| DCHECK_NE(TabStripModel::kNoTab, index); |
| // TabStripModel takes ownership of |preview|. |
| browser_->tab_strip_model()->ReplaceTabContentsAt(index, preview); |
| // InstantUnloadHandler takes ownership of |active_tab|. |
| instant_unload_handler_->RunUnloadListenersOrDestroy(active_tab, index); |
| |
| GURL url = preview->web_contents()->GetURL(); |
| DCHECK(browser_->profile()->GetExtensionService()); |
| if (browser_->profile()->GetExtensionService()->IsInstalledApp(url)) { |
| AppLauncherHandler::RecordAppLaunchType( |
| extension_misc::APP_LAUNCH_OMNIBOX_INSTANT); |
| } |
| } |
| |
| void BrowserInstantController::SetSuggestedText( |
| const string16& text, |
| InstantCompleteBehavior behavior) { |
| if (browser_->window()->GetLocationBar()) |
| browser_->window()->GetLocationBar()->SetSuggestedText(text, behavior); |
| } |
| |
| gfx::Rect BrowserInstantController::GetInstantBounds() { |
| return browser_->window()->GetInstantBounds(); |
| } |
| |
| void BrowserInstantController::InstantPreviewFocused() { |
| // NOTE: This is only invoked on aura. |
| browser_->window()->WebContentsFocused( |
| instant_->GetPreviewContents()->web_contents()); |
| } |
| |
| TabContents* BrowserInstantController::GetActiveTabContents() const { |
| return chrome::GetActiveTabContents(browser_); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserInstantController, content::NotificationObserver implementation: |
| |
| void BrowserInstantController::Observe( |
| int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| DCHECK_EQ(chrome::NOTIFICATION_PREF_CHANGED, type); |
| DCHECK_EQ(std::string(prefs::kInstantEnabled), |
| *content::Details<std::string>(details).ptr()); |
| ResetInstant(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserInstantController, TabStripModelObserver implementation: |
| |
| void BrowserInstantController::TabDeactivated(TabContents* contents) { |
| if (instant()) |
| instant_->Hide(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // BrowserInstantController, private: |
| |
| void BrowserInstantController::ResetInstant() { |
| instant_.reset( |
| !browser_shutdown::ShuttingDownWithoutClosingBrowsers() && |
| browser_->is_type_tabbed() ? |
| InstantController::CreateInstant(browser_->profile(), this) : NULL); |
| instant_unload_handler_.reset(instant() ? |
| new InstantUnloadHandler(browser_) : NULL); |
| } |
| |
| } // namespace chrome |