Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Unified Diff: chrome/browser/ui/browser_command_controller.cc

Issue 10677009: Move command handling and updating off Browser and onto a helper object. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/browser_command_controller.h ('k') | chrome/browser/ui/browser_commands.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/browser_command_controller.cc
===================================================================
--- chrome/browser/ui/browser_command_controller.cc (revision 144176)
+++ chrome/browser/ui/browser_command_controller.cc (working copy)
@@ -2,240 +2,53 @@
// 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.h"
+#include "chrome/browser/ui/browser_command_controller.h"
-#if defined(OS_WIN)
-#include <windows.h>
-#include <shellapi.h>
-#endif // OS_WIN
-
-#include <algorithm>
-#include <string>
-
-#include "base/base_paths.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/path_service.h"
-#include "base/string_number_conversions.h"
-#include "base/string_util.h"
-#include "base/stringprintf.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/time.h"
-#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/autofill/personal_data_manager_factory.h"
-#include "chrome/browser/background/background_contents_service.h"
-#include "chrome/browser/background/background_contents_service_factory.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_shutdown.h"
-#include "chrome/browser/character_encoding.h"
-#include "chrome/browser/chrome_page_zoom.h"
-#include "chrome/browser/content_settings/host_content_settings_map.h"
-#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
-#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
-#include "chrome/browser/debugger/devtools_toggle_action.h"
-#include "chrome/browser/debugger/devtools_window.h"
-#include "chrome/browser/download/download_crx_util.h"
-#include "chrome/browser/download/download_item_model.h"
-#include "chrome/browser/download/download_service.h"
-#include "chrome/browser/download/download_service_factory.h"
-#include "chrome/browser/download/download_shelf.h"
-#include "chrome/browser/download/download_started_animation.h"
-#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/extensions/browser_extension_window_controller.h"
-#include "chrome/browser/extensions/crx_installer.h"
-#include "chrome/browser/extensions/default_apps_trial.h"
-#include "chrome/browser/extensions/extension_prefs.h"
+#include "chrome/browser/defaults.h"
#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_tab_helper.h"
-#include "chrome/browser/favicon/favicon_tab_helper.h"
-#include "chrome/browser/file_select_helper.h"
-#include "chrome/browser/first_run/first_run.h"
-#include "chrome/browser/google/google_url_tracker.h"
-#include "chrome/browser/infobars/infobar_tab_helper.h"
-#include "chrome/browser/instant/instant_controller.h"
-#include "chrome/browser/instant/instant_unload_handler.h"
-#include "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
-#include "chrome/browser/intents/web_intents_util.h"
-#include "chrome/browser/lifetime/application_lifetime.h"
-#include "chrome/browser/media/media_stream_devices_controller.h"
-#include "chrome/browser/net/url_fixer_upper.h"
-#include "chrome/browser/notifications/notification_ui_manager.h"
-#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
#include "chrome/browser/printing/print_preview_tab_controller.h"
#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_destroyer.h"
#include "chrome/browser/profiles/profile_manager.h"
-#include "chrome/browser/profiles/profile_metrics.h"
-#include "chrome/browser/repost_form_warning_controller.h"
-#include "chrome/browser/sessions/restore_tab_helper.h"
-#include "chrome/browser/sessions/session_service.h"
-#include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/browser/sessions/session_types.h"
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/sessions/tab_restore_service_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/browser/sync/sync_ui_util.h"
-#include "chrome/browser/tab_contents/background_contents.h"
-#include "chrome/browser/tab_contents/retargeting_details.h"
-#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/themes/theme_service.h"
-#include "chrome/browser/themes/theme_service_factory.h"
-#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h"
-#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
+#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
-#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
-#include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
-#include "chrome/browser/ui/browser_toolbar_model_delegate.h"
-#include "chrome/browser/ui/browser_ui_prefs.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/constrained_window_tab_helper.h"
-#include "chrome/browser/ui/extensions/shell_window.h"
-#include "chrome/browser/ui/find_bar/find_bar.h"
-#include "chrome/browser/ui/find_bar/find_bar_controller.h"
-#include "chrome/browser/ui/find_bar/find_tab_helper.h"
-#include "chrome/browser/ui/fullscreen_controller.h"
-#include "chrome/browser/ui/global_error.h"
-#include "chrome/browser/ui/global_error_service.h"
-#include "chrome/browser/ui/global_error_service_factory.h"
-#include "chrome/browser/ui/hung_plugin_tab_helper.h"
-#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
-#include "chrome/browser/ui/media_stream_infobar_delegate.h"
-#include "chrome/browser/ui/omnibox/location_bar.h"
-#include "chrome/browser/ui/panels/panel.h"
-#include "chrome/browser/ui/panels/panel_manager.h"
-#include "chrome/browser/ui/search/search.h"
-#include "chrome/browser/ui/search/search_delegate.h"
-#include "chrome/browser/ui/search/search_model.h"
-#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
-#include "chrome/browser/ui/singleton_tabs.h"
-#include "chrome/browser/ui/status_bubble.h"
-#include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
-#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
-#include "chrome/browser/ui/tabs/dock_info.h"
-#include "chrome/browser/ui/tabs/tab_menu_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
-#include "chrome/browser/ui/web_applications/web_app_ui.h"
-#include "chrome/browser/ui/webui/feedback_ui.h"
-#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
-#include "chrome/browser/ui/window_sizer.h"
-#include "chrome/browser/upgrade_detector.h"
-#include "chrome/browser/web_applications/web_app.h"
-#include "chrome/common/chrome_constants.h"
+#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h"
#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/custom_handlers/protocol_handler.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/profiling.h"
-#include "chrome/common/url_constants.h"
-#include "chrome/common/web_apps.h"
-#include "content/public/browser/color_chooser.h"
-#include "content/public/browser/devtools_manager.h"
-#include "content/public/browser/download_item.h"
-#include "content/public/browser/download_manager.h"
-#include "content/public/browser/interstitial_page.h"
-#include "content/public/browser/invalidate_type.h"
+#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/plugin_service.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/site_instance.h"
-#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/notification_source.h"
#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "content/public/browser/web_intents_dispatcher.h"
#include "content/public/common/content_restriction.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/page_zoom.h"
-#include "content/public/common/renderer_preferences.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/locale_settings.h"
-#include "grit/theme_resources_standard.h"
-#include "net/base/net_util.h"
-#include "net/base/registry_controlled_domain.h"
-#include "net/cookies/cookie_monster.h"
-#include "net/url_request/url_request_context.h"
-#include "ui/base/animation/animation.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/point.h"
-#include "webkit/glue/web_intent_data.h"
-#include "webkit/glue/web_intent_service_data.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/glue/window_open_disposition.h"
-#include "webkit/plugins/webplugininfo.h"
+#include "content/public/common/url_constants.h"
+#include "ui/base/keycodes/keyboard_codes.h"
#if defined(OS_WIN)
#include "base/win/metro.h"
-#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
-#include "chrome/browser/shell_integration.h"
-#include "chrome/browser/ssl/ssl_error_info.h"
-#include "chrome/browser/task_manager/task_manager.h"
-#include "chrome/browser/ui/view_ids.h"
-#include "ui/base/win/shell.h"
-#endif // OS_WIN
-
-#if defined(OS_CHROMEOS)
-#include "chrome/browser/chromeos/gdata/gdata_util.h"
#endif
-#if defined(USE_ASH)
-#include "ash/ash_switches.h"
-#endif
-
-using base::TimeDelta;
-using content::NativeWebKeyboardEvent;
-using content::NavigationController;
+using content::WebContents;
using content::NavigationEntry;
-using content::OpenURLParams;
-using content::PluginService;
-using content::Referrer;
-using content::SiteInstance;
-using content::UserMetricsAction;
+using content::NavigationController;
using content::WebContents;
-using extensions::Extension;
-using ui::WebDialogDelegate;
-///////////////////////////////////////////////////////////////////////////////
-
namespace {
-// The URL to be loaded to display the "Report a broken page" form.
-const char kBrokenPageUrl[] =
- "https://www.google.com/support/chrome/bin/request.py?contact_type="
- "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
-
-// The URL for the privacy dashboard.
-const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
-
-// How long we wait before updating the browser chrome while loading a page.
-const int kUIUpdateCoalescingTimeMS = 200;
-
// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
bool HasInternalURL(const NavigationEntry* entry) {
if (!entry)
@@ -254,120 +67,20 @@
return false;
}
-bool AllowPanels(const std::string& app_name) {
- return PanelManager::ShouldUsePanels(
- web_app::GetExtensionIdFromApplicationName(app_name));
-}
-
} // namespace
-////////////////////////////////////////////////////////////////////////////////
-// Browser, CreateParams:
+namespace chrome {
-Browser::CreateParams::CreateParams()
- : type(TYPE_TABBED),
- profile(NULL),
- initial_show_state(ui::SHOW_STATE_DEFAULT),
- is_session_restore(false) {
-}
-
-Browser::CreateParams::CreateParams(Type type, Profile* profile)
- : type(type),
- profile(profile),
- app_type(APP_TYPE_HOST),
- initial_show_state(ui::SHOW_STATE_DEFAULT),
- is_session_restore(false) {
-}
-
-// static
-Browser::CreateParams Browser::CreateParams::CreateForApp(
- Type type,
- const std::string& app_name,
- const gfx::Rect& window_bounds,
- Profile* profile) {
- DCHECK(type != TYPE_TABBED);
- DCHECK(!app_name.empty());
-
- if (type == TYPE_PANEL && !AllowPanels(app_name))
- type = TYPE_POPUP;
-
- CreateParams params(type, profile);
- params.app_name = app_name;
- params.app_type = APP_TYPE_CHILD;
- params.initial_bounds = window_bounds;
-
- return params;
-}
-
-// static
-Browser::CreateParams Browser::CreateParams::CreateForDevTools(
- Profile* profile) {
- CreateParams params(TYPE_POPUP, profile);
- params.app_name = DevToolsWindow::kDevToolsApp;
- return params;
-}
-
///////////////////////////////////////////////////////////////////////////////
-// Browser, Constructors, Creation, Showing:
+// BrowserCommandController, public:
-Browser::Browser(Type type, Profile* profile)
- : type_(type),
- profile_(profile),
- window_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- tab_strip_model_(new TabStripModel(this, profile))),
- command_updater_(this),
- app_type_(APP_TYPE_HOST),
- chrome_updater_factory_(this),
- is_attempting_to_close_browser_(false),
- cancel_download_confirmation_state_(NOT_PROMPTED),
- initial_show_state_(ui::SHOW_STATE_DEFAULT),
- is_session_restore_(false),
- weak_factory_(this),
+BrowserCommandController::BrowserCommandController(Browser* browser)
+ : browser_(browser),
+ ALLOW_THIS_IN_INITIALIZER_LIST(command_updater_(this)),
block_command_execution_(false),
last_blocked_command_id_(-1),
- last_blocked_command_disposition_(CURRENT_TAB),
- pending_web_app_action_(NONE),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- content_setting_bubble_model_delegate_(
- new BrowserContentSettingBubbleModelDelegate(this))),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- toolbar_model_delegate_(
- new BrowserToolbarModelDelegate(this))),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- tab_restore_service_delegate_(
- new BrowserTabRestoreServiceDelegate(this))),
- ALLOW_THIS_IN_INITIALIZER_LIST(
- synced_window_delegate_(
- new BrowserSyncedWindowDelegate(this))),
- bookmark_bar_state_(BookmarkBar::HIDDEN),
- window_has_shown_(false) {
- tab_strip_model_->AddObserver(this);
-
- toolbar_model_.reset(new ToolbarModel(toolbar_model_delegate_.get()));
- search_model_.reset(new chrome::search::SearchModel(NULL));
- search_delegate_.reset(
- new chrome::search::SearchDelegate(search_model_.get()));
-
- registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
- content::NotificationService::AllSources());
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
- content::Source<Profile>(profile_->GetOriginalProfile()));
- registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
- content::NotificationService::AllSources());
-#if defined(ENABLE_THEMES)
- registrar_.Add(
- this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
- content::Source<ThemeService>(
- ThemeServiceFactory::GetForProfile(profile_)));
-#endif
- registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
- content::NotificationService::AllSources());
-
+ last_blocked_command_disposition_(CURRENT_TAB) {
+ browser_->tab_strip_model()->AddObserver(this);
PrefService* local_state = g_browser_process->local_state();
if (local_state) {
local_pref_registrar_.Init(local_state);
@@ -376,841 +89,47 @@
local_pref_registrar_.Add(prefs::kInManagedMode, this);
}
- profile_pref_registrar_.Init(profile_->GetPrefs());
+ profile_pref_registrar_.Init(profile()->GetPrefs());
profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this);
- profile_pref_registrar_.Add(prefs::kHomePage, this);
- profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
InitCommandState();
- BrowserList::AddBrowser(this);
- // NOTE: These prefs all need to be explicitly destroyed in the destructor
- // or you'll get a nasty surprise when you run the incognito tests.
- encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
- profile_->GetPrefs(), NULL);
-
- tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
- if (tab_restore_service_) {
- tab_restore_service_->AddObserver(this);
- TabRestoreServiceChanged(tab_restore_service_);
+ TabRestoreService* tab_restore_service =
+ TabRestoreServiceFactory::GetForProfile(profile());
+ if (tab_restore_service) {
+ tab_restore_service->AddObserver(this);
+ TabRestoreServiceChanged(tab_restore_service);
}
ProfileSyncService* service =
- ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
+ ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
if (service)
service->AddObserver(this);
-
- CreateInstantIfNecessary();
-
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
-
- FilePath profile_path = profile->GetPath();
- ProfileMetrics::LogProfileLaunch(profile_path);
}
-Browser::~Browser() {
+BrowserCommandController::~BrowserCommandController() {
ProfileSyncService* service =
- ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
+ ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
if (service)
service->RemoveObserver(this);
- // The tab strip should not have any tabs at this point.
- if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers())
- DCHECK(tab_strip_model_->empty());
- tab_strip_model_->RemoveObserver(this);
-
- BrowserList::RemoveBrowser(this);
-
- SessionService* session_service =
- SessionServiceFactory::GetForProfile(profile_);
- if (session_service)
- session_service->WindowClosed(session_id_);
-
TabRestoreService* tab_restore_service =
TabRestoreServiceFactory::GetForProfile(profile());
if (tab_restore_service)
- tab_restore_service->BrowserClosed(tab_restore_service_delegate());
-
-#if !defined(OS_MACOSX)
- if (!browser::GetBrowserCount(profile_)) {
- // We're the last browser window with this profile. We need to nuke the
- // TabRestoreService, which will start the shutdown of the
- // NavigationControllers and allow for proper shutdown. If we don't do this
- // chrome won't shutdown cleanly, and may end up crashing when some
- // thread tries to use the IO thread (or another thread) that is no longer
- // valid.
- // This isn't a valid assumption for Mac OS, as it stays running after
- // the last browser has closed. The Mac equivalent is in its app
- // controller.
- TabRestoreServiceFactory::ResetForProfile(profile_);
- }
-#endif
-
+ tab_restore_service->RemoveObserver(this);
profile_pref_registrar_.RemoveAll();
local_pref_registrar_.RemoveAll();
-
- encoding_auto_detect_.Destroy();
-
- if (profile_->IsOffTheRecord() &&
- !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
- // An incognito profile is no longer needed, this indirectly frees
- // its cache and cookies once it gets destroyed at the appropriate time.
- ProfileDestroyer::DestroyProfileWhenAppropriate(profile_);
- }
-
- // There may be pending file dialogs, we need to tell them that we've gone
- // away so they don't try and call back to us.
- if (select_file_dialog_.get())
- select_file_dialog_->ListenerDestroyed();
-
- TabRestoreServiceDestroyed(tab_restore_service_);
+ browser_->tab_strip_model()->RemoveObserver(this);
}
-// static
-Browser* Browser::Create(Profile* profile) {
- Browser* browser = new Browser(TYPE_TABBED, profile);
- browser->InitBrowserWindow();
- return browser;
-}
-
-// static
-Browser* Browser::CreateWithParams(const CreateParams& params) {
- if (!params.app_name.empty())
- chrome::RegisterAppPrefs(params.app_name, params.profile);
-
- Browser* browser = new Browser(params.type, params.profile);
- browser->app_name_ = params.app_name;
- browser->app_type_ = params.app_type;
- browser->set_override_bounds(params.initial_bounds);
- browser->set_initial_show_state(params.initial_show_state);
- browser->set_is_session_restore(params.is_session_restore);
-
- browser->InitBrowserWindow();
- return browser;
-}
-
-void Browser::InitBrowserWindow() {
- DCHECK(!window_);
-
- window_ = CreateBrowserWindow();
- fullscreen_controller_ = new FullscreenController(window_, profile_, this);
-
-#if defined(OS_WIN) && !defined(USE_AURA)
- // Set the app user model id for this application to that of the application
- // name. See http://crbug.com/7028.
- ui::win::SetAppIdForWindow(
- is_app() && !is_type_panel() ?
- ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(app_name_),
- profile_->GetPath()) :
- ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()),
- window()->GetNativeWindow());
-
- if (is_type_panel()) {
- ui::win::SetAppIconForWindow(ShellIntegration::GetChromiumIconPath(),
- window()->GetNativeWindow());
- }
-#endif
-
- // Create the extension window controller before sending notifications.
- extension_window_controller_.reset(
- new BrowserExtensionWindowController(this));
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_BROWSER_WINDOW_READY,
- content::Source<Browser>(this),
- content::NotificationService::NoDetails());
-
- PrefService* local_state = g_browser_process->local_state();
- if (local_state && local_state->FindPreference(
- prefs::kAutofillPersonalDataManagerFirstRun) &&
- local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
- // Notify PDM that this is a first run.
-#if defined(OS_WIN)
- ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_));
-#endif // defined(OS_WIN)
- // Reset the preference so we don't call it again for subsequent windows.
- local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
- }
-}
-
-void Browser::SetWindowForTesting(BrowserWindow* window) {
- DCHECK(!window_);
- window_ = window;
- fullscreen_controller_ = new FullscreenController(window_, profile_, this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Getters & Setters
-
-FindBarController* Browser::GetFindBarController() {
- if (!find_bar_controller_.get()) {
- FindBar* find_bar = window_->CreateFindBar();
- find_bar_controller_.reset(new FindBarController(find_bar));
- find_bar->SetFindBarController(find_bar_controller_.get());
- find_bar_controller_->ChangeTabContents(GetActiveTabContents());
- find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
- }
- return find_bar_controller_.get();
-}
-
-bool Browser::HasFindBarController() const {
- return find_bar_controller_.get() != NULL;
-}
-
-bool Browser::is_app() const {
- return !app_name_.empty();
-}
-
-bool Browser::is_devtools() const {
- return app_name_ == DevToolsWindow::kDevToolsApp;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, State Storage and Retrieval for UI:
-
-SkBitmap Browser::GetCurrentPageIcon() const {
- TabContents* contents = GetActiveTabContents();
- // |contents| can be NULL since GetCurrentPageIcon() is called by the window
- // during the window's creation (before tabs have been added).
- return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
-}
-
-string16 Browser::GetWindowTitleForCurrentTab() const {
- WebContents* contents = GetActiveWebContents();
- string16 title;
-
- // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
- // window during the window's creation (before tabs have been added).
- if (contents) {
- title = contents->GetTitle();
- FormatTitleForDisplay(&title);
- }
- if (title.empty())
- title = CoreTabHelper::GetDefaultTitle();
-
-#if defined(OS_MACOSX) || defined(USE_ASH)
- // On Mac or Ash, we don't want to suffix the page title with
- // the application name.
- return title;
-#else
- int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
- // Don't append the app name to window titles on app frames and app popups
- if (is_app())
- string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
- return l10n_util::GetStringFUTF16(string_id, title);
-#endif
-}
-
-// static
-void Browser::FormatTitleForDisplay(string16* title) {
- size_t current_index = 0;
- size_t match_index;
- while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
- title->replace(match_index, 1, string16());
- current_index = match_index;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, OnBeforeUnload handling:
-
-bool Browser::ShouldCloseWindow() {
- if (!CanCloseWithInProgressDownloads())
- return false;
-
- if (HasCompletedUnloadProcessing())
- return true;
-
- is_attempting_to_close_browser_ = true;
-
- if (!TabsNeedBeforeUnloadFired())
- return true;
-
- ProcessPendingTabs();
- return false;
-}
-
-void Browser::OnWindowClosing() {
- if (!ShouldCloseWindow())
- return;
-
- bool exiting = false;
-
- // Application should shutdown on last window close if the user is explicitly
- // trying to quit, or if there is nothing keeping the browser alive (such as
- // AppController on the Mac, or BackgroundContentsService for background
- // pages).
- bool should_quit_if_last_browser =
- browser_shutdown::IsTryingToQuit() || !browser::WillKeepAlive();
-
- if (should_quit_if_last_browser && BrowserList::size() == 1) {
- browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
- exiting = true;
- }
-
- // Don't use GetForProfileIfExisting here, we want to force creation of the
- // session service so that user can restore what was open.
- SessionService* session_service =
- SessionServiceFactory::GetForProfile(profile());
- if (session_service)
- session_service->WindowClosing(session_id());
-
- TabRestoreService* tab_restore_service =
- TabRestoreServiceFactory::GetForProfile(profile());
-
-#if defined(USE_AURA)
- if (tab_restore_service && is_app())
- tab_restore_service->BrowserClosing(tab_restore_service_delegate());
-#endif
-
- if (tab_restore_service && is_type_tabbed() && tab_count())
- tab_restore_service->BrowserClosing(tab_restore_service_delegate());
-
- // TODO(sky): convert session/tab restore to use notification.
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_BROWSER_CLOSING,
- content::Source<Browser>(this),
- content::Details<bool>(&exiting));
-
- CloseAllTabs();
-}
-
-void Browser::OnWindowActivated() {
- // On some platforms we want to automatically reload tabs that are
- // killed when the user selects them.
- WebContents* contents = GetActiveWebContents();
- if (contents && contents->GetCrashedStatus() ==
- base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kReloadKilledTabs)) {
- chrome::Reload(this, CURRENT_TAB);
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// In-progress download termination handling:
-
-void Browser::InProgressDownloadResponse(bool cancel_downloads) {
- if (cancel_downloads) {
- cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
- chrome::CloseWindow(this);
- return;
- }
-
- // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
- // close again we'll show the warning again.
- cancel_download_confirmation_state_ = NOT_PROMPTED;
-
- // Show the download page so the user can figure-out what downloads are still
- // in-progress.
- chrome::ShowDownloads(this);
-}
-
-Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
- int* num_downloads_blocking) const {
- DCHECK(num_downloads_blocking);
- *num_downloads_blocking = 0;
-
- if (is_attempting_to_close_browser_)
- return DOWNLOAD_CLOSE_OK;
-
- // If we're not running a full browser process with a profile manager
- // (testing), it's ok to close the browser.
- if (!g_browser_process->profile_manager())
- return DOWNLOAD_CLOSE_OK;
-
- int total_download_count = DownloadService::DownloadCountAllProfiles();
- if (total_download_count == 0)
- return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
-
- // Figure out how many windows are open total, and associated with this
- // profile, that are relevant for the ok-to-close decision.
- int profile_window_count = 0;
- int total_window_count = 0;
- for (BrowserList::const_iterator iter = BrowserList::begin();
- iter != BrowserList::end(); ++iter) {
- // Don't count this browser window or any other in the process of closing.
- Browser* const browser = *iter;
- // Check is_attempting_to_close_browser_ as window closing may be
- // delayed, and windows that are in the process of closing don't
- // count against our totals.
- if (browser == this || browser->is_attempting_to_close_browser_)
- continue;
-
- if ((*iter)->profile() == profile())
- profile_window_count++;
- total_window_count++;
- }
-
- // If there aren't any other windows, we're at browser shutdown,
- // which would cancel all current downloads.
- if (total_window_count == 0) {
- *num_downloads_blocking = total_download_count;
- return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
- }
-
- // If there aren't any other windows on our profile, and we're an incognito
- // profile, and there are downloads associated with that profile,
- // those downloads would be cancelled by our window (-> profile) close.
- DownloadService* download_service =
- DownloadServiceFactory::GetForProfile(profile());
- if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
- profile()->IsOffTheRecord()) {
- *num_downloads_blocking = download_service->DownloadCount();
- return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
- }
-
- // Those are the only conditions under which we will block shutdown.
- return DOWNLOAD_CLOSE_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Browser, TabStripModel pass-thrus:
-
-int Browser::tab_count() const {
- return tab_strip_model_->count();
-}
-
-int Browser::active_index() const {
- return tab_strip_model_->active_index();
-}
-
-int Browser::GetIndexOfController(
- const NavigationController* controller) const {
- return tab_strip_model_->GetIndexOfController(controller);
-}
-
-TabContents* Browser::GetActiveTabContents() const {
- return tab_strip_model_->GetActiveTabContents();
-}
-
-WebContents* Browser::GetActiveWebContents() const {
- TabContents* tab_contents = GetActiveTabContents();
- return tab_contents ? tab_contents->web_contents() : NULL;
-}
-
-TabContents* Browser::GetTabContentsAt(int index) const {
- return tab_strip_model_->GetTabContentsAt(index);
-}
-
-WebContents* Browser::GetWebContentsAt(int index) const {
- TabContents* tab_contents = GetTabContentsAt(index);
- if (tab_contents)
- return tab_contents->web_contents();
- return NULL;
-}
-
-void Browser::ActivateTabAt(int index, bool user_gesture) {
- tab_strip_model_->ActivateTabAt(index, user_gesture);
-}
-
-bool Browser::IsTabPinned(int index) const {
- return tab_strip_model_->IsTabPinned(index);
-}
-
-bool Browser::IsTabDiscarded(int index) const {
- return tab_strip_model_->IsTabDiscarded(index);
-}
-
-void Browser::CloseAllTabs() {
- tab_strip_model_->CloseAllTabs();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Browser, Tab adding/showing functions:
-
-bool Browser::IsTabStripEditable() const {
- return window()->IsTabStripEditable();
-}
-
-int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
- return (tab_strip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ?
- tab_count() : relative_index;
-}
-
-TabContents* Browser::AddSelectedTabWithURL(
- const GURL& url,
- content::PageTransition transition) {
- browser::NavigateParams params(this, url, transition);
- params.disposition = NEW_FOREGROUND_TAB;
- browser::Navigate(&params);
- return params.target_contents;
-}
-
-WebContents* Browser::AddTab(TabContents* tab_contents,
- content::PageTransition type) {
- tab_strip_model_->AddTabContents(tab_contents, -1, type,
- TabStripModel::ADD_ACTIVE);
- return tab_contents->web_contents();
-}
-
-WebContents* Browser::AddRestoredTab(
- const std::vector<TabNavigation>& navigations,
- int tab_index,
- int selected_navigation,
- const std::string& extension_app_id,
- bool select,
- bool pin,
- bool from_last_session,
- content::SessionStorageNamespace* session_storage_namespace) {
- GURL restore_url = navigations.at(selected_navigation).virtual_url();
- TabContents* tab_contents = TabContentsFactory(
- profile(),
- tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
- MSG_ROUTING_NONE,
- GetActiveWebContents(),
- session_storage_namespace);
- WebContents* new_tab = tab_contents->web_contents();
- tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id);
- std::vector<NavigationEntry*> entries;
- TabNavigation::CreateNavigationEntriesFromTabNavigations(
- profile_, navigations, &entries);
- new_tab->GetController().Restore(
- selected_navigation, from_last_session, &entries);
- DCHECK_EQ(0u, entries.size());
-
- int add_types = select ? TabStripModel::ADD_ACTIVE :
- TabStripModel::ADD_NONE;
- if (pin) {
- int first_mini_tab_idx = tab_strip_model_->IndexOfFirstNonMiniTab();
- tab_index = std::min(tab_index, first_mini_tab_idx);
- add_types |= TabStripModel::ADD_PINNED;
- }
- tab_strip_model_->InsertTabContentsAt(tab_index, tab_contents, add_types);
- if (select) {
- window_->Activate();
- } else {
- // We set the size of the view here, before WebKit does its initial
- // layout. If we don't, the initial layout of background tabs will be
- // performed with a view width of 0, which may cause script outputs and
- // anchor link location calculations to be incorrect even after a new
- // layout with proper view dimensions. TabStripModel::AddTabContents()
- // contains similar logic.
- new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size());
- new_tab->WasHidden();
- }
- SessionService* session_service =
- SessionServiceFactory::GetForProfileIfExisting(profile_);
- if (session_service)
- session_service->TabRestored(tab_contents, pin);
- return new_tab;
-}
-
-void Browser::AddWebContents(WebContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
-}
-
-void Browser::CloseTabContents(WebContents* contents) {
- CloseContents(contents);
-}
-
-void Browser::ReplaceRestoredTab(
- const std::vector<TabNavigation>& navigations,
- int selected_navigation,
- bool from_last_session,
- const std::string& extension_app_id,
- content::SessionStorageNamespace* session_storage_namespace) {
- GURL restore_url = navigations.at(selected_navigation).virtual_url();
- TabContents* tab_contents = TabContentsFactory(
- profile(),
- tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
- MSG_ROUTING_NONE,
- GetActiveWebContents(),
- session_storage_namespace);
- tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id);
- WebContents* replacement = tab_contents->web_contents();
- std::vector<NavigationEntry*> entries;
- TabNavigation::CreateNavigationEntriesFromTabNavigations(
- profile_, navigations, &entries);
- replacement->GetController().Restore(
- selected_navigation, from_last_session, &entries);
- DCHECK_EQ(0u, entries.size());
-
- tab_strip_model_->ReplaceNavigationControllerAt(active_index(), tab_contents);
-}
-
-void Browser::WindowFullscreenStateChanged() {
- fullscreen_controller_->WindowFullscreenStateChanged();
- FullScreenMode fullscreen_mode = FULLSCREEN_DISABLED;
- if (window_->IsFullscreen()) {
-#if defined(OS_WIN)
- fullscreen_mode = window_->IsInMetroSnapMode() ? FULLSCREEN_METRO_SNAP :
- FULLSCREEN_NORMAL;
-#else
- fullscreen_mode = FULLSCREEN_NORMAL;
-#endif
- }
- UpdateCommandsForFullscreenMode(fullscreen_mode);
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, Assorted browser commands:
-
-void Browser::ToggleFullscreenMode() {
- fullscreen_controller_->ToggleFullscreenMode();
-}
-
-void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
- fullscreen_controller_->ToggleFullscreenModeWithExtension(extension_url);
-}
-
-#if defined(OS_MACOSX)
-void Browser::TogglePresentationMode() {
- fullscreen_controller_->TogglePresentationMode();
-}
-#endif
-
-bool Browser::SupportsWindowFeature(WindowFeature feature) const {
- return SupportsWindowFeatureImpl(feature, true);
-}
-
-bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
- return SupportsWindowFeatureImpl(feature, false);
-}
-
-void Browser::ToggleEncodingAutoDetect() {
- content::RecordAction(UserMetricsAction("AutoDetectChange"));
- encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
- // If "auto detect" is turned on, then any current override encoding
- // is cleared. This also implicitly performs a reload.
- // OTOH, if "auto detect" is turned off, we don't change the currently
- // active encoding.
- if (encoding_auto_detect_.GetValue()) {
- WebContents* contents = GetActiveWebContents();
- if (contents)
- contents->ResetOverrideEncoding();
- }
-}
-
-void Browser::OverrideEncoding(int encoding_id) {
- content::RecordAction(UserMetricsAction("OverrideEncoding"));
- const std::string selected_encoding =
- CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
- WebContents* contents = GetActiveWebContents();
- if (!selected_encoding.empty() && contents)
- contents->SetOverrideEncoding(selected_encoding);
- // Update the list of recently selected encodings.
- std::string new_selected_encoding_list;
- if (CharacterEncoding::UpdateRecentlySelectedEncoding(
- profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
- encoding_id,
- &new_selected_encoding_list)) {
- profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
- new_selected_encoding_list);
- }
-}
-
-void Browser::OpenFile() {
- content::RecordAction(UserMetricsAction("OpenFile"));
- if (!select_file_dialog_.get())
- select_file_dialog_ = SelectFileDialog::Create(this);
-
- const FilePath directory = profile_->last_selected_directory();
-
- // TODO(beng): figure out how to juggle this.
- gfx::NativeWindow parent_window = window_->GetNativeWindow();
- select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
- string16(), directory,
- NULL, 0, FILE_PATH_LITERAL(""),
- GetActiveWebContents(),
- parent_window, NULL);
-}
-
-void Browser::OpenCreateShortcutsDialog() {
- content::RecordAction(UserMetricsAction("CreateShortcut"));
-#if !defined(OS_MACOSX)
- TabContents* current_tab = GetActiveTabContents();
- DCHECK(current_tab &&
- web_app::IsValidUrl(current_tab->web_contents()->GetURL())) <<
- "Menu item should be disabled.";
-
- NavigationEntry* entry =
- current_tab->web_contents()->GetController().GetLastCommittedEntry();
- if (!entry)
- return;
-
- // RVH's GetApplicationInfo should not be called before it returns.
- DCHECK(pending_web_app_action_ == NONE);
- pending_web_app_action_ = CREATE_SHORTCUT;
-
- // Start fetching web app info for CreateApplicationShortcut dialog and show
- // the dialog when the data is available in OnDidGetApplicationInfo.
- current_tab->extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
-#else
- NOTIMPLEMENTED();
-#endif
-}
-
-void Browser::UpdateDownloadShelfVisibility(bool visible) {
- if (GetStatusBubble())
- GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
-}
-
-bool Browser::OpenInstant(WindowOpenDisposition disposition) {
- if (!instant() || !instant()->PrepareForCommit() ||
- disposition == NEW_BACKGROUND_TAB) {
- // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
- // attempt to use the instant preview.
- 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_contents = instant()->ReleasePreviewContents(
- INSTANT_COMMIT_PRESSED_ENTER, NULL);
- // HideInstant is invoked after release so that InstantController is not
- // active when HideInstant asks it for its state.
- HideInstant();
- preview_contents->web_contents()->GetController().PruneAllButActive();
- tab_strip_model_->AddTabContents(
- preview_contents,
- -1,
- instant()->last_transition_type(),
- TabStripModel::ADD_ACTIVE);
- instant()->CompleteRelease(preview_contents);
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_INSTANT_COMMITTED,
- content::Source<TabContents>(preview_contents),
- 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;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// static
-bool Browser::RunUnloadEventsHelper(WebContents* contents) {
- // If the WebContents is not connected yet, then there's no unload
- // handler we can fire even if the WebContents has an unload listener.
- // One case where we hit this is in a tab that has an infinite loop
- // before load.
- if (contents->NeedToFireBeforeUnload()) {
- // If the page has unload listeners, then we tell the renderer to fire
- // them. Once they have fired, we'll get a message back saying whether
- // to proceed closing the page or not, which sends us back to this method
- // with the NeedToFireBeforeUnload bit cleared.
- contents->GetRenderViewHost()->FirePageBeforeUnload(false);
- return true;
- }
- return false;
-}
-
-// static
-void Browser::JSOutOfMemoryHelper(WebContents* web_contents) {
- TabContents* tab_contents = TabContents::FromWebContents(web_contents);
- if (!tab_contents)
- return;
-
- InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
- infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
- infobar_helper,
- NULL,
- l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT),
- true));
-}
-
-// static
-void Browser::RegisterProtocolHandlerHelper(WebContents* web_contents,
- const std::string& protocol,
- const GURL& url,
- const string16& title,
- bool user_gesture) {
- TabContents* tab_contents = TabContents::FromWebContents(web_contents);
- if (!tab_contents || tab_contents->profile()->IsOffTheRecord())
- return;
-
- ProtocolHandler handler =
- ProtocolHandler::CreateProtocolHandler(protocol, url, title);
-
- ProtocolHandlerRegistry* registry =
- tab_contents->profile()->GetProtocolHandlerRegistry();
-
- if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) {
- content::RecordAction(
- UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown"));
- InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
-
- RegisterProtocolHandlerInfoBarDelegate* rph_delegate =
- new RegisterProtocolHandlerInfoBarDelegate(infobar_helper,
- registry,
- handler);
-
- for (size_t i = 0; i < infobar_helper->infobar_count(); i++) {
- InfoBarDelegate* delegate = infobar_helper->GetInfoBarDelegateAt(i);
- RegisterProtocolHandlerInfoBarDelegate* cast_delegate =
- delegate->AsRegisterProtocolHandlerInfoBarDelegate();
- if (cast_delegate != NULL && cast_delegate->IsReplacedBy(rph_delegate)) {
- infobar_helper->ReplaceInfoBar(cast_delegate, rph_delegate);
- rph_delegate = NULL;
- break;
- }
- }
-
- if (rph_delegate != NULL)
- infobar_helper->AddInfoBar(rph_delegate);
- }
-}
-
-// static
-void Browser::FindReplyHelper(WebContents* web_contents,
- int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) {
- TabContents* tab_contents = TabContents::FromWebContents(web_contents);
- if (!tab_contents || !tab_contents->find_tab_helper())
- return;
-
- tab_contents->find_tab_helper()->HandleFindReply(request_id,
- number_of_matches,
- selection_rect,
- active_match_ordinal,
- final_update);
-}
-
-void Browser::ExecuteCommand(int id) {
- ExecuteCommandWithDisposition(id, CURRENT_TAB);
-}
-
-void Browser::ExecuteCommand(int id, int event_flags) {
- ExecuteCommandWithDisposition(
- id, browser::DispositionFromEventFlags(event_flags));
-}
-
-bool Browser::ExecuteCommandIfEnabled(int id) {
- if (command_updater_.SupportsCommand(id) &&
- command_updater_.IsCommandEnabled(id)) {
- ExecuteCommand(id);
- return true;
- }
- return false;
-}
-
-bool Browser::IsReservedCommandOrKey(int command_id,
- const NativeWebKeyboardEvent& event) {
+bool BrowserCommandController::IsReservedCommandOrKey(
+ int command_id,
+ const content::NativeWebKeyboardEvent& event) {
// In Apps mode, no keys are reserved.
- if (is_app())
+ if (browser_->is_app())
return false;
#if defined(OS_CHROMEOS)
@@ -1230,7 +149,7 @@
}
#endif
- if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN)
+ if (window()->IsFullscreen() && command_id == IDC_FULLSCREEN)
return true;
return command_id == IDC_CLOSE_TAB ||
command_id == IDC_CLOSE_WINDOW ||
@@ -1245,7 +164,7 @@
command_id == IDC_SEARCH;
}
-void Browser::SetBlockCommandExecution(bool block) {
+void BrowserCommandController::SetBlockCommandExecution(bool block) {
block_command_execution_ = block;
if (block) {
last_blocked_command_id_ = -1;
@@ -1253,51 +172,54 @@
}
}
-int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
+int BrowserCommandController::GetLastBlockedCommand(
+ WindowOpenDisposition* disposition) {
if (disposition)
*disposition = last_blocked_command_disposition_;
return last_blocked_command_id_;
}
-void Browser::UpdateUIForNavigationInTab(TabContents* contents,
- content::PageTransition transition,
- bool user_initiated) {
- tab_strip_model_->TabNavigating(contents, transition);
+void BrowserCommandController::TabStateChanged() {
+ UpdateCommandsForTabState();
+}
- bool contents_is_selected = contents == GetActiveTabContents();
- if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
- // Forcibly reset the location bar if the url is going to change in the
- // current tab, since otherwise it won't discard any ongoing user edits,
- // since it doesn't realize this is a user-initiated action.
- window()->GetLocationBar()->Revert();
+void BrowserCommandController::ContentRestrictionsChanged() {
+ UpdateCommandsForContentRestrictionState();
+}
+
+void BrowserCommandController::FullscreenStateChanged() {
+ FullScreenMode fullscreen_mode = FULLSCREEN_DISABLED;
+ if (window()->IsFullscreen()) {
+#if defined(OS_WIN)
+ fullscreen_mode = window()->IsInMetroSnapMode() ? FULLSCREEN_METRO_SNAP :
+ FULLSCREEN_NORMAL;
+#else
+ fullscreen_mode = FULLSCREEN_NORMAL;
+#endif
}
+ UpdateCommandsForFullscreenMode(fullscreen_mode);
+}
- if (GetStatusBubble())
- GetStatusBubble()->Hide();
+void BrowserCommandController::PrintingStateChanged() {
+ UpdatePrintingState();
+}
- // Update the location bar. This is synchronous. We specifically don't
- // update the load state since the load hasn't started yet and updating it
- // will put it out of sync with the actual state like whether we're
- // displaying a favicon, which controls the throbber. If we updated it here,
- // the throbber will show the default favicon for a split second when
- // navigating away from the new tab page.
- ScheduleUIUpdate(contents->web_contents(), content::INVALIDATE_TYPE_URL);
-
- if (contents_is_selected)
- contents->web_contents()->Focus();
+void BrowserCommandController::LoadingStateChanged(bool is_loading,
+ bool force) {
+ UpdateReloadStopState(is_loading, force);
}
-///////////////////////////////////////////////////////////////////////////////
-// Browser, PageNavigator implementation:
-
-WebContents* Browser::OpenURL(const OpenURLParams& params) {
- return OpenURLFromTab(NULL, params);
+void BrowserCommandController::SendToMobileStateChanged(
+ bool send_to_mobile_available) {
+ command_updater_.UpdateCommandEnabled(IDC_CHROME_TO_MOBILE_PAGE,
+ send_to_mobile_available);
}
-///////////////////////////////////////////////////////////////////////////////
-// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
+////////////////////////////////////////////////////////////////////////////////
+// BrowserCommandController,
+// CommandUpdater::CommandUpdaterDelegate implementation:
-void Browser::ExecuteCommandWithDisposition(
+void BrowserCommandController::ExecuteCommandWithDisposition(
int id, WindowOpenDisposition disposition) {
// No commands are enabled if there is not yet any selected tab.
// TODO(pkasting): It seems like we should not need this, because either
@@ -1306,7 +228,7 @@
// tab. However, Ben says he tried removing this before and got lots of
// crashes, e.g. from Windows sending WM_COMMANDs at random times during
// window construction. This probably could use closer examination someday.
- if (!GetActiveTabContents())
+ if (!browser_->GetActiveTabContents())
return;
DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
@@ -1326,29 +248,59 @@
// declaration order in browser.h!
switch (id) {
// Navigation commands
- case IDC_BACK: chrome::GoBack(this, disposition);break;
+ case IDC_BACK:
+ GoBack(browser_, disposition);
+ break;
case IDC_FORWARD:
- chrome::GoForward(this, disposition);
+ GoForward(browser_, disposition);
break;
- case IDC_RELOAD: chrome::Reload(this, disposition);break;
+ case IDC_RELOAD:
+ Reload(browser_, disposition);
+ break;
case IDC_RELOAD_IGNORING_CACHE:
- chrome::ReloadIgnoringCache(this, disposition);
+ ReloadIgnoringCache(browser_, disposition);
break;
- case IDC_HOME: chrome::Home(this, disposition); break;
- case IDC_OPEN_CURRENT_URL: chrome::OpenCurrentURL(this); break;
- case IDC_STOP: chrome::Stop(this); break;
+ case IDC_HOME:
+ Home(browser_, disposition);
+ break;
+ case IDC_OPEN_CURRENT_URL:
+ OpenCurrentURL(browser_);
+ break;
+ case IDC_STOP:
+ Stop(browser_);
+ break;
// Window management commands
- case IDC_NEW_WINDOW: chrome::NewWindow(this); break;
- case IDC_NEW_INCOGNITO_WINDOW: chrome::NewIncognitoWindow(this); break;
- case IDC_CLOSE_WINDOW: chrome::CloseWindow(this); break;
- case IDC_NEW_TAB: chrome::NewTab(this); break;
- case IDC_CLOSE_TAB: chrome::CloseTab(this); break;
- case IDC_SELECT_NEXT_TAB: chrome::SelectNextTab(this); break;
- case IDC_SELECT_PREVIOUS_TAB: chrome::SelectPreviousTab(this); break;
- case IDC_TABPOSE: chrome::OpenTabpose(this); break;
- case IDC_MOVE_TAB_NEXT: chrome::MoveTabNext(this); break;
- case IDC_MOVE_TAB_PREVIOUS: chrome::MoveTabPrevious(this); break;
+ case IDC_NEW_WINDOW:
+ NewWindow(browser_);
+ break;
+ case IDC_NEW_INCOGNITO_WINDOW:
+ NewIncognitoWindow(browser_);
+ break;
+ case IDC_CLOSE_WINDOW:
+ CloseWindow(browser_);
+ break;
+ case IDC_NEW_TAB:
+ NewTab(browser_);
+ break;
+ case IDC_CLOSE_TAB:
+ CloseTab(browser_);
+ break;
+ case IDC_SELECT_NEXT_TAB:
+ SelectNextTab(browser_);
+ break;
+ case IDC_SELECT_PREVIOUS_TAB:
+ SelectPreviousTab(browser_);
+ break;
+ case IDC_TABPOSE:
+ OpenTabpose(browser_);
+ break;
+ case IDC_MOVE_TAB_NEXT:
+ MoveTabNext(browser_);
+ break;
+ case IDC_MOVE_TAB_PREVIOUS:
+ MoveTabPrevious(browser_);
+ break;
case IDC_SELECT_TAB_0:
case IDC_SELECT_TAB_1:
case IDC_SELECT_TAB_2:
@@ -1357,42 +309,74 @@
case IDC_SELECT_TAB_5:
case IDC_SELECT_TAB_6:
case IDC_SELECT_TAB_7:
- chrome::SelectNumberedTab(this, id - IDC_SELECT_TAB_0);
+ SelectNumberedTab(browser_, id - IDC_SELECT_TAB_0);
break;
- case IDC_SELECT_LAST_TAB: chrome::SelectLastTab(this); break;
- case IDC_DUPLICATE_TAB: chrome::DuplicateTab(this); break;
- case IDC_RESTORE_TAB: RestoreTab(); break;
+ case IDC_SELECT_LAST_TAB:
+ SelectLastTab(browser_);
+ break;
+ case IDC_DUPLICATE_TAB:
+ DuplicateTab(browser_);
+ break;
+ case IDC_RESTORE_TAB:
+ RestoreTab(browser_);
+ break;
case IDC_COPY_URL:
- chrome::WriteCurrentURLToClipboard(this);
+ WriteCurrentURLToClipboard(browser_);
break;
case IDC_SHOW_AS_TAB:
- chrome::ConvertPopupToTabbedBrowser(this);
+ ConvertPopupToTabbedBrowser(browser_);
break;
- case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
+ case IDC_FULLSCREEN:
+ browser_->ToggleFullscreenMode();
+ break;
#if defined(OS_WIN)
- case IDC_METRO_SNAP_ENABLE: SetMetroSnapMode(true); break;
- case IDC_METRO_SNAP_DISABLE: SetMetroSnapMode(false); break;
+ case IDC_METRO_SNAP_ENABLE:
+ browser_->SetMetroSnapMode(true);
+ break;
+ case IDC_METRO_SNAP_DISABLE:
+ browser_->SetMetroSnapMode(false);
+ break;
#endif
#if defined(OS_MACOSX)
- case IDC_PRESENTATION_MODE: TogglePresentationMode(); break;
+ case IDC_PRESENTATION_MODE:
+ browser_->TogglePresentationMode();
+ break;
#endif
- case IDC_EXIT: chrome::Exit(); break;
+ case IDC_EXIT:
+ Exit();
+ break;
// Page-related commands
- case IDC_SAVE_PAGE: chrome::SavePage(this); break;
- case IDC_BOOKMARK_PAGE: chrome::BookmarkCurrentPage(this);break;
+ case IDC_SAVE_PAGE:
+ SavePage(browser_);
+ break;
+ case IDC_BOOKMARK_PAGE:
+ BookmarkCurrentPage(browser_);
+ break;
case IDC_PIN_TO_START_SCREEN:
- chrome::PinCurrentPageToStartScreen(this);
+ PinCurrentPageToStartScreen(browser_);
break;
- case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
- case IDC_VIEW_SOURCE: chrome::ViewSelectedSource(this); break;
- case IDC_EMAIL_PAGE_LOCATION: chrome::EmailPageLocation(this); break;
- case IDC_PRINT: chrome::Print(this); break;
- case IDC_ADVANCED_PRINT: chrome::AdvancedPrint(this); break;
+ case IDC_BOOKMARK_ALL_TABS:
+ BookmarkAllTabs(browser_);
+ break;
+ case IDC_VIEW_SOURCE:
+ ViewSelectedSource(browser_);
+ break;
+ case IDC_EMAIL_PAGE_LOCATION:
+ EmailPageLocation(browser_);
+ break;
+ case IDC_PRINT:
+ Print(browser_);
+ break;
+ case IDC_ADVANCED_PRINT:
+ AdvancedPrint(browser_);
+ break;
case IDC_CHROME_TO_MOBILE_PAGE:
- chrome::ShowChromeToMobileBubble(this);
+ ShowChromeToMobileBubble(browser_);
break;
- case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
+ case IDC_ENCODING_AUTO_DETECT:
+ browser_->ToggleEncodingAutoDetect();
+ break;
case IDC_ENCODING_UTF8:
case IDC_ENCODING_UTF16LE:
case IDC_ENCODING_ISO88591:
@@ -1429,97 +413,153 @@
case IDC_ENCODING_ISO88598:
case IDC_ENCODING_ISO88598I:
case IDC_ENCODING_WINDOWS1255:
- case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
+ case IDC_ENCODING_WINDOWS1258:
+ browser_->OverrideEncoding(id);
+ break;
// Clipboard commands
- case IDC_CUT: chrome::Cut(this); break;
- case IDC_COPY: chrome::Copy(this); break;
- case IDC_PASTE: chrome::Paste(this); break;
+ case IDC_CUT:
+ Cut(browser_);
+ break;
+ case IDC_COPY:
+ Copy(browser_);
+ break;
+ case IDC_PASTE:
+ Paste(browser_);
+ break;
// Find-in-page
- case IDC_FIND: chrome::Find(this); break;
- case IDC_FIND_NEXT: chrome::FindNext(this); break;
- case IDC_FIND_PREVIOUS: chrome::FindPrevious(this); break;
+ case IDC_FIND:
+ Find(browser_);
+ break;
+ case IDC_FIND_NEXT:
+ FindNext(browser_);
+ break;
+ case IDC_FIND_PREVIOUS:
+ FindPrevious(browser_);
+ break;
// Zoom
case IDC_ZOOM_PLUS:
- chrome::Zoom(this, content::PAGE_ZOOM_IN);
+ Zoom(browser_, content::PAGE_ZOOM_IN);
break;
case IDC_ZOOM_NORMAL:
- chrome::Zoom(this, content::PAGE_ZOOM_RESET);
+ Zoom(browser_, content::PAGE_ZOOM_RESET);
break;
case IDC_ZOOM_MINUS:
- chrome::Zoom(this, content::PAGE_ZOOM_OUT);
+ Zoom(browser_, content::PAGE_ZOOM_OUT);
break;
// Focus various bits of UI
- case IDC_FOCUS_TOOLBAR: chrome::FocusToolbar(this); break;
- case IDC_FOCUS_LOCATION: chrome::FocusLocationBar(this); break;
- case IDC_FOCUS_SEARCH: chrome::FocusSearch(this); break;
- case IDC_FOCUS_MENU_BAR: chrome::FocusAppMenu(this); break;
+ case IDC_FOCUS_TOOLBAR:
+ FocusToolbar(browser_);
+ break;
+ case IDC_FOCUS_LOCATION:
+ FocusLocationBar(browser_);
+ break;
+ case IDC_FOCUS_SEARCH:
+ FocusSearch(browser_);
+ break;
+ case IDC_FOCUS_MENU_BAR:
+ FocusAppMenu(browser_);
+ break;
case IDC_FOCUS_BOOKMARKS:
- chrome::FocusBookmarksToolbar(this);
+ FocusBookmarksToolbar(browser_);
break;
- case IDC_FOCUS_NEXT_PANE: chrome::FocusNextPane(this); break;
- case IDC_FOCUS_PREVIOUS_PANE: chrome::FocusPreviousPane(this); break;
+ case IDC_FOCUS_NEXT_PANE:
+ FocusNextPane(browser_);
+ break;
+ case IDC_FOCUS_PREVIOUS_PANE:
+ FocusPreviousPane(browser_);
+ break;
// Show various bits of UI
- case IDC_OPEN_FILE: OpenFile(); break;
- case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
+ case IDC_OPEN_FILE:
+ browser_->OpenFile();
+ break;
+ case IDC_CREATE_SHORTCUTS:
+ browser_->OpenCreateShortcutsDialog();
+ break;
case IDC_DEV_TOOLS:
- chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_NONE);
+ ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_NONE);
break;
case IDC_DEV_TOOLS_CONSOLE:
- chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
+ ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
break;
case IDC_DEV_TOOLS_INSPECT:
- chrome::ToggleDevToolsWindow(this, DEVTOOLS_TOGGLE_ACTION_INSPECT);
+ ToggleDevToolsWindow(browser_, DEVTOOLS_TOGGLE_ACTION_INSPECT);
break;
case IDC_TASK_MANAGER:
- chrome::OpenTaskManager(this, false);
+ OpenTaskManager(browser_, false);
break;
case IDC_VIEW_BACKGROUND_PAGES:
- chrome::OpenTaskManager(this, true);
+ OpenTaskManager(browser_, true);
break;
case IDC_FEEDBACK:
- chrome::OpenFeedbackDialog(this);
+ OpenFeedbackDialog(browser_);
break;
- case IDC_SHOW_BOOKMARK_BAR: chrome::ToggleBookmarkBar(this); break;
- case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
+ case IDC_SHOW_BOOKMARK_BAR:
+ ToggleBookmarkBar(browser_);
+ break;
+ case IDC_PROFILING_ENABLED:
+ Profiling::Toggle();
+ break;
- case IDC_SHOW_BOOKMARK_MANAGER: chrome::ShowBookmarkManager(this);break;
- case IDC_SHOW_APP_MENU: chrome::ShowAppMenu(this); break;
- case IDC_SHOW_AVATAR_MENU: chrome::ShowAvatarMenu(this); break;
- case IDC_SHOW_HISTORY: chrome::ShowHistory(this); break;
- case IDC_SHOW_DOWNLOADS: chrome::ShowDownloads(this); break;
- case IDC_MANAGE_EXTENSIONS: chrome::ShowExtensions(this); break;
- case IDC_OPTIONS: chrome::ShowSettings(this); break;
+ case IDC_SHOW_BOOKMARK_MANAGER:
+ ShowBookmarkManager(browser_);
+ break;
+ case IDC_SHOW_APP_MENU:
+ ShowAppMenu(browser_);
+ break;
+ case IDC_SHOW_AVATAR_MENU:
+ ShowAvatarMenu(browser_);
+ break;
+ case IDC_SHOW_HISTORY:
+ ShowHistory(browser_);
+ break;
+ case IDC_SHOW_DOWNLOADS:
+ ShowDownloads(browser_);
+ break;
+ case IDC_MANAGE_EXTENSIONS:
+ ShowExtensions(browser_);
+ break;
+ case IDC_OPTIONS:
+ ShowSettings(browser_);
+ break;
case IDC_EDIT_SEARCH_ENGINES:
- chrome::ShowSearchEngineSettings(this);
+ ShowSearchEngineSettings(browser_);
break;
- case IDC_VIEW_PASSWORDS: chrome::ShowPasswordManager(this);break;
+ case IDC_VIEW_PASSWORDS:
+ ShowPasswordManager(browser_);
+ break;
case IDC_CLEAR_BROWSING_DATA:
- chrome::ShowClearBrowsingDataDialog(this);
+ ShowClearBrowsingDataDialog(browser_);
break;
- case IDC_IMPORT_SETTINGS: chrome::ShowImportDialog(this); break;
- case IDC_ABOUT: chrome::ShowAboutChrome(this); break;
+ case IDC_IMPORT_SETTINGS:
+ ShowImportDialog(browser_);
+ break;
+ case IDC_ABOUT:
+ ShowAboutChrome(browser_);
+ break;
case IDC_UPGRADE_DIALOG:
- chrome::OpenUpdateChromeDialog(this);
+ OpenUpdateChromeDialog(browser_);
break;
case IDC_VIEW_INCOMPATIBILITIES:
- chrome::ShowConflicts(this);
+ ShowConflicts(browser_);
break;
case IDC_HELP_PAGE_VIA_KEYBOARD:
- chrome::ShowHelp(this, chrome::HELP_SOURCE_KEYBOARD);
+ ShowHelp(browser_, HELP_SOURCE_KEYBOARD);
break;
case IDC_HELP_PAGE_VIA_MENU:
- chrome::ShowHelp(this, chrome::HELP_SOURCE_MENU);
+ ShowHelp(browser_, HELP_SOURCE_MENU);
break;
case IDC_SHOW_SYNC_SETUP:
- chrome::ShowSyncSetup(this, SyncPromoUI::SOURCE_MENU);
+ ShowSyncSetup(browser_, SyncPromoUI::SOURCE_MENU);
break;
- case IDC_TOGGLE_SPEECH_INPUT: chrome::ToggleSpeechInput(this); break;
+ case IDC_TOGGLE_SPEECH_INPUT:
+ ToggleSpeechInput(browser_);
+ break;
default:
LOG(WARNING) << "Received Unimplemented Command: " << id;
@@ -1528,1328 +568,28 @@
}
////////////////////////////////////////////////////////////////////////////////
-// Browser, TabRestoreServiceObserver:
+// BrowserCommandController, content::NotificationObserver implementation:
-void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
- command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
- !service->entries().empty());
-}
-
-void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
- if (!tab_restore_service_)
- return;
-
- DCHECK_EQ(tab_restore_service_, service);
- tab_restore_service_->RemoveObserver(this);
- tab_restore_service_ = NULL;
-}
-
-// Centralized method for creating a TabContents, configuring and
-// installing all its supporting objects and observers.
-TabContents* Browser::TabContentsFactory(
- Profile* profile,
- SiteInstance* site_instance,
- int routing_id,
- const WebContents* base_web_contents,
- content::SessionStorageNamespace* session_storage_namespace) {
- WebContents* new_contents = WebContents::Create(
- profile, site_instance, routing_id, base_web_contents,
- session_storage_namespace);
- TabContents* tab_contents = new TabContents(new_contents);
- return tab_contents;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, TabStripModelDelegate implementation:
-
-TabContents* Browser::AddBlankTab(bool foreground) {
- return AddBlankTabAt(-1, foreground);
-}
-
-TabContents* Browser::AddBlankTabAt(int index, bool foreground) {
- // Time new tab page creation time. We keep track of the timing data in
- // WebContents, but we want to include the time it takes to create the
- // WebContents object too.
- base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
- browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
- content::PAGE_TRANSITION_TYPED);
- params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
- params.tabstrip_index = index;
- browser::Navigate(&params);
- params.target_contents->web_contents()->SetNewTabStartTime(
- new_tab_start_time);
- return params.target_contents;
-}
-
-Browser* Browser::CreateNewStripWithContents(
- TabContents* detached_contents,
- const gfx::Rect& window_bounds,
- const DockInfo& dock_info,
- bool maximize) {
- DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
-
- gfx::Rect new_window_bounds = window_bounds;
- if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
- dock_info.AdjustOtherWindowBounds();
-
- // Create an empty new browser window the same size as the old one.
- Browser* browser = new Browser(TYPE_TABBED, profile_);
- browser->set_override_bounds(new_window_bounds);
- browser->set_initial_show_state(
- maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
- browser->InitBrowserWindow();
- browser->tab_strip_model()->AppendTabContents(detached_contents, true);
- // Make sure the loading state is updated correctly, otherwise the throbber
- // won't start if the page is loading.
- browser->LoadingStateChanged(detached_contents->web_contents());
- return browser;
-}
-
-int Browser::GetDragActions() const {
- return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
- TabStripModelDelegate::TAB_MOVE_ACTION : 0);
-}
-
-TabContents* Browser::CreateTabContentsForURL(
- const GURL& url, const content::Referrer& referrer, Profile* profile,
- content::PageTransition transition, bool defer_load,
- SiteInstance* instance) const {
- TabContents* contents = TabContentsFactory(profile, instance,
- MSG_ROUTING_NONE, GetActiveWebContents(), NULL);
- if (!defer_load) {
- // Load the initial URL before adding the new tab contents to the tab strip
- // so that the tab contents has navigation state.
- contents->web_contents()->GetController().LoadURL(
- url, referrer, transition, std::string());
- }
-
- return contents;
-}
-
-bool Browser::CanDuplicateContentsAt(int index) {
- NavigationController& nc = GetWebContentsAt(index)->GetController();
- return nc.GetWebContents() && nc.GetLastCommittedEntry();
-}
-
-void Browser::DuplicateContentsAt(int index) {
- TabContents* contents = GetTabContentsAt(index);
- CHECK(contents);
- TabContents* contents_dupe = contents->Clone();
-
- bool pinned = false;
- if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
- // If this is a tabbed browser, just create a duplicate tab inside the same
- // window next to the tab being duplicated.
- int index = tab_strip_model_->GetIndexOfTabContents(contents);
- pinned = IsTabPinned(index);
- int add_types = TabStripModel::ADD_ACTIVE |
- TabStripModel::ADD_INHERIT_GROUP |
- (pinned ? TabStripModel::ADD_PINNED : 0);
- tab_strip_model_->InsertTabContentsAt(index + 1, contents_dupe, add_types);
- } else {
- Browser* browser = NULL;
- if (is_app()) {
- CHECK(!is_type_popup());
- CHECK(!is_type_panel());
- browser = Browser::CreateWithParams(
- Browser::CreateParams::CreateForApp(
- TYPE_POPUP, app_name_, gfx::Rect(),profile_));
- } else if (is_type_popup()) {
- browser = Browser::CreateWithParams(
- Browser::CreateParams(TYPE_POPUP, profile_));
- }
-
- // Preserve the size of the original window. The new window has already
- // been given an offset by the OS, so we shouldn't copy the old bounds.
- BrowserWindow* new_window = browser->window();
- new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
- window()->GetRestoredBounds().size()));
-
- // We need to show the browser now. Otherwise ContainerWin assumes the
- // WebContents is invisible and won't size it.
- browser->window()->Show();
-
- // The page transition below is only for the purpose of inserting the tab.
- browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK);
- }
-
- SessionService* session_service =
- SessionServiceFactory::GetForProfileIfExisting(profile_);
- if (session_service)
- session_service->TabRestored(contents_dupe, pinned);
-}
-
-void Browser::CloseFrameAfterDragSession() {
-#if !defined(OS_MACOSX)
- // This is scheduled to run after we return to the message loop because
- // otherwise the frame will think the drag session is still active and ignore
- // the request.
- // TODO(port): figure out what is required here in a cross-platform world
- MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
-#endif
-}
-
-void Browser::CreateHistoricalTab(TabContents* contents) {
- // We don't create historical tabs for incognito windows or windows without
- // profiles.
- if (!profile() || profile()->IsOffTheRecord())
- return;
-
- // We don't create historical tabs for print preview tabs.
- if (contents->web_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
- return;
-
- TabRestoreService* service =
- TabRestoreServiceFactory::GetForProfile(profile());
-
- // We only create historical tab entries for tabbed browser windows.
- if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
- service->CreateHistoricalTab(contents->web_contents(),
- tab_strip_model_->GetIndexOfTabContents(contents));
- }
-}
-
-bool Browser::RunUnloadListenerBeforeClosing(TabContents* contents) {
- return Browser::RunUnloadEventsHelper(contents->web_contents());
-}
-
-bool Browser::CanBookmarkAllTabs() const {
- BookmarkModel* model = profile()->GetBookmarkModel();
- return (model && model->IsLoaded()) &&
- tab_count() > 1 &&
- profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
-}
-
-void Browser::BookmarkAllTabs() {
- BookmarkEditor::ShowBookmarkAllTabsDialog(this);
-}
-
-bool Browser::CanRestoreTab() {
- return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
-}
-
-void Browser::RestoreTab() {
- content::RecordAction(UserMetricsAction("RestoreTab"));
- TabRestoreService* service =
- TabRestoreServiceFactory::GetForProfile(profile_);
- if (!service)
- return;
-
- service->RestoreMostRecentEntry(tab_restore_service_delegate());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, TabStripModelObserver implementation:
-
-void Browser::TabInsertedAt(TabContents* contents,
- int index,
- bool foreground) {
- SetAsDelegate(contents, this);
- contents->restore_tab_helper()->SetWindowID(session_id());
-
- SyncHistoryWithTabs(index);
-
- // Make sure the loading state is updated correctly, otherwise the throbber
- // won't start if the page is loading.
- LoadingStateChanged(contents->web_contents());
-
- // If the tab crashes in the beforeunload or unload handler, it won't be
- // able to ack. But we know we can close it.
- registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
- content::Source<WebContents>(contents->web_contents()));
-
- registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
- content::Source<WebContents>(contents->web_contents()));
-
- registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
- content::Source<WebContents>(contents->web_contents()));
-}
-
-void Browser::TabClosingAt(TabStripModel* tab_strip_model,
- TabContents* contents,
- int index) {
- fullscreen_controller_->OnTabClosing(contents->web_contents());
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_TAB_CLOSING,
- content::Source<NavigationController>(
- &contents->web_contents()->GetController()),
- content::NotificationService::NoDetails());
-
- // Sever the WebContents' connection back to us.
- SetAsDelegate(contents, NULL);
-}
-
-void Browser::TabDetachedAt(TabContents* contents, int index) {
- TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
-}
-
-void Browser::TabDeactivated(TabContents* contents) {
- fullscreen_controller_->OnTabDeactivated(contents);
- search_delegate_->OnTabDeactivated(contents);
-
- if (instant())
- instant()->Hide();
-
- // Save what the user's currently typing, so it can be restored when we
- // switch back to this tab.
- window_->GetLocationBar()->SaveStateToContents(contents->web_contents());
-}
-
-void Browser::ActiveTabChanged(TabContents* old_contents,
- TabContents* new_contents,
- int index,
- bool user_gesture) {
- // On some platforms we want to automatically reload tabs that are
- // killed when the user selects them.
- bool did_reload = false;
- if (user_gesture && new_contents->web_contents()->GetCrashedStatus() ==
- base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
- const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
- if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
- LOG(WARNING) << "Reloading killed tab at " << index;
- static int reload_count = 0;
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Tabs.SadTab.ReloadCount", ++reload_count, 1, 1000, 50);
- chrome::Reload(this, CURRENT_TAB);
- did_reload = true;
- }
- }
-
- // Discarded tabs always get reloaded.
- if (!did_reload && IsTabDiscarded(index)) {
- LOG(WARNING) << "Reloading discarded tab at " << index;
- static int reload_count = 0;
- UMA_HISTOGRAM_CUSTOM_COUNTS(
- "Tabs.Discard.ReloadCount", ++reload_count, 1, 1000, 50);
- chrome::Reload(this, CURRENT_TAB);
- }
-
- // If we have any update pending, do it now.
- if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
- ProcessPendingUIUpdates();
-
- // Propagate the profile to the location bar.
- UpdateToolbar(true);
-
- // Propagate tab state to toolbar, tab-strip, etc.
- UpdateSearchState(new_contents);
-
- // Update reload/stop state.
- UpdateReloadStopState(new_contents->web_contents()->IsLoading(), true);
-
- // Update commands to reflect current state.
- UpdateCommandsForTabState();
-
- // Reset the status bubble.
- StatusBubble* status_bubble = GetStatusBubble();
- if (status_bubble) {
- status_bubble->Hide();
-
- // Show the loading state (if any).
- status_bubble->SetStatus(
- GetActiveTabContents()->core_tab_helper()->GetStatusText());
- }
-
- if (HasFindBarController()) {
- find_bar_controller_->ChangeTabContents(new_contents);
- find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
- }
-
- // Update sessions. Don't force creation of sessions. If sessions doesn't
- // exist, the change will be picked up by sessions when created.
- SessionService* session_service =
- SessionServiceFactory::GetForProfileIfExisting(profile_);
- if (session_service && !tab_strip_model_->closing_all()) {
- session_service->SetSelectedTabInWindow(session_id(), active_index());
- }
-
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
-}
-
-void Browser::TabMoved(TabContents* contents,
- int from_index,
- int to_index) {
- DCHECK(from_index >= 0 && to_index >= 0);
- // Notify the history service.
- SyncHistoryWithTabs(std::min(from_index, to_index));
-}
-
-void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
- TabContents* old_contents,
- TabContents* new_contents,
- int index) {
- TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
- TabInsertedAt(new_contents, index, (index == active_index()));
-
- int entry_count =
- new_contents->web_contents()->GetController().GetEntryCount();
- if (entry_count > 0) {
- // Send out notification so that observers are updated appropriately.
- new_contents->web_contents()->GetController().NotifyEntryChanged(
- new_contents->web_contents()->GetController().GetEntryAtIndex(
- entry_count - 1),
- entry_count - 1);
- }
-
- SessionService* session_service =
- SessionServiceFactory::GetForProfile(profile());
- if (session_service) {
- // The new_contents may end up with a different navigation stack. Force
- // the session service to update itself.
- session_service->TabRestored(new_contents, IsTabPinned(index));
- }
-
- content::DevToolsManager::GetInstance()->ContentsReplaced(
- old_contents->web_contents(), new_contents->web_contents());
-}
-
-void Browser::TabPinnedStateChanged(TabContents* contents, int index) {
- SessionService* session_service =
- SessionServiceFactory::GetForProfileIfExisting(profile());
- if (session_service) {
- session_service->SetPinnedState(
- session_id(),
- GetTabContentsAt(index)->restore_tab_helper()->session_id(),
- IsTabPinned(index));
- }
-}
-
-void Browser::TabStripEmpty() {
- // Close the frame after we return to the message loop (not immediately,
- // otherwise it will destroy this object before the stack has a chance to
- // cleanly unwind.)
- // Note: This will be called several times if TabStripEmpty is called several
- // times. This is because it does not close the window if tabs are
- // still present.
- MessageLoop::current()->PostTask(
- FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
- // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not
- // attempt to add tabs to the browser before it closes.
- is_attempting_to_close_browser_ = true;
-}
-
-bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
- bool* is_keyboard_shortcut) {
- // Escape exits tabbed fullscreen mode.
- // TODO(koz): Write a test for this http://crbug.com/100441.
- if (event.windowsKeyCode == 27 &&
- fullscreen_controller_->HandleUserPressedEscape()) {
- return true;
- }
- return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
-}
-
-void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
- window()->HandleKeyboardEvent(event);
-}
-
-void Browser::OnAcceptFullscreenPermission(
- const GURL& url,
- FullscreenExitBubbleType bubble_type) {
- fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type);
-}
-
-void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) {
- fullscreen_controller_->OnDenyFullscreenPermission(bubble_type);
-}
-
-bool Browser::TabsNeedBeforeUnloadFired() {
- if (tabs_needing_before_unload_fired_.empty()) {
- for (int i = 0; i < tab_count(); ++i) {
- WebContents* contents = GetTabContentsAt(i)->web_contents();
- if (contents->NeedToFireBeforeUnload())
- tabs_needing_before_unload_fired_.insert(contents);
- }
- }
- return !tabs_needing_before_unload_fired_.empty();
-}
-
-bool Browser::IsFullscreenForTabOrPending() const {
- return fullscreen_controller_->IsFullscreenForTabOrPending();
-}
-
-bool Browser::IsMouseLocked() const {
- return fullscreen_controller_->IsMouseLocked();
-}
-
-void Browser::OnWindowDidShow() {
- if (window_has_shown_)
- return;
- window_has_shown_ = true;
-
- // Nothing to do for non-tabbed windows.
- if (!is_type_tabbed())
- return;
-
- // Show any pending global error bubble.
- GlobalErrorService* service =
- GlobalErrorServiceFactory::GetForProfile(profile());
- GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
- if (error)
- error->ShowBubbleView(this);
-}
-
-void Browser::ShowFirstRunBubble() {
- window()->GetLocationBar()->ShowFirstRunBubble();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, protected:
-
-BrowserWindow* Browser::CreateBrowserWindow() {
- bool create_panel = false;
-#if defined(USE_ASH)
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- ash::switches::kAuraPanelManager))
- create_panel = is_type_panel();
-#elif !defined(OS_CHROMEOS)
- create_panel = is_type_panel();
-#endif
- if (create_panel)
- return PanelManager::GetInstance()->CreatePanel(this)->browser_window();
-
- return BrowserWindow::CreateBrowserWindow(this);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, content::WebContentsDelegate implementation:
-
-WebContents* Browser::OpenURLFromTab(WebContents* source,
- const OpenURLParams& params) {
- browser::NavigateParams nav_params(this, params.url, params.transition);
- nav_params.source_contents = GetTabContentsAt(
- tab_strip_model_->GetIndexOfWebContents(source));
- nav_params.referrer = params.referrer;
- nav_params.disposition = params.disposition;
- nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
- nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
- nav_params.user_gesture = true;
- nav_params.override_encoding = params.override_encoding;
- nav_params.is_renderer_initiated = params.is_renderer_initiated;
- nav_params.transferred_global_request_id =
- params.transferred_global_request_id;
- browser::Navigate(&nav_params);
-
- return nav_params.target_contents ?
- nav_params.target_contents->web_contents() : NULL;
-}
-
-void Browser::NavigationStateChanged(const WebContents* source,
- unsigned changed_flags) {
- // Only update the UI when something visible has changed.
- if (changed_flags)
- ScheduleUIUpdate(source, changed_flags);
-
- // We can synchronously update commands since they will only change once per
- // navigation, so we don't have to worry about flickering. We do, however,
- // need to update the command state early on load to always present usable
- // actions in the face of slow-to-commit pages.
- if (changed_flags & (content::INVALIDATE_TYPE_URL |
- content::INVALIDATE_TYPE_LOAD))
- UpdateCommandsForTabState();
-}
-
-void Browser::AddNewContents(WebContents* source,
- WebContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- // No code for this yet.
- DCHECK(disposition != SAVE_TO_DISK);
- // Can't create a new contents for the current tab - invalid case.
- DCHECK(disposition != CURRENT_TAB);
-
- TabContents* source_tab_contents = NULL;
- BlockedContentTabHelper* source_blocked_content = NULL;
- TabContents* new_tab_contents = TabContents::FromWebContents(new_contents);
- if (!new_tab_contents) {
- new_tab_contents = new TabContents(new_contents);
- }
- if (source) {
- source_tab_contents = TabContents::FromWebContents(source);
- source_blocked_content = source_tab_contents->blocked_content_tab_helper();
- }
-
- if (source_tab_contents) {
- // Handle blocking of all contents.
- if (source_blocked_content->all_contents_blocked()) {
- source_blocked_content->AddTabContents(new_tab_contents,
- disposition,
- initial_pos,
- user_gesture);
- return;
- }
-
- // Handle blocking of popups.
- if ((disposition == NEW_POPUP) && !user_gesture &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisablePopupBlocking)) {
- // Unrequested popups from normal pages are constrained unless they're in
- // the whitelist. The popup owner will handle checking this.
- GetConstrainingTabContents(source_tab_contents)->
- blocked_content_tab_helper()->
- AddPopup(new_tab_contents, initial_pos, user_gesture);
- return;
- }
-
- new_contents->GetRenderViewHost()->DisassociateFromPopupCount();
- }
-
- browser::NavigateParams params(this, new_tab_contents);
- params.source_contents = source ?
- GetTabContentsAt(tab_strip_model_->GetIndexOfWebContents(source)): NULL;
- params.disposition = disposition;
- params.window_bounds = initial_pos;
- params.window_action = browser::NavigateParams::SHOW_WINDOW;
- params.user_gesture = user_gesture;
- browser::Navigate(&params);
-}
-
-void Browser::ActivateContents(WebContents* contents) {
- ActivateTabAt(tab_strip_model_->GetIndexOfWebContents(contents), false);
- window_->Activate();
-}
-
-void Browser::DeactivateContents(WebContents* contents) {
- window_->Deactivate();
-}
-
-void Browser::LoadingStateChanged(WebContents* source) {
- window_->UpdateLoadingAnimations(tab_strip_model_->TabsAreLoading());
- window_->UpdateTitleBar();
-
- WebContents* selected_contents = GetActiveWebContents();
- if (source == selected_contents) {
- bool is_loading = source->IsLoading();
- UpdateReloadStopState(is_loading, false);
- if (GetStatusBubble()) {
- GetStatusBubble()->SetStatus(
- GetActiveTabContents()->core_tab_helper()->GetStatusText());
- }
-
- if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
- // Schedule a shortcut update when web application info is available if
- // last committed entry is not NULL. Last committed entry could be NULL
- // when an interstitial page is injected (e.g. bad https certificate,
- // malware site etc). When this happens, we abort the shortcut update.
- NavigationEntry* entry = source->GetController().GetLastCommittedEntry();
- if (entry) {
- TabContents::FromWebContents(source)->
- extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
- } else {
- pending_web_app_action_ = NONE;
- }
- }
- }
-}
-
-void Browser::CloseContents(WebContents* source) {
- if (is_attempting_to_close_browser_) {
- // If we're trying to close the browser, just clear the state related to
- // waiting for unload to fire. Don't actually try to close the tab as it
- // will go down the slow shutdown path instead of the fast path of killing
- // all the renderer processes.
- ClearUnloadState(source, true);
- return;
- }
-
- int index = tab_strip_model_->GetIndexOfWebContents(source);
- if (index == TabStripModel::kNoTab) {
- NOTREACHED() << "CloseContents called for tab not in our strip";
- return;
- }
- tab_strip_model_->CloseTabContentsAt(index,
- TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
-}
-
-void Browser::MoveContents(WebContents* source, const gfx::Rect& pos) {
- if (!IsPopupOrPanel(source)) {
- NOTREACHED() << "moving invalid browser type";
- return;
- }
- window_->SetBounds(pos);
-}
-
-void Browser::DetachContents(WebContents* source) {
- int index = tab_strip_model_->GetIndexOfWebContents(source);
- if (index >= 0)
- tab_strip_model_->DetachTabContentsAt(index);
-}
-
-bool Browser::IsPopupOrPanel(const WebContents* source) const {
- // A non-tabbed BROWSER is an unconstrained popup.
- return is_type_popup() || is_type_panel();
-}
-
-void Browser::UpdateTargetURL(WebContents* source, int32 page_id,
- const GURL& url) {
- if (!GetStatusBubble())
- return;
-
- if (source == GetActiveWebContents()) {
- PrefService* prefs = profile_->GetPrefs();
- GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
- }
-}
-
-void Browser::ContentsMouseEvent(
- WebContents* source, const gfx::Point& location, bool motion) {
- if (!GetStatusBubble())
- return;
-
- if (source == GetActiveWebContents()) {
- GetStatusBubble()->MouseMoved(location, !motion);
- if (!motion)
- GetStatusBubble()->SetURL(GURL(), std::string());
- }
-}
-
-void Browser::ContentsZoomChange(bool zoom_in) {
- ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
-}
-
-void Browser::WebContentsFocused(WebContents* contents) {
- window_->WebContentsFocused(contents);
-}
-
-bool Browser::TakeFocus(bool reverse) {
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
- content::Source<Browser>(this),
- content::NotificationService::NoDetails());
- return false;
-}
-
-bool Browser::IsApplication() const {
- return is_app();
-}
-
-void Browser::ConvertContentsToApplication(WebContents* contents) {
- const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
- std::string app_name = web_app::GenerateApplicationNameFromURL(url);
-
- DetachContents(contents);
- Browser* app_browser = Browser::CreateWithParams(
- Browser::CreateParams::CreateForApp(
- TYPE_POPUP, app_name, gfx::Rect(), profile_));
- TabContents* tab_contents = TabContents::FromWebContents(contents);
- if (!tab_contents)
- tab_contents = new TabContents(contents);
- app_browser->tab_strip_model()->AppendTabContents(tab_contents, true);
-
- contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
- contents->GetRenderViewHost()->SyncRendererPrefs();
- app_browser->window()->Show();
-}
-
-gfx::Rect Browser::GetRootWindowResizerRect() const {
- return window_->GetRootWindowResizerRect();
-}
-
-void Browser::BeforeUnloadFired(WebContents* web_contents,
- bool proceed,
- bool* proceed_to_fire_unload) {
- if (!is_attempting_to_close_browser_) {
- *proceed_to_fire_unload = proceed;
- if (!proceed)
- web_contents->SetClosedByUserGesture(false);
- return;
- }
-
- if (!proceed) {
- CancelWindowClose();
- *proceed_to_fire_unload = false;
- web_contents->SetClosedByUserGesture(false);
- return;
- }
-
- if (RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents)) {
- // Now that beforeunload has fired, put the tab on the queue to fire
- // unload.
- tabs_needing_unload_fired_.insert(web_contents);
- ProcessPendingTabs();
- // We want to handle firing the unload event ourselves since we want to
- // fire all the beforeunload events before attempting to fire the unload
- // events should the user cancel closing the browser.
- *proceed_to_fire_unload = false;
- return;
- }
-
- *proceed_to_fire_unload = true;
-}
-
-void Browser::SetFocusToLocationBar(bool select_all) {
- // Two differences between this and FocusLocationBar():
- // (1) This doesn't get recorded in user metrics, since it's called
- // internally.
- // (2) This checks whether the location bar can be focused, and if not, clears
- // the focus. FocusLocationBar() is only reached when the location bar is
- // focusable, but this may be reached at other times, e.g. while in
- // fullscreen mode, where we need to leave focus in a consistent state.
- window_->SetFocusToLocationBar(select_all);
-}
-
-void Browser::RenderWidgetShowing() {
- window_->DisableInactiveFrame();
-}
-
-int Browser::GetExtraRenderViewHeight() const {
- return window_->GetExtraRenderViewHeight();
-}
-
-void Browser::OnStartDownload(WebContents* source,
- content::DownloadItem* download) {
- TabContents* tab_contents = TabContents::FromWebContents(source);
- TabContents* constrained = GetConstrainingTabContents(tab_contents);
- if (constrained != tab_contents) {
- // Download in a constrained popup is shown in the tab that opened it.
- WebContents* constrained_tab = constrained->web_contents();
- constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download);
- return;
- }
-
- if (!window())
- return;
-
- // GetDownloadShelf creates the download shelf if it was not yet created.
- DownloadShelf* shelf = window()->GetDownloadShelf();
- shelf->AddDownload(new DownloadItemModel(download));
- // Don't show the animation for "Save file" downloads.
- // For non-theme extensions, we don't show the download animation.
- // Show animation in same window as the download shelf. Download shelf
- // may not be in the same window that initiated the download, e.g.
- // Panels.
- // Don't show the animation if the selected tab is not visible (i.e. the
- // window is minimized, we're in a unit test, etc.).
- WebContents* shelf_tab = shelf->browser()->GetActiveWebContents();
- if ((download->GetTotalBytes() > 0) &&
- !download_crx_util::IsExtensionDownload(*download) &&
- platform_util::IsVisible(shelf_tab->GetNativeView()) &&
- ui::Animation::ShouldRenderRichAnimation()) {
- DownloadStartedAnimation::Show(shelf_tab);
- }
-
- // If the download occurs in a new tab, close it.
- if (source->GetController().IsInitialNavigation() && tab_count() > 1)
- CloseContents(source);
-}
-
-void Browser::ViewSourceForTab(WebContents* source, const GURL& page_url) {
- DCHECK(source);
- TabContents* tab_contents = GetTabContentsAt(
- tab_strip_model_->GetIndexOfWebContents(source));
- chrome::ViewSource(this, tab_contents);
-}
-
-void Browser::ViewSourceForFrame(WebContents* source,
- const GURL& frame_url,
- const std::string& frame_content_state) {
- DCHECK(source);
- TabContents* tab_contents = GetTabContentsAt(
- tab_strip_model_->GetIndexOfWebContents(source));
- chrome::ViewSource(this, tab_contents, frame_url, frame_content_state);
-}
-
-void Browser::ShowRepostFormWarningDialog(WebContents* source) {
- browser::ShowTabModalConfirmDialog(
- new RepostFormWarningController(source),
- TabContents::FromWebContents(source));
-}
-
-bool Browser::ShouldAddNavigationToHistory(
- const history::HistoryAddPageArgs& add_page_args,
- content::NavigationType navigation_type) {
- // Don't update history if running as app.
- return !IsApplication();
-}
-
-bool Browser::ShouldCreateWebContents(
- WebContents* web_contents,
- int route_id,
- WindowContainerType window_container_type,
- const string16& frame_name,
- const GURL& target_url) {
- if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
- // If a BackgroundContents is created, suppress the normal WebContents.
- return !MaybeCreateBackgroundContents(
- route_id, web_contents, frame_name, target_url);
- }
-
- return true;
-}
-
-void Browser::WebContentsCreated(WebContents* source_contents,
- int64 source_frame_id,
- const GURL& target_url,
- WebContents* new_contents) {
- // Create a TabContents now, so all observers are in place, as the network
- // requests for its initial navigation will start immediately. The WebContents
- // will later be inserted into this browser using Browser::Navigate via
- // AddNewContents. The latter will retrieve the newly created TabContents from
- // WebContents object.
- new TabContents(new_contents);
-
- // Notify.
- RetargetingDetails details;
- details.source_web_contents = source_contents;
- details.source_frame_id = source_frame_id;
- details.target_url = target_url;
- details.target_web_contents = new_contents;
- details.not_yet_in_tabstrip = true;
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_RETARGETING,
- content::Source<Profile>(profile_),
- content::Details<RetargetingDetails>(&details));
-}
-
-void Browser::ContentRestrictionsChanged(WebContents* source) {
- UpdateCommandsForContentRestrictionState();
-}
-
-void Browser::RendererUnresponsive(WebContents* source) {
- // Ignore hangs if print preview is open.
- TabContents* tab_contents = TabContents::FromWebContents(source);
- if (tab_contents) {
- printing::PrintPreviewTabController* controller =
- printing::PrintPreviewTabController::GetInstance();
- if (controller) {
- TabContents* preview_tab =
- controller->GetPrintPreviewForTab(tab_contents);
- if (preview_tab && preview_tab != tab_contents) {
- return;
- }
- }
- }
-
- browser::ShowHungRendererDialog(source);
-}
-
-void Browser::RendererResponsive(WebContents* source) {
- browser::HideHungRendererDialog(source);
-}
-
-void Browser::WorkerCrashed(WebContents* source) {
- TabContents* tab_contents = TabContents::FromWebContents(source);
- InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
- infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
- infobar_helper,
- NULL,
- l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
- true));
-}
-
-void Browser::DidNavigateMainFramePostCommit(WebContents* web_contents) {
- if (web_contents == GetActiveWebContents())
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
-}
-
-void Browser::DidNavigateToPendingEntry(WebContents* web_contents) {
- if (web_contents == GetActiveWebContents())
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
-}
-
-content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
- return GetJavaScriptDialogCreatorInstance();
-}
-
-content::ColorChooser* Browser::OpenColorChooser(WebContents* web_contents,
- int color_chooser_id,
- SkColor color) {
-#if defined(OS_WIN)
- // On Windows, only create a color chooser if one doesn't exist, because we
- // can't close the old color chooser dialog.
- if (!color_chooser_.get())
- color_chooser_.reset(content::ColorChooser::Create(color_chooser_id,
- web_contents,
- color));
-#else
- if (color_chooser_.get())
- color_chooser_->End();
- color_chooser_.reset(content::ColorChooser::Create(color_chooser_id,
- web_contents,
- color));
-#endif
- return color_chooser_.get();
-}
-
-void Browser::DidEndColorChooser() {
- color_chooser_.reset();
-}
-
-void Browser::RunFileChooser(WebContents* web_contents,
- const content::FileChooserParams& params) {
- FileSelectHelper::RunFileChooser(web_contents, params);
-}
-
-void Browser::EnumerateDirectory(WebContents* web_contents,
- int request_id,
- const FilePath& path) {
- FileSelectHelper::EnumerateDirectory(web_contents, request_id, path);
-}
-
-void Browser::ToggleFullscreenModeForTab(WebContents* web_contents,
- bool enter_fullscreen) {
- fullscreen_controller_->ToggleFullscreenModeForTab(web_contents,
- enter_fullscreen);
-}
-
-bool Browser::IsFullscreenForTabOrPending(
- const WebContents* web_contents) const {
- return fullscreen_controller_->IsFullscreenForTabOrPending(web_contents);
-}
-
-void Browser::JSOutOfMemory(WebContents* web_contents) {
- JSOutOfMemoryHelper(web_contents);
-}
-
-void Browser::RegisterProtocolHandler(WebContents* web_contents,
- const std::string& protocol,
- const GURL& url,
- const string16& title,
- bool user_gesture) {
- RegisterProtocolHandlerHelper(
- web_contents, protocol, url, title, user_gesture);
-}
-
-void Browser::RegisterIntentHandler(
- WebContents* web_contents,
- const webkit_glue::WebIntentServiceData& data,
- bool user_gesture) {
- RegisterIntentHandlerHelper(web_contents, data, user_gesture);
-}
-
-void Browser::WebIntentDispatch(
- WebContents* web_contents,
- content::WebIntentsDispatcher* intents_dispatcher) {
- if (!web_intents::IsWebIntentsEnabledForProfile(profile_))
- return;
-
- UMA_HISTOGRAM_COUNTS("WebIntents.Dispatch", 1);
-
- TabContents* tab_contents = TabContents::FromWebContents(web_contents);
- tab_contents->web_intent_picker_controller()->SetIntentsDispatcher(
- intents_dispatcher);
- tab_contents->web_intent_picker_controller()->ShowDialog(
- intents_dispatcher->GetIntent().action,
- intents_dispatcher->GetIntent().type);
-}
-
-void Browser::UpdatePreferredSize(WebContents* source,
- const gfx::Size& pref_size) {
- window_->UpdatePreferredSize(source, pref_size);
-}
-
-void Browser::ResizeDueToAutoResize(WebContents* source,
- const gfx::Size& new_size) {
- window_->ResizeDueToAutoResize(source, new_size);
-}
-
-void Browser::FindReply(WebContents* web_contents,
- int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) {
- FindReplyHelper(web_contents, request_id, number_of_matches, selection_rect,
- active_match_ordinal, final_update);
-}
-
-void Browser::RequestToLockMouse(WebContents* web_contents,
- bool user_gesture,
- bool last_unlocked_by_target) {
- fullscreen_controller_->RequestToLockMouse(web_contents,
- user_gesture,
- last_unlocked_by_target);
-}
-
-void Browser::LostMouseLock() {
- fullscreen_controller_->LostMouseLock();
-}
-
-void Browser::RequestMediaAccessPermission(
- content::WebContents* web_contents,
- const content::MediaStreamRequest* request,
- const content::MediaResponseCallback& callback) {
- TabContents* tab = TabContents::FromWebContents(web_contents);
- DCHECK(tab);
-
- scoped_ptr<MediaStreamDevicesController>
- controller(new MediaStreamDevicesController(tab->profile(),
- request,
- callback));
- if (!controller->DismissInfoBarAndTakeActionOnSettings()) {
- InfoBarTabHelper* infobar_helper = tab->infobar_tab_helper();
- InfoBarDelegate* old_infobar = NULL;
- for (size_t i = 0; i < infobar_helper->infobar_count(); ++i) {
- old_infobar = infobar_helper->GetInfoBarDelegateAt(i)->
- AsMediaStreamInfoBarDelegate();
- if (old_infobar)
- break;
- }
-
- InfoBarDelegate* infobar =
- new MediaStreamInfoBarDelegate(infobar_helper, controller.release());
- if (old_infobar)
- infobar_helper->ReplaceInfoBar(old_infobar, infobar);
- else
- infobar_helper->AddInfoBar(infobar);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, CoreTabHelperDelegate implementation:
-
-void Browser::SwapTabContents(TabContents* old_tab_contents,
- TabContents* new_tab_contents) {
- int index = tab_strip_model_->GetIndexOfTabContents(old_tab_contents);
- DCHECK_NE(TabStripModel::kNoTab, index);
- tab_strip_model_->ReplaceTabContentsAt(index, new_tab_contents);
-}
-
-bool Browser::CanReloadContents(TabContents* source) const {
- return !is_devtools();
-}
-
-bool Browser::CanSaveContents(TabContents* source) const {
- return !is_devtools();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, SearchEngineTabHelperDelegate implementation:
-
-void Browser::ConfirmAddSearchProvider(TemplateURL* template_url,
- Profile* profile) {
- window()->ConfirmAddSearchProvider(template_url, profile);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, ConstrainedWindowTabHelperDelegate implementation:
-
-void Browser::SetTabContentBlocked(TabContents* tab_contents, bool blocked) {
- int index = tab_strip_model_->GetIndexOfTabContents(tab_contents);
- if (index == TabStripModel::kNoTab) {
- NOTREACHED();
- return;
- }
- tab_strip_model_->SetTabBlocked(index, blocked);
- UpdatePrintingState(tab_contents->web_contents()->GetContentRestrictions());
- if (!blocked && GetActiveTabContents() == tab_contents)
- tab_contents->web_contents()->Focus();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, BlockedContentTabHelperDelegate implementation:
-
-TabContents* Browser::GetConstrainingTabContents(TabContents* source) {
- return source;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, BookmarkTabHelperDelegate implementation:
-
-void Browser::URLStarredChanged(TabContents* source, bool starred) {
- if (source == GetActiveTabContents())
- window_->SetStarredState(starred);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, ZoomObserver implementation:
-
-void Browser::OnZoomIconChanged(TabContents* source,
- ZoomController::ZoomIconState state) {
- if (source == GetActiveTabContents())
- window_->SetZoomIconState(state);
-}
-
-void Browser::OnZoomChanged(TabContents* source,
- int zoom_percent,
- bool can_show_bubble) {
- if (source == GetActiveTabContents()) {
- window_->SetZoomIconTooltipPercent(zoom_percent);
-
- // Only show the zoom bubble for zoom changes in the active window.
- if (can_show_bubble && window_->IsActive())
- window_->ShowZoomBubble(zoom_percent);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, ExtensionTabHelperDelegate implementation:
-
-void Browser::OnDidGetApplicationInfo(TabContents* source,
- int32 page_id) {
- if (GetActiveTabContents() != source)
- return;
-
- NavigationEntry* entry =
- source->web_contents()->GetController().GetLastCommittedEntry();
- if (!entry || (entry->GetPageID() != page_id))
- return;
-
- switch (pending_web_app_action_) {
- case CREATE_SHORTCUT: {
- window()->ShowCreateWebAppShortcutsDialog(source);
- break;
- }
- case UPDATE_SHORTCUT: {
- web_app::UpdateShortcutForTabContents(source);
- break;
- }
- default:
- NOTREACHED();
- break;
- }
-
- pending_web_app_action_ = NONE;
-}
-
-void Browser::OnInstallApplication(TabContents* source,
- const WebApplicationInfo& web_app) {
- ExtensionService* extension_service = profile()->GetExtensionService();
- if (!extension_service)
- return;
-
- scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(
- extension_service,
- extension_service->show_extensions_prompts() ?
- new ExtensionInstallPrompt(this) : NULL));
- installer->InstallWebApp(web_app);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, SelectFileDialog::Listener implementation:
-
-void Browser::FileSelected(const FilePath& path, int index, void* params) {
- profile_->set_last_selected_directory(path.DirName());
- GURL file_url = net::FilePathToFileURL(path);
-
-#if defined(OS_CHROMEOS)
- gdata::util::ModifyGDataFileResourceUrl(profile_, path, &file_url);
-#endif
-
- if (file_url.is_empty())
- return;
-
- OpenURL(OpenURLParams(
- file_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED,
- false));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, content::NotificationObserver implementation:
-
-void Browser::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
+void BrowserCommandController::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
switch (type) {
- case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
- if (is_attempting_to_close_browser_) {
- // Pass in false so that we delay processing. We need to delay the
- // processing as it may close the tab, which is currently on the call
- // stack above us.
- ClearUnloadState(content::Source<WebContents>(source).ptr(), false);
- }
- break;
-
- case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
- // When the current tab's SSL state changes, we need to update the URL
- // bar to reflect the new state. Note that it's possible for the selected
- // tab contents to be NULL. This is because we listen for all sources
- // (NavigationControllers) for convenience, so the notification could
- // actually be for a different window while we're doing asynchronous
- // closing of this one.
- if (GetActiveWebContents() &&
- &GetActiveWebContents()->GetController() ==
- content::Source<NavigationController>(source).ptr())
- UpdateToolbar(false);
- break;
-
- case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
- if (window()->GetLocationBar())
- window()->GetLocationBar()->UpdatePageActions();
-
- // Close any tabs from the unloaded extension, unless it's terminated,
- // in which case let the sad tabs remain.
- if (content::Details<extensions::UnloadedExtensionInfo>(
- details)->reason != extension_misc::UNLOAD_REASON_TERMINATE) {
- const Extension* extension =
- content::Details<extensions::UnloadedExtensionInfo>(
- details)->extension;
- for (int i = tab_strip_model_->count() - 1; i >= 0; --i) {
- WebContents* tc =
- tab_strip_model_->GetTabContentsAt(i)->web_contents();
- bool close_tab_contents =
- tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
- tc->GetURL().host() == extension->id();
- // We want to close all panels originated by the unloaded extension.
- close_tab_contents = close_tab_contents ||
- (type_ == TYPE_PANEL &&
- (web_app::GetExtensionIdFromApplicationName(app_name_) ==
- extension->id()));
- if (close_tab_contents) {
- CloseTabContents(tc);
- }
- }
- }
- break;
- }
-
- case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
- Profile* profile = content::Source<Profile>(source).ptr();
- if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
- window()->GetLocationBar()->InvalidatePageActions();
- break;
- }
-
- case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
- case chrome::NOTIFICATION_EXTENSION_LOADED:
- // During window creation on Windows we may end up calling into
- // SHAppBarMessage, which internally spawns a nested message loop. This
- // makes it possible for us to end up here before window creation has
- // completed,at which point window_ is NULL. See 94752 for details.
- if (window() && window()->GetLocationBar())
- window()->GetLocationBar()->UpdatePageActions();
- break;
-
-#if defined(ENABLE_THEMES)
- case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
- window()->UserChangedTheme();
- break;
-#endif
-
- case chrome::NOTIFICATION_PREF_CHANGED: {
+ case NOTIFICATION_PREF_CHANGED: {
const std::string& pref_name =
*content::Details<std::string>(details).ptr();
if (pref_name == prefs::kPrintingEnabled) {
- UpdatePrintingState(GetContentRestrictionsForSelectedTab());
- } else if (pref_name == prefs::kInstantEnabled) {
- if (browser_shutdown::ShuttingDownWithoutClosingBrowsers() ||
- !InstantController::IsEnabled(profile())) {
- if (instant()) {
- instant()->DestroyPreviewContents();
- instant_.reset();
- instant_unload_handler_.reset();
- }
- } else {
- CreateInstantIfNecessary();
- }
+ UpdatePrintingState();
} else if (pref_name == prefs::kIncognitoModeAvailability) {
UpdateCommandsForIncognitoAvailability();
} else if (pref_name == prefs::kDevToolsDisabled) {
UpdateCommandsForDevTools();
- if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
- content::DevToolsManager::GetInstance()->CloseAllClientHosts();
} else if (pref_name == prefs::kEditBookmarksEnabled) {
UpdateCommandsForBookmarkEditing();
} else if (pref_name == prefs::kShowBookmarkBar) {
UpdateCommandsForBookmarkBar();
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
- } else if (pref_name == prefs::kHomePage) {
- PrefService* pref_service = content::Source<PrefService>(source).ptr();
- MarkHomePageAsChanged(pref_service);
} else if (pref_name == prefs::kAllowFileSelectionDialogs) {
- UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
+ UpdateSaveAsState();
UpdateOpenFileState();
} else if (pref_name == prefs::kInManagedMode) {
UpdateCommandsForMultipleProfiles();
@@ -2858,24 +598,11 @@
}
break;
}
-
- case chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED: {
- WebContents* web_contents = content::Source<WebContents>(source).ptr();
- if (web_contents == GetActiveWebContents()) {
- LocationBar* location_bar = window()->GetLocationBar();
- if (location_bar)
- location_bar->UpdateContentSettingsIcons();
- }
- break;
- }
-
case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
UpdateCommandsForTabState();
break;
case content::NOTIFICATION_INTERSTITIAL_DETACHED:
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
UpdateCommandsForTabState();
break;
@@ -2884,88 +611,67 @@
}
}
-///////////////////////////////////////////////////////////////////////////////
-// Browser, ProfileSyncServiceObserver implementation:
+////////////////////////////////////////////////////////////////////////////////
+// BrowserCommandController, TabStripModelObserver implementation:
-void Browser::OnStateChanged() {
- DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
- profile_));
- // For unit tests, we don't have a window.
- if (!window_)
- return;
- const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen());
- command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
- show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
+void BrowserCommandController::TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground) {
+ AddInterstitialObservers(contents);
}
-///////////////////////////////////////////////////////////////////////////////
-// Browser, InstantDelegate implementation:
-
-void Browser::ShowInstant(TabContents* preview_contents) {
- window_->ShowInstant(preview_contents);
-
- // TODO(beng): investigate if we can avoid this and instead rely on the
- // visibility of the WebContentsView
- GetActiveWebContents()->WasHidden();
- preview_contents->web_contents()->WasRestored();
+void BrowserCommandController::TabDetachedAt(TabContents* contents, int index) {
+ RemoveInterstitialObservers(contents);
}
-void Browser::HideInstant() {
- window_->HideInstant();
- if (GetActiveWebContents())
- GetActiveWebContents()->WasRestored();
- if (instant_->GetPreviewContents())
- instant_->GetPreviewContents()->web_contents()->WasHidden();
+void BrowserCommandController::TabReplacedAt(TabStripModel* tab_strip_model,
+ TabContents* old_contents,
+ TabContents* new_contents,
+ int index) {
+ RemoveInterstitialObservers(old_contents);
+ AddInterstitialObservers(new_contents);
}
-void Browser::CommitInstant(TabContents* preview_contents) {
- TabContents* tab_contents = GetActiveTabContents();
- int index = tab_strip_model_->GetIndexOfTabContents(tab_contents);
- DCHECK_NE(TabStripModel::kNoTab, index);
- // TabStripModel takes ownership of preview_contents.
- tab_strip_model_->ReplaceTabContentsAt(index, preview_contents);
- // InstantUnloadHandler takes ownership of tab_contents.
- instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
+////////////////////////////////////////////////////////////////////////////////
+// BrowserCommandController, TabRestoreServiceObserver implementation:
- GURL url = preview_contents->web_contents()->GetURL();
- DCHECK(profile_->GetExtensionService());
- if (profile_->GetExtensionService()->IsInstalledApp(url)) {
- AppLauncherHandler::RecordAppLaunchType(
- extension_misc::APP_LAUNCH_OMNIBOX_INSTANT);
- }
+void BrowserCommandController::TabRestoreServiceChanged(
+ TabRestoreService* service) {
+ command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
+ CanRestoreTab(browser_));
}
-void Browser::SetSuggestedText(const string16& text,
- InstantCompleteBehavior behavior) {
- if (window()->GetLocationBar())
- window()->GetLocationBar()->SetSuggestedText(text, behavior);
+void BrowserCommandController::TabRestoreServiceDestroyed(
+ TabRestoreService* service) {
+ service->RemoveObserver(this);
}
-gfx::Rect Browser::GetInstantBounds() {
- return window()->GetInstantBounds();
-}
+////////////////////////////////////////////////////////////////////////////////
+// BrowserCommandController, ProfileSyncServiceObserver implementation:
-void Browser::InstantPreviewFocused() {
- // NOTE: This is only invoked on aura.
- window_->WebContentsFocused(instant_->GetPreviewContents()->web_contents());
+void BrowserCommandController::OnStateChanged() {
+ DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
+ profile()));
+ // For unit tests, we don't have a window.
+ if (!window())
+ return;
+ const bool show_main_ui = IsShowingMainUI(window()->IsFullscreen());
+ command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
+ show_main_ui && profile()->GetOriginalProfile()->IsSyncAccessible());
}
-TabContents* Browser::GetInstantHostTabContents() const {
- return GetActiveTabContents();
-}
+////////////////////////////////////////////////////////////////////////////////
+// BrowserCommandController, private:
-///////////////////////////////////////////////////////////////////////////////
-// Browser, Command and state updating (private):
-
-bool Browser::IsShowingMainUI(bool is_fullscreen) {
+bool BrowserCommandController::IsShowingMainUI(bool is_fullscreen) {
#if !defined(OS_MACOSX)
- return is_type_tabbed() && !is_fullscreen;
+ return browser_->is_type_tabbed() && !is_fullscreen;
#else
- return is_type_tabbed();
+ return browser_->is_type_tabbed();
#endif
}
-void Browser::InitCommandState() {
+void BrowserCommandController::InitCommandState() {
// All browser commands whose state isn't set automagically some other way
// (like Back & Forward with initial page load) must have their state
// initialized here, otherwise they will be forever disabled.
@@ -3034,8 +740,7 @@
UpdateOpenFileState();
command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
UpdateCommandsForDevTools();
- command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER,
- chrome::CanOpenTaskManager());
+ command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true);
@@ -3043,10 +748,10 @@
command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
command_updater_.UpdateCommandEnabled(
- IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
+ IDC_SHOW_SYNC_SETUP, profile()->GetOriginalProfile()->IsSyncAccessible());
// Initialize other commands based on the window type.
- bool normal_window = is_type_tabbed();
+ bool normal_window = browser_->is_type_tabbed();
// Navigation commands
command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
@@ -3054,7 +759,7 @@
// Window management commands
// TODO(rohitrao): Disable fullscreen on non-Lion?
command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
- !(is_type_panel() && is_app()));
+ !(browser_->is_type_panel() && browser_->is_app()));
command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
normal_window);
@@ -3077,16 +782,18 @@
#if defined(OS_MACOSX)
command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
- !(is_type_panel() && is_app()));
+ !(browser_->is_type_panel() && browser_->is_app()));
#endif
// Clipboard commands
- command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
+ command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !browser_->is_devtools());
// Find-in-page
- command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
- command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
- command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
+ command_updater_.UpdateCommandEnabled(IDC_FIND, !browser_->is_devtools());
+ command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT,
+ !browser_->is_devtools());
+ command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS,
+ !browser_->is_devtools());
// Show various bits of UI
command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
@@ -3114,9 +821,9 @@
UpdateCommandsForIncognitoAvailability();
}
-void Browser::UpdateCommandsForIncognitoAvailability() {
+void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
IncognitoModePrefs::Availability incognito_availability =
- IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
+ IncognitoModePrefs::GetAvailability(profile()->GetPrefs());
command_updater_.UpdateCommandEnabled(
IDC_NEW_WINDOW,
incognito_availability != IncognitoModePrefs::FORCED);
@@ -3137,48 +844,47 @@
command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
enable_extensions && command_enabled);
- const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
+ const bool show_main_ui =
+ IsShowingMainUI(window() && window()->IsFullscreen());
command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
show_main_ui && command_enabled);
command_updater_.UpdateCommandEnabled(IDC_OPTIONS,
show_main_ui && command_enabled);
}
-void Browser::UpdateCommandsForTabState() {
- TabContents* current_tab_contents = GetActiveTabContents();
+void BrowserCommandController::UpdateCommandsForTabState() {
+ TabContents* current_tab_contents = browser_->GetActiveTabContents();
if (!current_tab_contents) // May be NULL during tab restore.
return;
WebContents* current_web_contents = current_tab_contents->web_contents();
// Navigation commands
- NavigationController& nc = current_web_contents->GetController();
- command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
- command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
- command_updater_.UpdateCommandEnabled(
- IDC_RELOAD, CanReloadContents(current_tab_contents));
- command_updater_.UpdateCommandEnabled(
- IDC_RELOAD_IGNORING_CACHE, CanReloadContents(current_tab_contents));
+ command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_));
+ command_updater_.UpdateCommandEnabled(IDC_FORWARD, CanGoForward(browser_));
+ command_updater_.UpdateCommandEnabled(IDC_RELOAD, CanReload(browser_));
+ command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
+ CanReload(browser_));
// Window management commands
command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
- !is_app() && CanDuplicateContentsAt(active_index()));
+ !browser_->is_app() && CanDuplicateTab(browser_));
// Page-related commands
- window_->SetStarredState(
+ window()->SetStarredState(
current_tab_contents->bookmark_tab_helper()->is_starred());
- window_->SetZoomIconState(
+ window()->SetZoomIconState(
current_tab_contents->zoom_controller()->zoom_icon_state());
- window_->SetZoomIconTooltipPercent(
+ window()->SetZoomIconTooltipPercent(
current_tab_contents->zoom_controller()->zoom_percent());
command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
- current_web_contents->GetController().CanViewSource());
+ CanViewSource(browser_));
command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
- toolbar_model_->ShouldDisplayURL() &&
- current_web_contents->GetURL().is_valid());
- if (is_devtools())
- command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
+ CanEmailPageLocation(browser_));
+ if (browser_->is_devtools())
+ command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
// Changing the encoding is not possible on Chrome-internal webpages.
+ NavigationController& nc = current_web_contents->GetController();
bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
current_web_contents->ShowingInterstitialPage();
command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
@@ -3188,16 +894,17 @@
// TODO(pinkerton): Disable app-mode in the model until we implement it
// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
#if !defined(OS_MACOSX)
- command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
- web_app::IsValidUrl(current_web_contents->GetURL()));
+ command_updater_.UpdateCommandEnabled(
+ IDC_CREATE_SHORTCUTS,
+ CanCreateApplicationShortcuts(browser_));
#endif
UpdateCommandsForContentRestrictionState();
UpdateCommandsForBookmarkEditing();
}
-void Browser::UpdateCommandsForContentRestrictionState() {
- int restrictions = GetContentRestrictionsForSelectedTab();
+void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
+ int restrictions = GetContentRestrictions(browser_);
command_updater_.UpdateCommandEnabled(
IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
@@ -3205,13 +912,13 @@
IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
command_updater_.UpdateCommandEnabled(
IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
- UpdateSaveAsState(restrictions);
- UpdatePrintingState(restrictions);
+ UpdateSaveAsState();
+ UpdatePrintingState();
}
-void Browser::UpdateCommandsForDevTools() {
+void BrowserCommandController::UpdateCommandsForDevTools() {
bool dev_tools_enabled =
- !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
+ !profile()->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
dev_tools_enabled);
command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
@@ -3220,32 +927,26 @@
dev_tools_enabled);
}
-void Browser::UpdateCommandsForBookmarkEditing() {
- bool enabled =
- profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
- browser_defaults::bookmarks_enabled;
-
+void BrowserCommandController::UpdateCommandsForBookmarkEditing() {
command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
- enabled && is_type_tabbed());
+ CanBookmarkCurrentPage(browser_));
command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
- enabled && CanBookmarkAllTabs());
+ CanBookmarkAllTabs(browser_));
command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN,
- true);
+ true);
}
-void Browser::UpdateCommandsForBookmarkBar() {
- const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
+void BrowserCommandController::UpdateCommandsForBookmarkBar() {
+ const bool show_main_ui =
+ IsShowingMainUI(window() && window()->IsFullscreen());
command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
browser_defaults::bookmarks_enabled &&
- !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
+ !profile()->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
show_main_ui);
}
-void Browser::MarkHomePageAsChanged(PrefService* pref_service) {
- pref_service->SetBoolean(prefs::kHomePageChanged, true);
-}
-
-void Browser::UpdateCommandsForFullscreenMode(FullScreenMode fullscreen_mode) {
+void BrowserCommandController::UpdateCommandsForFullscreenMode(
+ FullScreenMode fullscreen_mode) {
const bool show_main_ui =
IsShowingMainUI(fullscreen_mode != FULLSCREEN_DISABLED);
bool main_not_fullscreen = show_main_ui &&
@@ -3255,8 +956,9 @@
command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
// Window management commands
- command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
- type_ != TYPE_TABBED && (fullscreen_mode == FULLSCREEN_DISABLED));
+ command_updater_.UpdateCommandEnabled(
+ IDC_SHOW_AS_TAB,
+ !browser_->is_type_tabbed() && fullscreen_mode == FULLSCREEN_DISABLED);
// Focus various bits of UI
command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
@@ -3275,13 +977,13 @@
command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
- show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
+ show_main_ui && profile()->GetOriginalProfile()->IsSyncAccessible());
// Settings page/subpages are forced to open in normal mode. We disable these
// commands when incognito is forced.
const bool options_enabled = show_main_ui &&
IncognitoModePrefs::GetAvailability(
- profile_->GetPrefs()) != IncognitoModePrefs::FORCED;
+ profile()->GetPrefs()) != IncognitoModePrefs::FORCED;
command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
@@ -3302,60 +1004,25 @@
UpdateCommandsForMultipleProfiles();
}
-void Browser::UpdateCommandsForMultipleProfiles() {
- bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
+void BrowserCommandController::UpdateCommandsForMultipleProfiles() {
+ bool show_main_ui = IsShowingMainUI(window() && window()->IsFullscreen());
command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
show_main_ui &&
!profile()->IsOffTheRecord() &&
ProfileManager::IsMultipleProfilesEnabled());
}
-void Browser::UpdatePrintingState(int content_restrictions) {
- bool print_enabled = true;
- bool advanced_print_enabled = true;
- if (g_browser_process->local_state()) {
- print_enabled =
- g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled);
- advanced_print_enabled = print_enabled;
- }
- if (print_enabled) {
- // Do not print when a constrained window is showing. It's confusing.
- TabContents* tab_contents = GetActiveTabContents();
- bool has_constrained_window =
- tab_contents &&
- tab_contents->constrained_window_tab_helper()->
- constrained_window_count();
- if (has_constrained_window ||
- content_restrictions & content::CONTENT_RESTRICTION_PRINT) {
- print_enabled = false;
- advanced_print_enabled = false;
- }
-
- // The exception is print preview,
- // where advanced printing is always enabled.
- printing::PrintPreviewTabController* controller =
- printing::PrintPreviewTabController::GetInstance();
- if (controller && (controller->GetPrintPreviewForTab(tab_contents) ||
- controller->is_creating_print_preview_tab())) {
- advanced_print_enabled = true;
- }
- }
- command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
+void BrowserCommandController::UpdatePrintingState() {
+ command_updater_.UpdateCommandEnabled(IDC_PRINT, CanPrint(browser_));
command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
- advanced_print_enabled);
+ CanAdvancedPrint(browser_));
}
-void Browser::UpdateSaveAsState(int content_restrictions) {
- bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE);
- enabled = enabled && CanSaveContents(GetActiveTabContents());
- PrefService* state = g_browser_process->local_state();
- if (state)
- enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
-
- command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
+void BrowserCommandController::UpdateSaveAsState() {
+ command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_));
}
-void Browser::UpdateOpenFileState() {
+void BrowserCommandController::UpdateOpenFileState() {
bool enabled = true;
PrefService* local_state = g_browser_process->local_state();
if (local_state)
@@ -3364,545 +1031,33 @@
command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
}
-void Browser::UpdateReloadStopState(bool is_loading, bool force) {
- window_->UpdateReloadStopState(is_loading, force);
+void BrowserCommandController::UpdateReloadStopState(bool is_loading,
+ bool force) {
+ window()->UpdateReloadStopState(is_loading, force);
command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
}
-///////////////////////////////////////////////////////////////////////////////
-// Browser, UI update coalescing and handling (private):
-
-void Browser::UpdateToolbar(bool should_restore_state) {
- window_->UpdateToolbar(GetActiveTabContents(), should_restore_state);
+void BrowserCommandController::AddInterstitialObservers(TabContents* contents) {
+ registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
+ content::Source<WebContents>(contents->web_contents()));
+ registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
+ content::Source<WebContents>(contents->web_contents()));
}
-void Browser::UpdateSearchState(TabContents* contents) {
- if (chrome::search::IsInstantExtendedAPIEnabled(profile_))
- search_delegate_->OnTabActivated(contents);
-}
-
-void Browser::ScheduleUIUpdate(const WebContents* source,
- unsigned changed_flags) {
- if (!source)
- return;
-
- // Do some synchronous updates.
- if (changed_flags & content::INVALIDATE_TYPE_URL &&
- source == GetActiveWebContents()) {
- // Only update the URL for the current tab. Note that we do not update
- // the navigation commands since those would have already been updated
- // synchronously by NavigationStateChanged.
- UpdateToolbar(false);
- changed_flags &= ~content::INVALIDATE_TYPE_URL;
- }
- if (changed_flags & content::INVALIDATE_TYPE_LOAD) {
- // Update the loading state synchronously. This is so the throbber will
- // immediately start/stop, which gives a more snappy feel. We want to do
- // this for any tab so they start & stop quickly.
- tab_strip_model_->UpdateTabContentsStateAt(
- GetIndexOfController(&source->GetController()),
- TabStripModelObserver::LOADING_ONLY);
- // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too,
- // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from
- // changed_flags.
- }
-
- if (changed_flags & content::INVALIDATE_TYPE_TITLE && !source->IsLoading()) {
- // To correctly calculate whether the title changed while not loading
- // we need to process the update synchronously. This state only matters for
- // the TabStripModel, so we notify the TabStripModel now and notify others
- // asynchronously.
- tab_strip_model_->UpdateTabContentsStateAt(
- GetIndexOfController(&source->GetController()),
- TabStripModelObserver::TITLE_NOT_LOADING);
- }
-
- // If the only updates were synchronously handled above, we're done.
- if (changed_flags == 0)
- return;
-
- // Save the dirty bits.
- scheduled_updates_[source] |= changed_flags;
-
- if (!chrome_updater_factory_.HasWeakPtrs()) {
- // No task currently scheduled, start another.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&Browser::ProcessPendingUIUpdates,
- chrome_updater_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(kUIUpdateCoalescingTimeMS));
- }
-}
-
-void Browser::ProcessPendingUIUpdates() {
-#ifndef NDEBUG
- // Validate that all tabs we have pending updates for exist. This is scary
- // because the pending list must be kept in sync with any detached or
- // deleted tabs.
- for (UpdateMap::const_iterator i = scheduled_updates_.begin();
- i != scheduled_updates_.end(); ++i) {
- bool found = false;
- for (int tab = 0; tab < tab_count(); tab++) {
- if (GetWebContentsAt(tab) == i->first) {
- found = true;
- break;
- }
- }
- DCHECK(found);
- }
-#endif
-
- chrome_updater_factory_.InvalidateWeakPtrs();
-
- for (UpdateMap::const_iterator i = scheduled_updates_.begin();
- i != scheduled_updates_.end(); ++i) {
- // Do not dereference |contents|, it may be out-of-date!
- const WebContents* contents = i->first;
- unsigned flags = i->second;
-
- if (contents == GetActiveWebContents()) {
- // Updates that only matter when the tab is selected go here.
-
- if (flags & content::INVALIDATE_TYPE_PAGE_ACTIONS) {
- LocationBar* location_bar = window()->GetLocationBar();
- if (location_bar)
- location_bar->UpdatePageActions();
- }
- // Updating the URL happens synchronously in ScheduleUIUpdate.
- if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) {
- GetStatusBubble()->SetStatus(
- GetActiveTabContents()->
- core_tab_helper()->GetStatusText());
- }
-
- if (flags & (content::INVALIDATE_TYPE_TAB |
- content::INVALIDATE_TYPE_TITLE)) {
-// TODO(pinkerton): Disable app-mode in the model until we implement it
-// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
-#if !defined(OS_MACOSX)
- command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
- web_app::IsValidUrl(contents->GetURL()));
-#endif
- window_->UpdateTitleBar();
- }
- }
-
- // Updates that don't depend upon the selected state go here.
- if (flags &
- (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
- tab_strip_model_->UpdateTabContentsStateAt(
- tab_strip_model_->GetIndexOfWebContents(contents),
- TabStripModelObserver::ALL);
- }
-
- // We don't need to process INVALIDATE_STATE, since that's not visible.
- }
-
- scheduled_updates_.clear();
-}
-
-void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
- if (!contents)
- return;
-
- UpdateMap::iterator i = scheduled_updates_.find(contents);
- if (i != scheduled_updates_.end())
- scheduled_updates_.erase(i);
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, Getters for UI (private):
-
-StatusBubble* Browser::GetStatusBubble() {
-#if !defined(OS_MACOSX)
- // In kiosk mode, we want to always hide the status bubble.
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
- return NULL;
-#endif
- return window_ ? window_->GetStatusBubble() : NULL;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, Session restore functions (private):
-
-void Browser::SyncHistoryWithTabs(int index) {
- SessionService* session_service =
- SessionServiceFactory::GetForProfileIfExisting(profile());
- if (session_service) {
- for (int i = index; i < tab_count(); ++i) {
- TabContents* tab = GetTabContentsAt(i);
- if (tab) {
- session_service->SetTabIndexInWindow(
- session_id(), tab->restore_tab_helper()->session_id(), i);
- session_service->SetPinnedState(
- session_id(),
- tab->restore_tab_helper()->session_id(),
- IsTabPinned(i));
- }
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, OnBeforeUnload handling (private):
-
-void Browser::ProcessPendingTabs() {
- if (!is_attempting_to_close_browser_) {
- // Because we might invoke this after a delay it's possible for the value of
- // is_attempting_to_close_browser_ to have changed since we scheduled the
- // task.
- return;
- }
-
- if (HasCompletedUnloadProcessing()) {
- // We've finished all the unload events and can proceed to close the
- // browser.
- OnWindowClosing();
- return;
- }
-
- // Process beforeunload tabs first. When that queue is empty, process
- // unload tabs.
- if (!tabs_needing_before_unload_fired_.empty()) {
- WebContents* web_contents = *(tabs_needing_before_unload_fired_.begin());
- // Null check render_view_host here as this gets called on a PostTask and
- // the tab's render_view_host may have been nulled out.
- if (web_contents->GetRenderViewHost()) {
- web_contents->GetRenderViewHost()->FirePageBeforeUnload(false);
- } else {
- ClearUnloadState(web_contents, true);
- }
- } else if (!tabs_needing_unload_fired_.empty()) {
- // We've finished firing all beforeunload events and can proceed with unload
- // events.
- // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
- // somewhere around here so that we have accurate measurements of shutdown
- // time.
- // TODO(ojan): We can probably fire all the unload events in parallel and
- // get a perf benefit from that in the cases where the tab hangs in it's
- // unload handler or takes a long time to page in.
- WebContents* web_contents = *(tabs_needing_unload_fired_.begin());
- // Null check render_view_host here as this gets called on a PostTask and
- // the tab's render_view_host may have been nulled out.
- if (web_contents->GetRenderViewHost()) {
- web_contents->GetRenderViewHost()->ClosePage();
- } else {
- ClearUnloadState(web_contents, true);
- }
- } else {
- NOTREACHED();
- }
-}
-
-bool Browser::HasCompletedUnloadProcessing() const {
- return is_attempting_to_close_browser_ &&
- tabs_needing_before_unload_fired_.empty() &&
- tabs_needing_unload_fired_.empty();
-}
-
-void Browser::CancelWindowClose() {
- // Closing of window can be canceled from a beforeunload handler.
- DCHECK(is_attempting_to_close_browser_);
- tabs_needing_before_unload_fired_.clear();
- tabs_needing_unload_fired_.clear();
- is_attempting_to_close_browser_ = false;
-
- content::NotificationService::current()->Notify(
- chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
- content::Source<Browser>(this),
- content::NotificationService::NoDetails());
-}
-
-bool Browser::RemoveFromSet(UnloadListenerSet* set, WebContents* web_contents) {
- DCHECK(is_attempting_to_close_browser_);
-
- UnloadListenerSet::iterator iter =
- std::find(set->begin(), set->end(), web_contents);
- if (iter != set->end()) {
- set->erase(iter);
- return true;
- }
- return false;
-}
-
-void Browser::ClearUnloadState(WebContents* web_contents, bool process_now) {
- if (is_attempting_to_close_browser_) {
- RemoveFromSet(&tabs_needing_before_unload_fired_, web_contents);
- RemoveFromSet(&tabs_needing_unload_fired_, web_contents);
- if (process_now) {
- ProcessPendingTabs();
- } else {
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr()));
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, In-progress download termination handling (private):
-
-bool Browser::CanCloseWithInProgressDownloads() {
- // If we've prompted, we need to hear from the user before we
- // can close.
- if (cancel_download_confirmation_state_ != NOT_PROMPTED)
- return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
-
- int num_downloads_blocking;
- if (DOWNLOAD_CLOSE_OK ==
- OkToCloseWithInProgressDownloads(&num_downloads_blocking))
- return true;
-
- // Closing this window will kill some downloads; prompt to make sure
- // that's ok.
- cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
- window_->ConfirmBrowserCloseWithPendingDownloads();
-
- // Return false so the browser does not close. We'll close if the user
- // confirms in the dialog.
- return false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Browser, Assorted utility functions (private):
-
-void Browser::SetAsDelegate(TabContents* tab, Browser* delegate) {
- // WebContents...
- tab->web_contents()->SetDelegate(delegate);
-
- // ...and all the helpers.
- tab->blocked_content_tab_helper()->set_delegate(delegate);
- tab->bookmark_tab_helper()->set_delegate(delegate);
- tab->zoom_controller()->set_observer(delegate);
- tab->constrained_window_tab_helper()->set_delegate(delegate);
- tab->core_tab_helper()->set_delegate(delegate);
- tab->extension_tab_helper()->set_delegate(delegate);
- tab->search_engine_tab_helper()->set_delegate(delegate);
-}
-
-void Browser::CloseFrame() {
- window_->Close();
-}
-
-void Browser::TabDetachedAtImpl(TabContents* contents, int index,
- DetachType type) {
- if (type == DETACH_TYPE_DETACH) {
- // Save the current location bar state, but only if the tab being detached
- // is the selected tab. Because saving state can conditionally revert the
- // location bar, saving the current tab's location bar state to a
- // non-selected tab can corrupt both tabs.
- if (contents == GetActiveTabContents()) {
- LocationBar* location_bar = window()->GetLocationBar();
- if (location_bar)
- location_bar->SaveStateToContents(contents->web_contents());
- }
-
- if (!tab_strip_model_->closing_all())
- SyncHistoryWithTabs(0);
- }
-
- SetAsDelegate(contents, NULL);
- RemoveScheduledUpdatesFor(contents->web_contents());
-
- if (find_bar_controller_.get() && index == active_index()) {
- find_bar_controller_->ChangeTabContents(NULL);
- }
-
- if (is_attempting_to_close_browser_) {
- // If this is the last tab with unload handlers, then ProcessPendingTabs
- // would call back into the TabStripModel (which is invoking this method on
- // us). Avoid that by passing in false so that the call to
- // ProcessPendingTabs is delayed.
- ClearUnloadState(contents->web_contents(), false);
- }
-
- // Stop observing search model changes for this tab.
- search_delegate_->OnTabDetached(contents);
-
+void BrowserCommandController::RemoveInterstitialObservers(
+ TabContents* contents) {
registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
content::Source<WebContents>(contents->web_contents()));
registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
content::Source<WebContents>(contents->web_contents()));
- registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
- content::Source<WebContents>(contents->web_contents()));
}
-bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
- bool check_fullscreen) const {
- // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
- // other platforms, we hide some controls when in fullscreen mode.
- bool hide_ui_for_fullscreen = false;
-#if !defined(OS_MACOSX)
- hide_ui_for_fullscreen = check_fullscreen && window_ &&
- window_->IsFullscreen();
-#endif
-
- unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF;
-
- if (is_type_tabbed())
- features |= FEATURE_BOOKMARKBAR;
-
- if (!hide_ui_for_fullscreen) {
- if (!is_type_tabbed())
- features |= FEATURE_TITLEBAR;
-
- if (is_type_tabbed())
- features |= FEATURE_TABSTRIP;
-
- if (is_type_tabbed())
- features |= FEATURE_TOOLBAR;
-
- if (!is_app())
- features |= FEATURE_LOCATIONBAR;
- }
- return !!(features & feature);
+BrowserWindow* BrowserCommandController::window() {
+ return browser_->window();
}
-void Browser::CreateInstantIfNecessary() {
- if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
- !profile()->IsOffTheRecord()) {
- instant_.reset(new InstantController(this, InstantController::INSTANT));
- instant_unload_handler_.reset(new InstantUnloadHandler(this));
- }
+Profile* BrowserCommandController::profile() {
+ return browser_->profile();
}
-int Browser::GetContentRestrictionsForSelectedTab() {
- int content_restrictions = 0;
- WebContents* current_tab = GetActiveWebContents();
- if (current_tab) {
- content_restrictions = current_tab->GetContentRestrictions();
- NavigationEntry* active_entry =
- current_tab->GetController().GetActiveEntry();
- // See comment in UpdateCommandsForTabState about why we call url().
- if (!download_util::IsSavableURL(
- active_entry ? active_entry->GetURL() : GURL())
- || current_tab->ShowingInterstitialPage())
- content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
- if (current_tab->ShowingInterstitialPage())
- content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
- }
- return content_restrictions;
-}
-
-void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
- BookmarkBar::State state;
- // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
- if (browser_defaults::bookmarks_enabled &&
- profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
- (!window_ || !window_->IsFullscreen())) {
- state = BookmarkBar::SHOW;
- } else {
- TabContents* tab = GetActiveTabContents();
- if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
- state = BookmarkBar::DETACHED;
- else
- state = BookmarkBar::HIDDEN;
- }
-
- // Only allow the bookmark bar to be shown in default mode.
- if (!search_model_->mode().is_default())
- state = BookmarkBar::HIDDEN;
-
- if (state == bookmark_bar_state_)
- return;
-
- bookmark_bar_state_ = state;
-
- if (!window_)
- return; // This is called from the constructor when window_ is NULL.
-
- if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
- // Don't notify BrowserWindow on a tab switch as at the time this is invoked
- // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
- // end up querying state once they process the tab switch.
- return;
- }
-
- BookmarkBar::AnimateChangeType animate_type =
- (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
- BookmarkBar::ANIMATE_STATE_CHANGE :
- BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
- window_->BookmarkBarStateChanged(animate_type);
-}
-
-bool Browser::MaybeCreateBackgroundContents(int route_id,
- WebContents* opener_web_contents,
- const string16& frame_name,
- const GURL& target_url) {
- GURL opener_url = opener_web_contents->GetURL();
- ExtensionService* extensions_service = profile_->GetExtensionService();
-
- if (!opener_url.is_valid() ||
- frame_name.empty() ||
- !extensions_service ||
- !extensions_service->is_ready())
- return false;
-
- // Only hosted apps have web extents, so this ensures that only hosted apps
- // can create BackgroundContents. We don't have to check for background
- // permission as that is checked in RenderMessageFilter when the CreateWindow
- // message is processed.
- const Extension* extension =
- extensions_service->extensions()->GetHostedAppByURL(
- ExtensionURLInfo(opener_url));
- if (!extension)
- return false;
-
- // No BackgroundContents allowed if BackgroundContentsService doesn't exist.
- BackgroundContentsService* service =
- BackgroundContentsServiceFactory::GetForProfile(profile_);
- if (!service)
- return false;
-
- // Ensure that we're trying to open this from the extension's process.
- SiteInstance* opener_site_instance = opener_web_contents->GetSiteInstance();
- extensions::ProcessMap* process_map = extensions_service->process_map();
- if (!opener_site_instance->GetProcess() ||
- !process_map->Contains(
- extension->id(), opener_site_instance->GetProcess()->GetID())) {
- return false;
- }
-
- // Only allow a single background contents per app.
- bool allow_js_access = extension->allow_background_js_access();
- BackgroundContents* existing =
- service->GetAppBackgroundContents(ASCIIToUTF16(extension->id()));
- if (existing) {
- // For non-scriptable background contents, ignore the request altogether,
- // (returning true, so that a regular WebContents isn't created either).
- if (!allow_js_access)
- return true;
- // For scriptable background pages, if one already exists, close it (even
- // if it was specified in the manifest).
- DLOG(INFO) << "Closing existing BackgroundContents for " << opener_url;
- delete existing;
- }
-
- // If script access is not allowed, create the the background contents in a
- // new SiteInstance, so that a separate process is used.
- scoped_refptr<content::SiteInstance> site_instance =
- allow_js_access ?
- opener_site_instance :
- content::SiteInstance::Create(opener_web_contents->GetBrowserContext());
-
- // Passed all the checks, so this should be created as a BackgroundContents.
- BackgroundContents* contents = service->CreateBackgroundContents(
- site_instance,
- route_id,
- profile_,
- frame_name,
- ASCIIToUTF16(extension->id()));
-
- // When a separate process is used, the original renderer cannot access the
- // new window later, thus we need to navigate the window now.
- if (contents && !allow_js_access) {
- contents->web_contents()->GetController().LoadURL(
- target_url,
- content::Referrer(),
- content::PAGE_TRANSITION_LINK,
- std::string()); // No extra headers.
- }
-
- return contents != NULL;
-}
+} // namespace chrome
« no previous file with comments | « chrome/browser/ui/browser_command_controller.h ('k') | chrome/browser/ui/browser_commands.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698