blob: 4e546fa7eee67b9cf2b40743313df3541701b364 [file] [log] [blame]
[email protected]daa9e382012-01-06 00:30:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]7b5dc002010-11-16 23:08:105#include "chrome/browser/ui/browser.h"
[email protected]c61db1d2009-02-06 03:39:186
[email protected]aca02cf2010-05-03 18:56:017#if defined(OS_WIN)
[email protected]541434c2011-06-25 01:38:598#include <windows.h>
[email protected]dcd57762011-06-25 12:18:519#include <shellapi.h>
[email protected]aca02cf2010-05-03 18:56:0110#endif // OS_WIN
11
[email protected]5dcbc02f2010-01-26 22:32:0612#include <algorithm>
13#include <string>
14
[email protected]b02d0382009-11-30 21:19:5015#include "base/base_paths.h"
[email protected]24f1477532011-11-22 22:55:3616#include "base/bind.h"
[email protected]8a53ee042009-01-21 16:41:3317#include "base/command_line.h"
[email protected]8a53ee042009-01-21 16:41:3318#include "base/logging.h"
[email protected]49098f702011-10-13 03:47:1819#include "base/metrics/field_trial.h"
[email protected]835d7c82010-10-14 04:38:3820#include "base/metrics/histogram.h"
[email protected]b02d0382009-11-30 21:19:5021#include "base/path_service.h"
[email protected]0af8f132011-07-16 01:37:0222#include "base/string_number_conversions.h"
[email protected]b6a4ac2b2011-10-17 20:05:4823#include "base/string_util.h"
[email protected]5a17d492011-10-24 19:37:0324#include "base/stringprintf.h"
[email protected]34b99632011-01-01 01:01:0625#include "base/threading/thread.h"
26#include "base/threading/thread_restrictions.h"
[email protected]7f070d42011-03-09 20:25:3227#include "base/time.h"
[email protected]6524385ef2010-08-18 06:34:1328#include "base/utf_string_conversions.h"
[email protected]1a3aba82010-11-08 23:52:5429#include "chrome/app/chrome_command_ids.h"
[email protected]ea9edcb02011-09-23 22:05:0430#include "chrome/browser/autofill/personal_data_manager_factory.h"
[email protected]a07676b22011-06-17 16:36:5331#include "chrome/browser/background/background_contents_service.h"
[email protected]4fdf6742012-01-10 20:14:3632#include "chrome/browser/background/background_contents_service_factory.h"
[email protected]a9afddb2009-02-12 17:49:4233#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5434#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]5c238752009-06-13 10:29:0735#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1836#include "chrome/browser/browser_shutdown.h"
[email protected]40d59ce52009-03-06 23:20:1437#include "chrome/browser/character_encoding.h"
[email protected]0f083402011-11-22 02:59:0138#include "chrome/browser/chrome_page_zoom.h"
[email protected]55c87fa2011-10-15 07:28:2839#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]7d189022011-08-25 22:54:2040#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
41#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
[email protected]dce502762011-07-20 08:53:4942#include "chrome/browser/debugger/devtools_toggle_action.h"
43#include "chrome/browser/debugger/devtools_window.h"
[email protected]8a282712011-08-23 19:28:0044#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]59560e0b2009-06-04 03:30:2245#include "chrome/browser/download/download_item_model.h"
[email protected]9bb54ee2011-10-12 17:43:3546#include "chrome/browser/download/download_service.h"
47#include "chrome/browser/download/download_service_factory.h"
[email protected]59560e0b2009-06-04 03:30:2248#include "chrome/browser/download/download_started_animation.h"
[email protected]a53209b2012-01-20 16:48:1649#include "chrome/browser/download/download_util.h"
[email protected]bb461532010-11-26 21:50:2350#include "chrome/browser/extensions/crx_installer.h"
[email protected]49098f702011-10-13 03:47:1851#include "chrome/browser/extensions/default_apps_trial.h"
[email protected]41d9faf2012-02-28 23:46:0252#include "chrome/browser/extensions/browser_extension_window_controller.h"
[email protected]9fd542df2009-09-30 07:32:0153#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]0c6da502009-08-14 22:32:3954#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
[email protected]10abd192010-09-30 02:03:4955#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0056#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0857#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5958#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0459#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]3a29a6e2011-08-24 18:26:2160#include "chrome/browser/file_select_helper.h"
[email protected]820735792010-07-29 23:40:0161#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4962#include "chrome/browser/google/google_url_tracker.h"
[email protected]7e204122011-09-01 18:56:2163#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]6b723f82010-10-05 20:14:2764#include "chrome/browser/instant/instant_controller.h"
[email protected]5aab5e22010-12-08 22:13:2965#include "chrome/browser/instant/instant_unload_handler.h"
[email protected]7d189022011-08-25 22:54:2066#include "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
[email protected]95a33ed62011-09-30 15:07:0867#include "chrome/browser/intents/web_intents_registry_factory.h"
[email protected]8f0bbd62012-02-22 03:37:1868#include "chrome/browser/intents/web_intents_util.h"
[email protected]90f39902009-10-03 04:25:3769#include "chrome/browser/net/browser_url_util.h"
[email protected]a239c3f2009-02-17 22:13:1970#include "chrome/browser/net/url_fixer_upper.h"
[email protected]2c4fb7b2011-04-02 06:33:2971#include "chrome/browser/notifications/notification_ui_manager.h"
[email protected]14a000d2010-04-29 21:44:2472#include "chrome/browser/platform_util.h"
[email protected]4e94ab32011-08-05 05:28:2773#include "chrome/browser/prefs/incognito_mode_prefs.h"
[email protected]37858e52010-08-26 00:22:0274#include "chrome/browser/prefs/pref_service.h"
[email protected]4fdf6742012-01-10 20:14:3675#include "chrome/browser/prerender/prerender_manager.h"
76#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]d952a052011-09-06 18:42:4577#include "chrome/browser/prerender/prerender_tab_helper.h"
[email protected]02337592010-09-27 18:38:2578#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]0996e9b2011-08-26 17:59:0179#include "chrome/browser/printing/print_preview_tab_controller.h"
[email protected]68761472011-08-31 18:55:1480#include "chrome/browser/printing/print_view_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3381#include "chrome/browser/profiles/profile.h"
[email protected]5e919242012-02-13 23:59:3582#include "chrome/browser/profiles/profile_destroyer.h"
[email protected]5a17d492011-10-24 19:37:0383#include "chrome/browser/profiles/profile_manager.h"
[email protected]a7be6982011-12-12 21:53:5784#include "chrome/browser/profiles/profile_metrics.h"
[email protected]67baffc82011-12-19 18:03:0785#include "chrome/browser/repost_form_warning_controller.h"
[email protected]81898992011-06-14 22:15:0086#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4487#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1588#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1889#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0690#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1591#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1392#include "chrome/browser/sync/profile_sync_service.h"
[email protected]5e61afb92012-01-27 20:09:1393#include "chrome/browser/sync/profile_sync_service_factory.h"
[email protected]40f047972009-11-25 03:54:4094#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0495#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2996#include "chrome/browser/tab_contents/background_contents.h"
[email protected]4fdf6742012-01-10 20:14:3697#include "chrome/browser/tab_contents/retargeting_details.h"
[email protected]7cceebac2011-03-03 00:32:2198#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]1ab4ddf2011-07-21 04:48:0499#include "chrome/browser/tab_contents/tab_util.h"
[email protected]07d490bc2011-03-07 17:05:26100#include "chrome/browser/tabs/tab_finder.h"
[email protected]c848d3d92010-09-16 21:57:45101#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]ffa6f592011-06-24 22:03:57102#include "chrome/browser/themes/theme_service.h"
103#include "chrome/browser/themes/theme_service_factory.h"
[email protected]3ab9cb82011-06-03 18:02:07104#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:37105#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:14106#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]55452902011-06-01 21:57:47107#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:04108#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:37109#include "chrome/browser/ui/browser_navigator.h"
[email protected]fb7da4132011-03-15 15:51:00110#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]00070c732011-04-09 15:31:33111#include "chrome/browser/ui/browser_window.h"
[email protected]31145092011-09-30 01:49:44112#include "chrome/browser/ui/constrained_window_tab_helper.h"
[email protected]a44657202012-01-09 05:48:31113#include "chrome/browser/ui/extensions/shell_window.h"
[email protected]45300ad42010-12-02 15:51:14114#include "chrome/browser/ui/find_bar/find_bar.h"
115#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:38116#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]bf8708692011-12-20 21:24:28117#include "chrome/browser/ui/fullscreen_controller.h"
[email protected]2f516c792011-09-19 22:22:09118#include "chrome/browser/ui/global_error.h"
119#include "chrome/browser/ui/global_error_service.h"
120#include "chrome/browser/ui/global_error_service_factory.h"
[email protected]943b8612011-08-31 21:07:13121#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
[email protected]6a3ec2312010-12-02 19:30:19122#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:43123#include "chrome/browser/ui/panels/panel.h"
124#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:12125#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19126#include "chrome/browser/ui/status_bubble.h"
[email protected]3da95a102011-11-30 21:47:45127#include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
[email protected]51d83bdf2011-12-09 16:09:29128#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19129#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:44130#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:19131#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]f847e6082011-03-24 00:08:26132#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]daa9e382012-01-06 00:30:34133#include "chrome/browser/ui/webui/feedback_ui.h"
[email protected]6a1622a2011-09-20 22:37:45134#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
[email protected]5c557f372011-02-26 15:09:20135#include "chrome/browser/ui/webui/options/content_settings_handler.h"
[email protected]65549182012-02-25 00:45:40136#include "chrome/browser/ui/webui/signin/login_ui_service.h"
137#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
[email protected]aff3de22012-02-13 22:58:06138#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h"
[email protected]9a800652010-12-02 17:08:44139#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54140#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50141#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33142#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:27143#include "chrome/common/chrome_notification_types.h"
[email protected]d938aed92009-01-22 19:49:33144#include "chrome/common/chrome_switches.h"
[email protected]7d189022011-08-25 22:54:20145#include "chrome/common/custom_handlers/protocol_handler.h"
[email protected]5b1a0e22009-05-26 19:00:58146#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33147#include "chrome/common/extensions/extension_constants.h"
[email protected]8a53ee042009-01-21 16:41:33148#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25149#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34150#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23151#include "chrome/common/web_apps.h"
[email protected]b8148ac2011-07-13 22:03:25152#include "content/browser/browser_url_handler.h"
[email protected]a01efd22011-03-01 00:38:32153#include "content/browser/renderer_host/render_view_host.h"
[email protected]0e12d7d2011-12-01 16:21:44154#include "content/public/browser/devtools_manager.h"
[email protected]e582fdd2011-12-20 16:48:17155#include "content/public/browser/download_item.h"
156#include "content/public/browser/download_manager.h"
[email protected]cadaec52012-02-08 21:53:13157#include "content/public/browser/interstitial_page.h"
[email protected]d9083482012-01-06 00:38:46158#include "content/public/browser/invalidate_type.h"
[email protected]cdcb1dee2012-01-04 00:46:20159#include "content/public/browser/navigation_controller.h"
[email protected]022af742011-12-28 18:37:25160#include "content/public/browser/navigation_entry.h"
[email protected]7f6f44c2011-12-14 13:23:38161#include "content/public/browser/notification_details.h"
162#include "content/public/browser/notification_service.h"
[email protected]3a5180ae2011-12-21 02:39:38163#include "content/public/browser/plugin_service.h"
[email protected]b6583592012-01-25 19:52:33164#include "content/public/browser/site_instance.h"
[email protected]7f6f44c2011-12-14 13:23:38165#include "content/public/browser/user_metrics.h"
[email protected]d9083482012-01-06 00:38:46166#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:10167#include "content/public/browser/web_contents_view.h"
[email protected]0d9989d2011-12-21 20:26:00168#include "content/public/browser/web_intents_dispatcher.h"
[email protected]4573fbd2011-10-31 20:25:18169#include "content/public/common/content_restriction.h"
[email protected]c08950d22011-10-13 22:20:29170#include "content/public/common/content_switches.h"
[email protected]0f083402011-11-22 02:59:01171#include "content/public/common/page_zoom.h"
[email protected]cadaec52012-02-08 21:53:13172#include "content/public/common/renderer_preferences.h"
[email protected]a3e18c42009-03-04 23:36:05173#include "grit/chromium_strings.h"
174#include "grit/generated_resources.h"
175#include "grit/locale_settings.h"
[email protected]d952a052011-09-06 18:42:45176#include "grit/theme_resources_standard.h"
[email protected]8a53ee042009-01-21 16:41:33177#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33178#include "net/base/net_util.h"
179#include "net/base/registry_controlled_domain.h"
180#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39181#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17182#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38183#include "ui/gfx/point.h"
[email protected]ce9751942011-09-21 01:57:24184#include "webkit/glue/web_intent_data.h"
[email protected]4a19be92011-09-22 14:25:02185#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33186#include "webkit/glue/window_open_disposition.h"
[email protected]3a5180ae2011-12-21 02:39:38187#include "webkit/plugins/webplugininfo.h"
[email protected]8a53ee042009-01-21 16:41:33188
189#if defined(OS_WIN)
[email protected]36d5e5592010-11-15 20:45:59190#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15191#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59192#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12193#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19194#include "chrome/browser/ui/view_ids.h"
195#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]dcd57762011-06-25 12:18:51196#include "ui/base/win/shell.h"
[email protected]8a53ee042009-01-21 16:41:33197#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33198
[email protected]6a4f5af22009-09-23 22:43:00199#if defined(OS_MACOSX)
[email protected]8aee8ed32011-06-14 20:16:41200#include "content/browser/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00201#endif
202
[email protected]b7969202010-05-14 21:29:26203#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35204#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]2166c432011-12-07 20:18:28205#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
206#include "chrome/browser/chromeos/dbus/power_manager_client.h"
[email protected]598e6c212012-02-01 04:57:56207#if defined(USE_AURA)
208#include "chrome/browser/extensions/api/terminal/terminal_extension_helper.h"
209#endif
[email protected]efda32f92011-07-06 22:47:04210#include "chrome/browser/ui/webui/active_downloads_ui.h"
[email protected]eab8c0f2011-11-18 22:33:50211#endif
212
[email protected]c2f0a892012-01-24 22:19:21213#if defined(USE_AURA)
[email protected]bafda132012-02-16 19:32:51214#include "ash/ash_switches.h"
[email protected]c2f0a892012-01-24 22:19:21215#include "ash/shell.h"
[email protected]bafda132012-02-16 19:32:51216#include "chrome/browser/ui/views/aura/panel_view_aura.h"
[email protected]c2f0a892012-01-24 22:19:21217#endif
218
[email protected]eab8c0f2011-11-18 22:33:50219#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]efda32f92011-07-06 22:47:04220#include "chrome/browser/download/download_shelf.h"
[email protected]b7969202010-05-14 21:29:26221#endif
222
[email protected]cb6dbc52011-08-10 17:34:39223#if defined(FILE_MANAGER_EXTENSION)
[email protected]7df1dad2012-02-27 11:19:51224#include "chrome/browser/chromeos/extensions/file_manager_util.h"
[email protected]cb6dbc52011-08-10 17:34:39225#endif
226
[email protected]8a53ee042009-01-21 16:41:33227using base::TimeDelta;
[email protected]c5eed492012-01-04 17:07:50228using content::NavigationController;
[email protected]10f417c52011-12-28 21:04:23229using content::NavigationEntry;
[email protected]e5d549d2011-12-28 01:29:20230using content::OpenURLParams;
[email protected]3a5180ae2011-12-21 02:39:38231using content::PluginService;
[email protected]e5d549d2011-12-28 01:29:20232using content::Referrer;
[email protected]b6583592012-01-25 19:52:33233using content::SiteInstance;
[email protected]d583e3f22011-12-27 21:38:17234using content::SSLStatus;
[email protected]7f6f44c2011-12-14 13:23:38235using content::UserMetricsAction;
[email protected]ea049a02011-12-25 21:37:09236using content::WebContents;
initial.commit09911bf2008-07-26 23:55:29237
[email protected]36b6dcb2008-11-12 01:19:57238///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29239
[email protected]505323e22009-01-24 02:47:58240namespace {
241
[email protected]91a79232010-11-10 18:15:08242// The URL to be loaded to display the "Report a broken page" form.
243const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20244 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08245 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
246
247// The URL for the privacy dashboard.
248const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
249
250// How long we wait before updating the browser chrome while loading a page.
251const int kUIUpdateCoalescingTimeMS = 200;
252
253const char kHashMark[] = "#";
254
[email protected]50dc3deb2011-07-07 01:07:19255// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
[email protected]10f417c52011-12-28 21:04:23256bool HasInternalURL(const NavigationEntry* entry) {
[email protected]50dc3deb2011-07-07 01:07:19257 if (!entry)
258 return false;
259
260 // Check the |virtual_url()| first. This catches regular chrome:// URLs
261 // including URLs that were rewritten (such as chrome://bookmarks).
[email protected]36fc0392011-12-25 03:59:51262 if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme))
[email protected]50dc3deb2011-07-07 01:07:19263 return true;
264
265 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
266 // view-source: of a chrome:// URL.
[email protected]36fc0392011-12-25 03:59:51267 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme))
268 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme);
[email protected]50dc3deb2011-07-07 01:07:19269
270 return false;
271}
272
[email protected]b6cb7702011-11-15 05:33:11273// Get the launch URL for a given extension, with optional override/fallback.
274// |override_url|, if non-empty, will be preferred over the extension's
275// launch url.
276GURL UrlForExtension(const Extension* extension, const GURL& override_url) {
277 if (!extension)
278 return override_url;
279
280 GURL url;
281 if (!override_url.is_empty()) {
282 DCHECK(extension->web_extent().MatchesURL(override_url));
283 url = override_url;
284 } else {
285 url = extension->GetFullLaunchURL();
286 }
287
288 // For extensions lacking launch urls, determine a reasonable fallback.
289 if (!url.is_valid()) {
290 url = extension->options_url();
291 if (!url.is_valid()) {
292 url = GURL(std::string(chrome::kChromeUISettingsURL) +
293 chrome::kExtensionsSubPage);
294 }
295 }
296
297 return url;
298}
299
[email protected]113baf92012-02-14 02:21:06300// Parse two comma-separated integers from str. Return true on success.
301bool ParseCommaSeparatedIntegers(const std::string& str,
302 int* ret_num1,
303 int* ret_num2) {
304 size_t num1_size = str.find_first_of(',');
305 if (num1_size == std::string::npos)
306 return false;
307
308 size_t num2_pos = num1_size + 1;
309 size_t num2_size = str.size() - num2_pos;
310 int num1, num2;
311 if (!base::StringToInt(str.substr(0, num1_size), &num1) ||
312 !base::StringToInt(str.substr(num2_pos, num2_size), &num2))
313 return false;
314
315 *ret_num1 = num1;
316 *ret_num2 = num2;
317 return true;
318}
319
[email protected]505323e22009-01-24 02:47:58320} // namespace
321
[email protected]b35b26b32011-05-05 20:35:14322////////////////////////////////////////////////////////////////////////////////
323// Browser, CreateParams:
324
325Browser::CreateParams::CreateParams(Type type, Profile* profile)
326 : type(type),
[email protected]a636d8e52012-02-28 15:40:41327 profile(profile),
328 initial_show_state(ui::SHOW_STATE_DEFAULT),
329 is_session_restore(false) {
[email protected]b35b26b32011-05-05 20:35:14330}
331
[email protected]36b6dcb2008-11-12 01:19:57332///////////////////////////////////////////////////////////////////////////////
333// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29334
[email protected]299dabd2008-11-19 02:27:16335Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05336 : type_(type),
337 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39338 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40339 ALLOW_THIS_IN_INITIALIZER_LIST(
340 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14341 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29342 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05343 chrome_updater_factory_(this),
344 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06345 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]400eaf82011-08-22 15:47:39346 show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]8bc061f2011-08-31 22:46:23347 is_session_restore_(false),
[email protected]24f1477532011-11-22 22:55:36348 weak_factory_(this),
[email protected]867125a02009-12-10 06:01:48349 block_command_execution_(false),
350 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51351 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00352 pending_web_app_action_(NONE),
353 ALLOW_THIS_IN_INITIALIZER_LIST(
354 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48355 new BrowserTabRestoreServiceDelegate(this))),
[email protected]afefa74e2011-07-26 05:04:23356 ALLOW_THIS_IN_INITIALIZER_LIST(
357 synced_window_delegate_(
358 new BrowserSyncedWindowDelegate(this))),
[email protected]8a5e0ca2011-08-25 06:30:47359 bookmark_bar_state_(BookmarkBar::HIDDEN),
[email protected]2f516c792011-09-19 22:22:09360 window_has_shown_(false) {
[email protected]432115822011-07-10 15:52:27361 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
[email protected]ad50def52011-10-19 23:17:07362 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27363 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
[email protected]a93089b12011-11-22 20:47:38364 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27365 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]a93089b12011-11-22 20:47:38366 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27367 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]a93089b12011-11-22 20:47:38368 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27369 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
[email protected]a93089b12011-11-22 20:47:38370 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27371 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
[email protected]ad50def52011-10-19 23:17:07372 content::NotificationService::AllSources());
[email protected]ffa6f592011-06-24 22:03:57373 registrar_.Add(
[email protected]432115822011-07-10 15:52:27374 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
[email protected]6c2381d2011-10-19 02:52:53375 content::Source<ThemeService>(
376 ThemeServiceFactory::GetForProfile(profile_)));
[email protected]ea049a02011-12-25 21:37:09377 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
[email protected]ad50def52011-10-19 23:17:07378 content::NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29379
[email protected]9e823662010-10-13 23:36:00380 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04381 if (local_state) {
382 local_pref_registrar_.Init(local_state);
383 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
384 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
[email protected]3819f2ee2011-08-21 09:44:38385 local_pref_registrar_.Add(prefs::kMetricsReportingEnabled, this);
[email protected]97b46382011-05-02 13:23:04386 }
387
388 profile_pref_registrar_.Init(profile_->GetPrefs());
389 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
390 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
[email protected]3710d0002011-10-11 00:35:00391 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this);
[email protected]6c6b02d2011-09-02 03:36:47392 profile_pref_registrar_.Add(prefs::kHomePage, this);
[email protected]97b46382011-05-02 13:23:04393 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]4e94ab32011-08-05 05:28:27394 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
[email protected]3819f2ee2011-08-21 09:44:38395 profile_pref_registrar_.Add(prefs::kSearchSuggestEnabled, this);
[email protected]9e823662010-10-13 23:36:00396
initial.commit09911bf2008-07-26 23:55:29397 InitCommandState();
398 BrowserList::AddBrowser(this);
399
[email protected]97b46382011-05-02 13:23:04400 // NOTE: These prefs all need to be explicitly destroyed in the destructor
401 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29402 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
403 profile_->GetPrefs(), NULL);
[email protected]281918912010-05-27 22:05:13404
[email protected]92371eb2011-04-28 11:50:15405 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13406 if (tab_restore_service_) {
407 tab_restore_service_->AddObserver(this);
408 TabRestoreServiceChanged(tab_restore_service_);
409 }
[email protected]d3b98c82010-07-14 07:45:59410
[email protected]5e61afb92012-01-27 20:09:13411 ProfileSyncService* service =
412 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
413 if (service)
414 service->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30415
[email protected]2031cf9d2010-10-12 05:05:37416 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26417
418 // Make sure TabFinder has been created. This does nothing if TabFinder is
419 // not enabled.
420 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48421
422 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
[email protected]a7be6982011-12-12 21:53:57423
424 FilePath profile_path = profile->GetPath();
425 ProfileMetrics::LogProfileLaunch(profile_path);
initial.commit09911bf2008-07-26 23:55:29426}
427
428Browser::~Browser() {
[email protected]5e61afb92012-01-27 20:09:13429 ProfileSyncService* service =
430 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
431 if (service)
432 service->RemoveObserver(this);
[email protected]d3b98c82010-07-14 07:45:59433
initial.commit09911bf2008-07-26 23:55:29434 BrowserList::RemoveBrowser(this);
435
[email protected]7be64502011-05-03 17:51:47436#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29437 if (!BrowserList::HasBrowserWithProfile(profile_)) {
438 // We're the last browser window with this profile. We need to nuke the
439 // TabRestoreService, which will start the shutdown of the
440 // NavigationControllers and allow for proper shutdown. If we don't do this
441 // chrome won't shutdown cleanly, and may end up crashing when some
442 // thread tries to use the IO thread (or another thread) that is no longer
443 // valid.
[email protected]fbc947b2009-06-19 13:28:24444 // This isn't a valid assumption for Mac OS, as it stays running after
445 // the last browser has closed. The Mac equivalent is in its app
446 // controller.
[email protected]92371eb2011-04-28 11:50:15447 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29448 }
[email protected]fbc947b2009-06-19 13:28:24449#endif
initial.commit09911bf2008-07-26 23:55:29450
[email protected]92371eb2011-04-28 11:50:15451 SessionService* session_service =
452 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29453 if (session_service)
454 session_service->WindowClosed(session_id_);
455
[email protected]92371eb2011-04-28 11:50:15456 TabRestoreService* tab_restore_service =
457 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]d8375fd2008-11-25 22:45:39458 if (tab_restore_service)
[email protected]fb7da4132011-03-15 15:51:00459 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39460
[email protected]97b46382011-05-02 13:23:04461 profile_pref_registrar_.RemoveAll();
462 local_pref_registrar_.RemoveAll();
463
[email protected]9a8c4022011-01-25 14:25:33464 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33465
initial.commit09911bf2008-07-26 23:55:29466 if (profile_->IsOffTheRecord() &&
[email protected]474e5db2011-08-12 13:02:23467 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
[email protected]5e919242012-02-13 23:59:35468 // An incognito profile is no longer needed, this indirectly frees
469 // its cache and cookies once it gets destroyed at the appropriate time.
[email protected]f7227502012-02-22 21:54:32470 ProfileDestroyer::DestroyOffTheRecordProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29471 }
472
473 // There may be pending file dialogs, we need to tell them that we've gone
474 // away so they don't try and call back to us.
475 if (select_file_dialog_.get())
476 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13477
478 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29479}
480
[email protected]01a5a762011-11-21 05:40:55481bool Browser::IsFullscreenForTab() const {
482 return fullscreen_controller_->IsFullscreenForTab();
483}
484
[email protected]15952e462008-11-14 00:29:05485// static
486Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14487 Browser* browser = new Browser(TYPE_TABBED, profile);
488 browser->InitBrowserWindow();
489 return browser;
490}
491
492// static
493Browser* Browser::CreateWithParams(const CreateParams& params) {
[email protected]a636d8e52012-02-28 15:40:41494 if (!params.app_name.empty())
495 RegisterAppPrefs(params.app_name, params.profile);
496
[email protected]b35b26b32011-05-05 20:35:14497 Browser* browser = new Browser(params.type, params.profile);
498 browser->app_name_ = params.app_name;
[email protected]81b2b0ac2011-11-23 01:54:48499 browser->set_override_bounds(params.initial_bounds);
[email protected]a636d8e52012-02-28 15:40:41500 browser->set_show_state(params.initial_show_state);
501 browser->set_is_session_restore(params.is_session_restore);
502
[email protected]9800de5e2011-03-11 18:19:49503 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05504 return browser;
505}
[email protected]6104acf2008-11-11 22:27:34506
[email protected]15952e462008-11-14 00:29:05507// static
[email protected]9ee17e8c2010-08-10 19:17:31508Browser* Browser::CreateForType(Type type, Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14509 CreateParams params(type, profile);
510 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05511}
512
513// static
[email protected]b35b26b32011-05-05 20:35:14514Browser* Browser::CreateForApp(Type type,
515 const std::string& app_name,
[email protected]5c209242011-06-06 20:36:17516 const gfx::Rect& window_bounds,
[email protected]b35b26b32011-05-05 20:35:14517 Profile* profile) {
518 DCHECK(type != TYPE_TABBED);
519 DCHECK(!app_name.empty());
[email protected]f075fe0a22010-04-26 04:06:43520
[email protected]7e7a28092011-12-09 22:24:55521#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]b35b26b32011-05-05 20:35:14522 if (type == TYPE_PANEL &&
[email protected]7e7a28092011-12-09 22:24:55523 !PanelManager::ShouldUsePanels(
524 web_app::GetExtensionIdFromApplicationName(app_name))) {
[email protected]b35b26b32011-05-05 20:35:14525 type = TYPE_POPUP;
[email protected]5530ac652010-09-25 05:35:49526 }
[email protected]384cb192011-10-14 20:46:51527#if defined(TOOLKIT_GTK)
[email protected]4517b272011-11-09 01:58:05528 // Panels are only supported on a white list of window managers for Linux.
529 if (type == TYPE_PANEL) {
[email protected]ca595c8f2011-11-10 19:30:58530 ui::WindowManagerName wm_type = ui::GuessWindowManager();
531 if (wm_type != ui::WM_COMPIZ &&
532 wm_type != ui::WM_ICE_WM &&
533 wm_type != ui::WM_KWIN &&
534 wm_type != ui::WM_METACITY &&
535 wm_type != ui::WM_MUTTER) {
[email protected]4517b272011-11-09 01:58:05536 type = TYPE_POPUP;
537 }
538 }
[email protected]384cb192011-10-14 20:46:51539#endif // TOOLKIT_GTK
[email protected]7e7a28092011-12-09 22:24:55540#endif // !OS_CHROMEOS || USE_AURA
[email protected]f075fe0a22010-04-26 04:06:43541
[email protected]b35b26b32011-05-05 20:35:14542 CreateParams params(type, profile);
543 params.app_name = app_name;
[email protected]81b2b0ac2011-11-23 01:54:48544 params.initial_bounds = window_bounds;
[email protected]b35b26b32011-05-05 20:35:14545 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05546}
547
[email protected]8e48e982009-12-25 11:22:46548// static
549Browser* Browser::CreateForDevTools(Profile* profile) {
[email protected]4befe2ec2011-08-31 16:13:39550#if defined(OS_CHROMEOS)
551 CreateParams params(TYPE_TABBED, profile);
552#else
[email protected]b35b26b32011-05-05 20:35:14553 CreateParams params(TYPE_POPUP, profile);
[email protected]4befe2ec2011-08-31 16:13:39554#endif
[email protected]b35b26b32011-05-05 20:35:14555 params.app_name = DevToolsWindow::kDevToolsApp;
556 return CreateWithParams(params);
[email protected]8e48e982009-12-25 11:22:46557}
558
[email protected]9800de5e2011-03-11 18:19:49559void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05560 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43561
[email protected]9800de5e2011-03-11 18:19:49562 window_ = CreateBrowserWindow();
[email protected]01a5a762011-11-21 05:40:55563 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
[email protected]15952e462008-11-14 00:29:05564
[email protected]5e37c452011-09-06 19:31:39565#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]6a34951a2012-01-17 18:10:40566 // Set the app user model id for this application to that of the application
567 // name. See http://crbug.com/7028.
568 ui::win::SetAppIdForWindow(
569 is_app() && !is_type_panel() ?
570 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
571 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
572 window()->GetNativeHandle());
[email protected]45446a52010-11-04 17:41:00573
[email protected]6a34951a2012-01-17 18:10:40574 if (is_type_panel()) {
575 ui::win::SetAppIconForWindow(ShellIntegration::GetChromiumIconPath(),
576 window()->GetNativeHandle());
[email protected]45446a52010-11-04 17:41:00577 }
[email protected]80cf3562009-11-17 08:17:24578#endif
579
[email protected]41d9faf2012-02-28 23:46:02580 // Create the extension window controller before sending notifications.
581 extension_window_controller_.reset(
582 new BrowserExtensionWindowController(this));
583
[email protected]ad50def52011-10-19 23:17:07584 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27585 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
[email protected]6c2381d2011-10-19 02:52:53586 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:07587 content::NotificationService::NoDetails());
[email protected]14d8c66e2009-09-22 00:32:52588
[email protected]15952e462008-11-14 00:29:05589 PrefService* local_state = g_browser_process->local_state();
[email protected]2f516c792011-09-19 22:22:09590 if (local_state && local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01591 prefs::kAutofillPersonalDataManagerFirstRun) &&
592 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46593 // Notify PDM that this is a first run.
594#if defined(OS_WIN)
[email protected]ea9edcb02011-09-23 22:05:04595 ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_));
[email protected]f69c8852010-10-12 02:36:46596#endif // defined(OS_WIN)
597 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01598 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46599 }
[email protected]6a1622a2011-09-20 22:37:45600
601 // Permanently dismiss ntp4 bubble for new users.
[email protected]dfa08b042011-12-28 23:07:21602 if (first_run::IsChromeFirstRun())
[email protected]27e96a972011-10-20 20:06:55603 NewTabPageHandler::DismissIntroMessage(local_state);
initial.commit09911bf2008-07-26 23:55:29604}
605
[email protected]bf8708692011-12-20 21:24:28606void Browser::SetWindowForTesting(BrowserWindow* window) {
607 DCHECK(!window_);
608 window_ = window;
609 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
610}
611
[email protected]36b6dcb2008-11-12 01:19:57612///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07613// Getters & Setters
614
[email protected]b77cb302009-10-29 04:09:17615FindBarController* Browser::GetFindBarController() {
616 if (!find_bar_controller_.get()) {
[email protected]632983f2011-08-08 22:51:24617 FindBar* find_bar = window_->CreateFindBar();
[email protected]b77cb302009-10-29 04:09:17618 find_bar_controller_.reset(new FindBarController(find_bar));
619 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24620 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17621 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
622 }
623 return find_bar_controller_.get();
624}
625
[email protected]24db8a072009-10-29 20:35:37626bool Browser::HasFindBarController() const {
627 return find_bar_controller_.get() != NULL;
628}
629
[email protected]b35b26b32011-05-05 20:35:14630bool Browser::is_app() const {
631 return !app_name_.empty();
632}
633
634bool Browser::is_devtools() const {
635 return app_name_ == DevToolsWindow::kDevToolsApp;
636}
637
[email protected]5c238752009-06-13 10:29:07638///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57639// Browser, Creation Helpers:
640
641// static
[email protected]eddcf7502012-02-09 22:43:48642void Browser::NewEmptyWindow(Profile* profile) {
643 bool incognito = profile->IsOffTheRecord();
644 PrefService* prefs = profile->GetPrefs();
645 if (incognito) {
646 if (IncognitoModePrefs::GetAvailability(prefs) ==
647 IncognitoModePrefs::DISABLED) {
648 incognito = false;
649 }
650 } else {
651 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
652 IncognitoModePrefs::ShouldLaunchIncognito(
653 *CommandLine::ForCurrentProcess(), prefs)) {
654 incognito = true;
655 }
656 }
657
658 if (incognito) {
659 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
660 OpenEmptyWindow(profile->GetOffTheRecordProfile());
661 } else {
662 content::RecordAction(UserMetricsAction("NewWindow"));
663 SessionService* session_service =
664 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
665 if (!session_service ||
666 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
667 OpenEmptyWindow(profile->GetOriginalProfile());
668 }
669 }
670}
671
672// static
[email protected]15952e462008-11-14 00:29:05673void Browser::OpenEmptyWindow(Profile* profile) {
674 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57675 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05676 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29677}
678
[email protected]36b6dcb2008-11-12 01:19:57679// static
[email protected]fbc947b2009-06-19 13:28:24680void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15681 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24682 if (service)
683 service->RestoreMostRecentEntry(NULL);
684}
685
686// static
[email protected]36b6dcb2008-11-12 01:19:57687void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55688 Browser* browser = GetOrCreateTabbedBrowser(
689 profile->GetOffTheRecordProfile());
[email protected]2905f742011-10-13 03:51:58690 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK);
[email protected]15952e462008-11-14 00:29:05691 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17692}
693
[email protected]36b6dcb2008-11-12 01:19:57694// static
[email protected]bb81f382012-01-03 22:45:44695WebContents* Browser::OpenApplication(
[email protected]d83a5602010-09-16 00:22:48696 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02697 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39698 extension_misc::LaunchContainer container,
[email protected]b6cb7702011-11-15 05:33:11699 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16700 WindowOpenDisposition disposition) {
[email protected]bb81f382012-01-03 22:45:44701 WebContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04702 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
703 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37704
[email protected]9b217652010-10-08 22:04:23705 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
706
[email protected]bbadaa782010-04-28 21:21:53707 switch (container) {
[email protected]a44657202012-01-09 05:48:31708 case extension_misc::LAUNCH_SHELL: {
709 ShellWindow* shell_window = ShellWindow::Create(
710 profile,
711 extension,
712 UrlForExtension(extension, override_url));
713 if (shell_window)
714 tab = shell_window->web_contents();
715 break;
716 }
[email protected]d83a5602010-09-16 00:22:48717 case extension_misc::LAUNCH_PANEL:
[email protected]bafda132012-02-16 19:32:51718#if defined(USE_AURA)
719 if (extension &&
720 CommandLine::ForCurrentProcess()->HasSwitch(
721 ash::switches::kAuraPanelManager)) {
722 tab = OpenApplicationPanel(profile, extension, override_url);
723 break;
724 }
725 // else fall through to LAUNCH_WINDOW
726#endif
727 case extension_misc::LAUNCH_WINDOW:
[email protected]bbadaa782010-04-28 21:21:53728 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]b6cb7702011-11-15 05:33:11729 override_url, NULL);
[email protected]c28071ad2010-03-12 17:28:56730 break;
[email protected]d83a5602010-09-16 00:22:48731 case extension_misc::LAUNCH_TAB: {
[email protected]b6cb7702011-11-15 05:33:11732 tab = Browser::OpenApplicationTab(profile, extension, override_url,
733 disposition);
[email protected]c28071ad2010-03-12 17:28:56734 break;
735 }
736 default:
737 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53738 break;
[email protected]c28071ad2010-03-12 17:28:56739 }
[email protected]bbadaa782010-04-28 21:21:53740 return tab;
[email protected]c28071ad2010-03-12 17:28:56741}
742
[email protected]bafda132012-02-16 19:32:51743#if defined(USE_AURA)
744// static
745WebContents* Browser::OpenApplicationPanel(
746 Profile* profile,
747 const Extension* extension,
748 const GURL& url_input) {
749 GURL url = UrlForExtension(extension, url_input);
750 std::string app_name =
751 web_app::GenerateApplicationNameFromExtensionId(extension->id());
752 gfx::Rect panel_bounds;
753 panel_bounds.set_width(extension->launch_width());
754 panel_bounds.set_height(extension->launch_height());
755 PanelViewAura* panel_view = new PanelViewAura(app_name);
756 panel_view->Init(profile, url, panel_bounds);
757 return panel_view->WebContents();
758}
759#endif
760
[email protected]c28071ad2010-03-12 17:28:56761// static
[email protected]bb81f382012-01-03 22:45:44762WebContents* Browser::OpenApplicationWindow(
[email protected]bbadaa782010-04-28 21:21:53763 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02764 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48765 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26766 const GURL& url_input,
767 Browser** app_browser) {
[email protected]b6cb7702011-11-15 05:33:11768 DCHECK(!url_input.is_empty() || extension);
769 GURL url = UrlForExtension(extension, url_input);
[email protected]f381dfa2010-04-29 04:41:37770
[email protected]2f1c09d2011-01-14 14:58:14771 std::string app_name;
[email protected]b6cb7702011-11-15 05:33:11772 app_name = extension ?
773 web_app::GenerateApplicationNameFromExtensionId(extension->id()) :
774 web_app::GenerateApplicationNameFromURL(url);
[email protected]2f1c09d2011-01-14 14:58:14775
[email protected]a44657202012-01-09 05:48:31776 Type type = extension && (container == extension_misc::LAUNCH_PANEL) ?
777 TYPE_PANEL : TYPE_POPUP;
[email protected]94ce7252010-12-20 21:46:33778
[email protected]5c209242011-06-06 20:36:17779 gfx::Rect window_bounds;
780 if (extension) {
781 window_bounds.set_width(extension->launch_width());
782 window_bounds.set_height(extension->launch_height());
783 }
[email protected]94ce7252010-12-20 21:46:33784
[email protected]5c209242011-06-06 20:36:17785 Browser* browser = Browser::CreateForApp(type, app_name, window_bounds,
[email protected]b35b26b32011-05-05 20:35:14786 profile);
[email protected]011396a2011-04-13 23:35:28787
[email protected]0e71e4152010-12-07 04:16:26788 if (app_browser)
789 *app_browser = browser;
790
[email protected]3c9e1872010-11-18 16:17:49791 TabContentsWrapper* wrapper =
[email protected]2905f742011-10-13 03:51:58792 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_START_PAGE);
[email protected]bb81f382012-01-03 22:45:44793 WebContents* contents = wrapper->web_contents();
[email protected]cecc93a2010-10-05 15:58:55794 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:52795 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]cecc93a2010-10-05 15:58:55796 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53797
[email protected]68f009f2009-02-26 19:43:35798 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
799 // focus explicitly.
[email protected]d487beefe2011-12-21 05:41:21800 contents->GetView()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26801 return contents;
802}
[email protected]eabfdae92009-12-11 06:13:51803
[email protected]bb81f382012-01-03 22:45:44804WebContents* Browser::OpenAppShortcutWindow(Profile* profile,
[email protected]0e71e4152010-12-07 04:16:26805 const GURL& url,
806 bool update_shortcut) {
807 Browser* app_browser;
[email protected]bb81f382012-01-03 22:45:44808 WebContents* tab = OpenApplicationWindow(
[email protected]0e71e4152010-12-07 04:16:26809 profile,
810 NULL, // this is a URL app. No extension.
811 extension_misc::LAUNCH_WINDOW,
812 url,
813 &app_browser);
814
815 if (!tab)
816 return NULL;
817
818 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35819 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
820 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
821 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46822 // OnDidGetApplicationInfo, which calls
823 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
824 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26825 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35826 }
[email protected]0e71e4152010-12-07 04:16:26827 return tab;
[email protected]c28071ad2010-03-12 17:28:56828}
829
830// static
[email protected]bb81f382012-01-03 22:45:44831WebContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02832 const Extension* extension,
[email protected]b6cb7702011-11-15 05:33:11833 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16834 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14835 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]bb81f382012-01-03 22:45:44836 WebContents* contents = NULL;
[email protected]78d78a62011-09-29 18:24:33837 if (!browser) {
838 // No browser for this profile, need to open a new one.
839 browser = Browser::Create(profile);
840 browser->window()->Show();
841 // There's no current tab in this browser window, so add a new one.
842 disposition = NEW_FOREGROUND_TAB;
843 }
[email protected]c28071ad2010-03-12 17:28:56844
[email protected]10abd192010-09-30 02:03:49845 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36846 ExtensionService* extension_service = profile->GetExtensionService();
847 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59848
[email protected]10abd192010-09-30 02:03:49849 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36850 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02851 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23852 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]333b1de2011-09-12 18:28:50853
[email protected]49098f702011-10-13 03:47:18854 static bool default_apps_trial_exists =
[email protected]568c3312011-12-06 15:36:04855 base::FieldTrialList::TrialExists(kDefaultAppsTrialName);
[email protected]49098f702011-10-13 03:47:18856 if (default_apps_trial_exists) {
857 UMA_HISTOGRAM_ENUMERATION(
858 base::FieldTrial::MakeName("Extensions.AppTabLaunchType",
[email protected]568c3312011-12-06 15:36:04859 kDefaultAppsTrialName),
[email protected]49098f702011-10-13 03:47:18860 launch_type, 100);
861 }
[email protected]333b1de2011-09-12 18:28:50862
[email protected]eaca0ad12011-04-18 15:53:41863 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49864 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
865 add_type |= TabStripModel::ADD_PINNED;
866
[email protected]b6cb7702011-11-15 05:33:11867 GURL extension_url = UrlForExtension(extension, override_url);
[email protected]10abd192010-09-30 02:03:49868 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
869 // cases.
[email protected]37fcf262011-01-26 19:39:15870 browser::NavigateParams params(browser, extension_url,
[email protected]2905f742011-10-13 03:51:58871 content::PAGE_TRANSITION_START_PAGE);
[email protected]616381f02010-11-02 15:15:33872 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16873 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39874
[email protected]7e41c2b2011-05-06 10:31:16875 if (disposition == CURRENT_TAB) {
[email protected]bb81f382012-01-03 22:45:44876 WebContents* existing_tab = browser->GetSelectedWebContents();
[email protected]24bf2022010-10-14 16:34:39877 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49878 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39879
[email protected]bce1f1c2011-12-05 15:11:58880 existing_tab->OpenURL(OpenURLParams(
881 extension_url,
882 content::Referrer(existing_tab->GetURL(),
883 WebKit::WebReferrerPolicyDefault),
884 disposition, content::PAGE_TRANSITION_LINK, false));
[email protected]616381f02010-11-02 15:15:33885 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39886 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49887 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26888 }
[email protected]eaca0ad12011-04-18 15:53:41889 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
890 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39891
892 contents = existing_tab;
893 } else {
[email protected]616381f02010-11-02 15:15:33894 browser::Navigate(&params);
[email protected]bb81f382012-01-03 22:45:44895 contents = params.target_contents->web_contents();
[email protected]24bf2022010-10-14 16:34:39896 }
897
[email protected]7bd42fc2011-02-09 17:32:42898 // TODO(skerner): If we are already in full screen mode, and the user
899 // set the app to open as a regular or pinned tab, what should happen?
900 // Today we open the tab, but stay in full screen mode. Should we leave
901 // full screen mode in this case?
902 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
[email protected]b6cb7702011-11-15 05:33:11903 !browser->window()->IsFullscreen()) {
[email protected]184717d52012-02-22 04:46:16904 browser->ToggleFullscreenMode();
[email protected]b6cb7702011-11-15 05:33:11905 }
[email protected]10abd192010-09-30 02:03:49906
[email protected]cecc93a2010-10-05 15:58:55907 return contents;
[email protected]c28071ad2010-03-12 17:28:56908}
909
910// static
[email protected]90a8bf252010-03-12 00:09:47911void Browser::OpenBookmarkManagerWindow(Profile* profile) {
912 Browser* browser = Browser::Create(profile);
[email protected]0af8f132011-07-16 01:37:02913 browser->OpenBookmarkManager();
[email protected]90a8bf252010-03-12 00:09:47914 browser->window()->Show();
915}
916
[email protected]057d959a2010-03-12 02:56:20917#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47918// static
[email protected]91a5b3e2009-10-30 19:32:22919void Browser::OpenHistoryWindow(Profile* profile) {
920 Browser* browser = Browser::Create(profile);
921 browser->ShowHistoryTab();
922 browser->window()->Show();
923}
924
925// static
926void Browser::OpenDownloadsWindow(Profile* profile) {
927 Browser* browser = Browser::Create(profile);
928 browser->ShowDownloadsTab();
929 browser->window()->Show();
930}
931
932// static
[email protected]1fdff702009-10-22 00:36:18933void Browser::OpenHelpWindow(Profile* profile) {
934 Browser* browser = Browser::Create(profile);
[email protected]202802e42011-07-06 11:40:46935 browser->ShowHelpTab();
[email protected]1fdff702009-10-22 00:36:18936 browser->window()->Show();
937}
[email protected]4a42d272010-06-18 01:29:42938
[email protected]eca258132010-11-15 23:33:08939// static
[email protected]4a42d272010-06-18 01:29:42940void Browser::OpenOptionsWindow(Profile* profile) {
941 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49942 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42943 browser->window()->Show();
944}
[email protected]c8de64a2011-01-25 17:10:23945
946// static
[email protected]65549182012-02-25 00:45:40947void Browser::OpenSyncSetupWindow(Profile* profile) {
948 Browser* browser = Browser::Create(profile);
949 browser->ShowSyncSetup();
950 browser->window()->Show();
951}
952
953// static
[email protected]ddddfda2011-07-14 23:19:39954void Browser::OpenClearBrowsingDataDialogWindow(Profile* profile) {
[email protected]c8de64a2011-01-25 17:10:23955 Browser* browser = Browser::Create(profile);
956 browser->OpenClearBrowsingDataDialog();
957 browser->window()->Show();
958}
959
960// static
961void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
962 Browser* browser = Browser::Create(profile);
963 browser->OpenImportSettingsDialog();
964 browser->window()->Show();
965}
[email protected]b99081b2011-03-10 17:43:47966
967// static
968void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
969 Browser* browser = Browser::Create(profile);
970 browser->OpenInstantConfirmDialog();
971 browser->window()->Show();
972}
[email protected]1fdff702009-10-22 00:36:18973#endif
974
[email protected]ccb55cf52010-03-06 22:02:04975// static
976void Browser::OpenExtensionsWindow(Profile* profile) {
977 Browser* browser = Browser::Create(profile);
978 browser->ShowExtensionsTab();
979 browser->window()->Show();
980}
981
[email protected]36b6dcb2008-11-12 01:19:57982///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57983// Browser, State Storage and Retrieval for UI:
984
[email protected]57ecc4b2010-08-11 03:02:51985std::string Browser::GetWindowPlacementKey() const {
986 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57987 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51988 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57989 name.append(app_name_);
990 }
[email protected]bc9a5152008-11-15 00:32:04991 return name;
992}
[email protected]36b6dcb2008-11-12 01:19:57993
[email protected]bc9a5152008-11-15 00:32:04994bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14995 switch (type_) {
996 case TYPE_TABBED:
997 return true;
998 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:51999 // Only save the window placement of popups if they are restored,
1000 // or the window belongs to DevTools.
[email protected]a636d8e52012-02-28 15:40:411001#if defined USE_AURA
1002 if (is_app())
1003 return true;
1004#endif
[email protected]bd6cdf22011-06-21 08:11:511005 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:141006 case TYPE_PANEL:
1007 // Do not save the window placement of panels.
1008 return false;
1009 default:
1010 return false;
1011 }
[email protected]bc9a5152008-11-15 00:32:041012}
[email protected]36b6dcb2008-11-12 01:19:571013
[email protected]400eaf82011-08-22 15:47:391014void Browser::SaveWindowPlacement(const gfx::Rect& bounds,
1015 ui::WindowShowState show_state) {
[email protected]bc9a5152008-11-15 00:32:041016 // Save to the session storage service, used when reloading a past session.
1017 // Note that we don't want to be the ones who cause lazy initialization of
1018 // the session service. This function gets called during initial window
1019 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:151020 SessionService* session_service =
1021 SessionServiceFactory::GetForProfileIfExisting(profile());
1022 if (session_service)
[email protected]400eaf82011-08-22 15:47:391023 session_service->SetWindowBounds(session_id_, bounds, show_state);
[email protected]36b6dcb2008-11-12 01:19:571024}
1025
[email protected]15952e462008-11-14 00:29:051026gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]113baf92012-02-14 02:21:061027 gfx::Rect restored_bounds = override_bounds_;
1028 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
1029 &restored_bounds);
1030
[email protected]bb975362009-01-21 01:00:221031 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:051032 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
1033 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
1034 if (record_mode || playback_mode) {
1035 // In playback/record mode we always fix the size of the browser and
1036 // move it to (0,0). The reason for this is two reasons: First we want
1037 // resize/moves in the playback to still work, and Second we want
1038 // playbacks to work (as much as possible) on machines w/ different
1039 // screen sizes.
[email protected]113baf92012-02-14 02:21:061040 restored_bounds = gfx::Rect(0, 0, 800, 600);
[email protected]15952e462008-11-14 00:29:051041 }
1042
[email protected]113baf92012-02-14 02:21:061043 // The following options override playback/record.
1044 if (parsed_command_line.HasSwitch(switches::kWindowSize)) {
1045 std::string str =
1046 parsed_command_line.GetSwitchValueASCII(switches::kWindowSize);
1047 int width, height;
1048 if (ParseCommaSeparatedIntegers(str, &width, &height))
1049 restored_bounds.set_size(gfx::Size(width, height));
1050 }
1051 if (parsed_command_line.HasSwitch(switches::kWindowPosition)) {
1052 std::string str =
1053 parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition);
1054 int x, y;
1055 if (ParseCommaSeparatedIntegers(str, &x, &y))
1056 restored_bounds.set_origin(gfx::Point(x, y));
1057 }
1058
[email protected]15952e462008-11-14 00:29:051059 return restored_bounds;
1060}
1061
[email protected]400eaf82011-08-22 15:47:391062ui::WindowShowState Browser::GetSavedWindowShowState() const {
[email protected]76d8a4f2012-02-27 19:25:101063 // Only tabbed browsers use the command line or preference state, with the
1064 // exception of devtools.
[email protected]a636d8e52012-02-28 15:40:411065 bool show_state = !is_type_tabbed();
1066
1067#if defined(USE_AURA)
1068 // Apps save state on aura.
1069 show_state &= !is_app();
1070#endif
1071
1072 if (show_state)
[email protected]3c627ff2012-01-27 17:04:071073 return show_state_;
[email protected]dfca0c32012-01-18 22:32:251074
[email protected]bb975362009-01-21 01:00:221075 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]400eaf82011-08-22 15:47:391076 return ui::SHOW_STATE_MAXIMIZED;
[email protected]15952e462008-11-14 00:29:051077
[email protected]400eaf82011-08-22 15:47:391078 if (show_state_ != ui::SHOW_STATE_DEFAULT)
1079 return show_state_;
[email protected]2e716622009-03-09 21:11:011080
[email protected]96f20102011-11-16 17:20:321081 const DictionaryValue* window_pref =
1082 profile()->GetPrefs()->GetDictionary(GetWindowPlacementKey().c_str());
[email protected]2e716622009-03-09 21:11:011083 bool maximized = false;
[email protected]96f20102011-11-16 17:20:321084 window_pref->GetBoolean("maximized", &maximized);
1085
[email protected]3c627ff2012-01-27 17:04:071086 return maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_DEFAULT;
[email protected]36b6dcb2008-11-12 01:19:571087}
1088
1089SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:041090 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:231091 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
1092 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:041093 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:571094}
1095
[email protected]731f8a42009-07-20 22:07:321096string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]4ca15302012-01-03 05:53:201097 WebContents* contents = GetSelectedWebContents();
[email protected]dda5dfa32009-07-10 00:33:291098 string16 title;
[email protected]c7c42332008-11-15 01:10:541099
[email protected]731f8a42009-07-20 22:07:321100 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
1101 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:571102 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:291103 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:571104 FormatTitleForDisplay(&title);
1105 }
1106 if (title.empty())
[email protected]51d83bdf2011-12-09 16:09:291107 title = CoreTabHelper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:571108
[email protected]16779842009-07-08 23:45:291109#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:331110 // On Mac or ChromeOS, we don't want to suffix the page title with
1111 // the application name.
[email protected]d904bc82009-07-07 00:41:041112 return title;
[email protected]7be64502011-05-03 17:51:471113#else
[email protected]edb5e6a2009-04-08 23:46:171114 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:551115 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:141116 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:171117 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:291118 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:501119#endif
[email protected]36b6dcb2008-11-12 01:19:571120}
1121
1122// static
[email protected]dda5dfa32009-07-10 00:33:291123void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:571124 size_t current_index = 0;
1125 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:511126 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:151127 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:571128 current_index = match_index;
1129 }
1130}
1131
1132///////////////////////////////////////////////////////////////////////////////
1133// Browser, OnBeforeUnload handling:
1134
[email protected]460a2942010-12-15 19:43:151135bool Browser::TabsNeedBeforeUnloadFired() {
1136 if (tabs_needing_before_unload_fired_.empty()) {
1137 for (int i = 0; i < tab_count(); ++i) {
[email protected]a81343d232011-12-27 07:39:201138 WebContents* contents = GetTabContentsWrapperAt(i)->web_contents();
[email protected]460a2942010-12-15 19:43:151139 if (contents->NeedToFireBeforeUnload())
1140 tabs_needing_before_unload_fired_.insert(contents);
1141 }
1142 }
1143 return !tabs_needing_before_unload_fired_.empty();
1144}
1145
[email protected]36b6dcb2008-11-12 01:19:571146bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:061147 if (!CanCloseWithInProgressDownloads())
1148 return false;
1149
1150 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:041151 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:061152
[email protected]36b6dcb2008-11-12 01:19:571153 is_attempting_to_close_browser_ = true;
1154
[email protected]460a2942010-12-15 19:43:151155 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:041156 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:571157
1158 ProcessPendingTabs();
1159 return false;
1160}
1161
1162void Browser::OnWindowClosing() {
1163 if (!ShouldCloseWindow())
1164 return;
1165
[email protected]911f8152010-03-18 16:46:401166 bool exiting = false;
1167
[email protected]c984d9f2010-07-20 20:52:201168 // Application should shutdown on last window close if the user is explicitly
1169 // trying to quit, or if there is nothing keeping the browser alive (such as
1170 // AppController on the Mac, or BackgroundContentsService for background
1171 // pages).
1172 bool should_quit_if_last_browser =
1173 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:501174
1175 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:571176 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:401177 exiting = true;
1178 }
[email protected]36b6dcb2008-11-12 01:19:571179
[email protected]92371eb2011-04-28 11:50:151180 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:571181 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:151182 SessionService* session_service =
1183 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:571184 if (session_service)
1185 session_service->WindowClosing(session_id());
1186
[email protected]92371eb2011-04-28 11:50:151187 TabRestoreService* tab_restore_service =
1188 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]a636d8e52012-02-28 15:40:411189
1190#if defined(USE_AURA)
1191 if (tab_restore_service && is_app())
1192 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
1193#endif
1194
[email protected]b35b26b32011-05-05 20:35:141195 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:001196 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:391197
[email protected]911f8152010-03-18 16:46:401198 // TODO(sky): convert session/tab restore to use notification.
[email protected]ad50def52011-10-19 23:17:071199 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:271200 chrome::NOTIFICATION_BROWSER_CLOSING,
[email protected]6c2381d2011-10-19 02:52:531201 content::Source<Browser>(this),
1202 content::Details<bool>(&exiting));
[email protected]911f8152010-03-18 16:46:401203
[email protected]36b6dcb2008-11-12 01:19:571204 CloseAllTabs();
1205}
1206
[email protected]28788c7d2011-05-20 23:03:451207void Browser::OnWindowActivated() {
1208 // On some platforms we want to automatically reload tabs that are
1209 // killed when the user selects them.
[email protected]4ca15302012-01-03 05:53:201210 WebContents* contents = GetSelectedWebContents();
[email protected]be1f56ab2011-12-22 06:55:311211 if (contents && contents->GetCrashedStatus() ==
[email protected]28788c7d2011-05-20 23:03:451212 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
1213 if (CommandLine::ForCurrentProcess()->HasSwitch(
1214 switches::kReloadKilledTabs)) {
1215 Reload(CURRENT_TAB);
1216 }
1217 }
1218}
1219
[email protected]69444cc2009-04-09 20:40:061220////////////////////////////////////////////////////////////////////////////////
1221// In-progress download termination handling:
1222
1223void Browser::InProgressDownloadResponse(bool cancel_downloads) {
1224 if (cancel_downloads) {
1225 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1226 CloseWindow();
1227 return;
1228 }
1229
1230 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1231 // close again we'll show the warning again.
1232 cancel_download_confirmation_state_ = NOT_PROMPTED;
1233
1234 // Show the download page so the user can figure-out what downloads are still
1235 // in-progress.
1236 ShowDownloadsTab();
1237}
1238
[email protected]5a17d492011-10-24 19:37:031239Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
1240 int* num_downloads_blocking) const {
1241 DCHECK(num_downloads_blocking);
1242 *num_downloads_blocking = 0;
1243
1244 if (is_attempting_to_close_browser_)
1245 return DOWNLOAD_CLOSE_OK;
1246
1247 // If we're not running a full browser process with a profile manager
1248 // (testing), it's ok to close the browser.
1249 if (!g_browser_process->profile_manager())
1250 return DOWNLOAD_CLOSE_OK;
1251
1252 int total_download_count = DownloadService::DownloadCountAllProfiles();
1253 if (total_download_count == 0)
1254 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
1255
1256 // Figure out how many windows are open total, and associated with this
1257 // profile, that are relevant for the ok-to-close decision.
1258 int profile_window_count = 0;
1259 int total_window_count = 0;
1260 for (BrowserList::const_iterator iter = BrowserList::begin();
1261 iter != BrowserList::end(); ++iter) {
1262 // Don't count this browser window or any other in the process of closing.
1263 Browser* const browser = *iter;
1264 // Check is_attempting_to_close_browser_ as window closing may be
1265 // delayed, and windows that are in the process of closing don't
1266 // count against our totals.
1267 if (browser == this || browser->is_attempting_to_close_browser_)
1268 continue;
1269
1270 if ((*iter)->profile() == profile())
1271 profile_window_count++;
1272 total_window_count++;
1273 }
1274
1275 // If there aren't any other windows, we're at browser shutdown,
1276 // which would cancel all current downloads.
1277 if (total_window_count == 0) {
1278 *num_downloads_blocking = total_download_count;
1279 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
1280 }
1281
1282 // If there aren't any other windows on our profile, and we're an incognito
1283 // profile, and there are downloads associated with that profile,
1284 // those downloads would be cancelled by our window (-> profile) close.
1285 DownloadService* download_service =
1286 DownloadServiceFactory::GetForProfile(profile());
1287 if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
1288 profile()->IsOffTheRecord()) {
1289 *num_downloads_blocking = download_service->DownloadCount();
1290 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
1291 }
1292
1293 // Those are the only conditions under which we will block shutdown.
1294 return DOWNLOAD_CLOSE_OK;
1295}
1296
[email protected]69444cc2009-04-09 20:40:061297////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451298// Browser, TabStripModel pass-thrus:
1299
1300int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:401301 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:451302}
1303
[email protected]1ea49d52011-04-12 17:44:441304int Browser::active_index() const {
1305 return tab_handler_->GetTabStripModel()->active_index();
[email protected]c848d3d92010-09-16 21:57:451306}
1307
1308int Browser::GetIndexOfController(
[email protected]c5eed492012-01-04 17:07:501309 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:401310 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451311}
1312
[email protected]3c9e1872010-11-18 16:17:491313TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
[email protected]41f022e2012-01-31 05:56:401314 return tab_handler_->GetTabStripModel()->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491315}
[email protected]b375c5d2011-05-03 21:15:041316
[email protected]4ca15302012-01-03 05:53:201317WebContents* Browser::GetSelectedWebContents() const {
1318 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1319 return wrapper ? wrapper->web_contents() : NULL;
1320}
1321
[email protected]3c9e1872010-11-18 16:17:491322TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
[email protected]41f022e2012-01-31 05:56:401323 return tab_handler_->GetTabStripModel()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451324}
1325
[email protected]6acde6352012-01-04 16:52:201326WebContents* Browser::GetWebContentsAt(int index) const {
[email protected]41f022e2012-01-31 05:56:401327 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(index);
[email protected]3c9e1872010-11-18 16:17:491328 if (wrapper)
[email protected]6acde6352012-01-04 16:52:201329 return wrapper->web_contents();
[email protected]3c9e1872010-11-18 16:17:491330 return NULL;
[email protected]c848d3d92010-09-16 21:57:451331}
1332
[email protected]eaca0ad12011-04-18 15:53:411333void Browser::ActivateTabAt(int index, bool user_gesture) {
1334 tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451335}
1336
[email protected]fb7da4132011-03-15 15:51:001337bool Browser::IsTabPinned(int index) const {
[email protected]41f022e2012-01-31 05:56:401338 return tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]fb7da4132011-03-15 15:51:001339}
1340
[email protected]002efb042011-10-07 17:30:241341bool Browser::IsTabDiscarded(int index) const {
1342 return tab_handler_->GetTabStripModel()->IsTabDiscarded(index);
1343}
1344
[email protected]c848d3d92010-09-16 21:57:451345void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:401346 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451347}
1348
1349////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571350// Browser, Tab adding/showing functions:
1351
[email protected]95bf8a5b2010-12-22 16:04:071352bool Browser::IsTabStripEditable() const {
1353 return window()->IsTabStripEditable();
1354}
1355
[email protected]b3344872010-05-03 15:52:291356int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:401357 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
1358 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291359}
1360
[email protected]dad09ce42011-08-25 23:11:301361TabContentsWrapper* Browser::AddSelectedTabWithURL(
1362 const GURL& url,
[email protected]2905f742011-10-13 03:51:581363 content::PageTransition transition) {
[email protected]616381f02010-11-02 15:15:331364 browser::NavigateParams params(this, url, transition);
1365 params.disposition = NEW_FOREGROUND_TAB;
1366 browser::Navigate(&params);
1367 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571368}
1369
[email protected]d9083482012-01-06 00:38:461370WebContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]2905f742011-10-13 03:51:581371 content::PageTransition type) {
[email protected]ecc523f62010-09-28 22:45:401372 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]eaca0ad12011-04-18 15:53:411373 tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
[email protected]d9083482012-01-06 00:38:461374 return tab_contents->web_contents();
[email protected]36b6dcb2008-11-12 01:19:571375}
1376
[email protected]2a6bc3e2011-12-28 23:51:331377void Browser::AddWebContents(WebContents* new_contents,
[email protected]e0c7c262009-04-23 23:09:431378 WindowOpenDisposition disposition,
1379 const gfx::Rect& initial_pos,
1380 bool user_gesture) {
1381 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1382}
1383
[email protected]0ec4898e2011-12-30 21:09:241384void Browser::CloseTabContents(WebContents* contents) {
[email protected]e0c7c262009-04-23 23:09:431385 CloseContents(contents);
1386}
1387
[email protected]b86451c2011-08-16 02:13:441388gfx::NativeWindow Browser::BrowserShowHtmlDialog(
[email protected]62c1f7a2011-10-01 01:12:041389 HtmlDialogUIDelegate* delegate,
[email protected]22c830d2011-11-29 20:00:371390 gfx::NativeWindow parent_window,
1391 DialogStyle style) {
[email protected]62c1f7a2011-10-01 01:12:041392#if defined(OS_CHROMEOS)
1393 // For Chrome OS, first try to parent the dialog over the current browser --
1394 // it's likely to be maximized onscreen. If it isn't tabbed (e.g. it's a
1395 // panel), find a browser that is.
1396 parent_window = window_->GetNativeHandle();
1397 if (!is_type_tabbed()) {
1398 Browser* tabbed_browser = BrowserList::FindTabbedBrowser(profile_, true);
1399 if (tabbed_browser && tabbed_browser->window())
1400 parent_window = tabbed_browser->window()->GetNativeHandle();
1401 }
1402#endif // defined(OS_CHROMEOS)
1403 if (!parent_window)
1404 parent_window = window_->GetNativeHandle();
1405
[email protected]c5e22aee52012-01-19 16:10:511406 return browser::ShowHtmlDialog(parent_window,
1407 profile_,
1408 this,
1409 delegate,
1410 style);
[email protected]e0c7c262009-04-23 23:09:431411}
1412
1413void Browser::BrowserRenderWidgetShowing() {
1414 RenderWidgetShowing();
1415}
1416
[email protected]c9bd2e82011-04-15 23:28:191417void Browser::BookmarkBarSizeChanged(bool is_animating) {
1418 window_->ToolbarSizeChanged(is_animating);
[email protected]e0c7c262009-04-23 23:09:431419}
1420
[email protected]6acde6352012-01-04 16:52:201421WebContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571422 const std::vector<TabNavigation>& navigations,
1423 int tab_index,
1424 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081425 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091426 bool select,
[email protected]5e369672009-11-03 23:48:301427 bool pin,
[email protected]6ee12c42010-09-14 09:36:071428 bool from_last_session,
[email protected]adbfb8df2012-02-24 01:19:431429 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041430 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1431 TabContentsWrapper* wrapper = TabContentsFactory(
1432 profile(),
1433 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]3c9e1872010-11-18 16:17:491434 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:441435 GetSelectedWebContents(),
[email protected]ecc523f62010-09-28 22:45:401436 session_storage_namespace);
[email protected]6acde6352012-01-04 16:52:201437 WebContents* new_tab = wrapper->web_contents();
[email protected]36fb2c7c2011-04-04 15:49:081438 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]10f417c52011-12-28 21:04:231439 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141440 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1441 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561442 new_tab->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141443 selected_navigation, from_last_session, &entries);
1444 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571445
[email protected]eaca0ad12011-04-18 15:53:411446 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211447 TabStripModel::ADD_NONE;
1448 if (pin) {
[email protected]41f022e2012-01-31 05:56:401449 int first_mini_tab_idx =
1450 tab_handler_->GetTabStripModel()->IndexOfFirstNonMiniTab();
1451 tab_index = std::min(tab_index, first_mini_tab_idx);
[email protected]981b992e2011-03-28 21:05:211452 add_types |= TabStripModel::ADD_PINNED;
1453 }
1454 tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1455 add_types);
[email protected]c93a9dd2010-04-22 20:25:181456 if (select) {
[email protected]77bc6732009-04-20 22:01:031457 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181458 } else {
1459 // We set the size of the view here, before WebKit does its initial
1460 // layout. If we don't, the initial layout of background tabs will be
1461 // performed with a view width of 0, which may cause script outputs and
1462 // anchor link location calculations to be incorrect even after a new
1463 // layout with proper view dimensions. TabStripModel::AddTabContents()
1464 // contains similar logic.
[email protected]d487beefe2011-12-21 05:41:211465 new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size());
[email protected]c93a9dd2010-04-22 20:25:181466 new_tab->HideContents();
[email protected]f5fa20e2011-12-21 22:35:561467 new_tab->GetController().LoadIfNecessary();
[email protected]c93a9dd2010-04-22 20:25:181468 }
[email protected]92371eb2011-04-28 11:50:151469 SessionService* session_service =
1470 SessionServiceFactory::GetForProfileIfExisting(profile_);
1471 if (session_service)
[email protected]81898992011-06-14 22:15:001472 session_service->TabRestored(wrapper, pin);
[email protected]ce3fa3c2009-04-20 19:55:571473 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571474}
1475
1476void Browser::ReplaceRestoredTab(
1477 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301478 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101479 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071480 const std::string& extension_app_id,
[email protected]adbfb8df2012-02-24 01:19:431481 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041482 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1483 TabContentsWrapper* wrapper = TabContentsFactory(
1484 profile(),
1485 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]ecc523f62010-09-28 22:45:401486 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:441487 GetSelectedWebContents(),
[email protected]6ee12c42010-09-14 09:36:071488 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081489 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]d9083482012-01-06 00:38:461490 WebContents* replacement = wrapper->web_contents();
[email protected]10f417c52011-12-28 21:04:231491 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141492 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1493 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561494 replacement->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141495 selected_navigation, from_last_session, &entries);
1496 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571497
[email protected]ecc523f62010-09-28 22:45:401498 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
[email protected]41f022e2012-01-31 05:56:401499 active_index(), wrapper);
[email protected]36b6dcb2008-11-12 01:19:571500}
1501
[email protected]a8eff102009-04-14 15:23:431502bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131503 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431504}
1505
[email protected]3698f172010-03-17 20:50:291506bool Browser::NavigateToIndexWithDisposition(int index,
1507 WindowOpenDisposition disp) {
[email protected]c5eed492012-01-04 17:07:501508 NavigationController& controller =
[email protected]f5fa20e2011-12-21 22:35:561509 GetOrCloneTabForDisposition(disp)->GetController();
[email protected]a26023822011-12-29 00:23:551510 if (index < 0 || index >= controller.GetEntryCount())
[email protected]3698f172010-03-17 20:50:291511 return false;
[email protected]cb84d642010-06-10 00:56:281512 controller.GoToIndex(index);
1513 return true;
[email protected]3698f172010-03-17 20:50:291514}
1515
[email protected]fee320542011-03-02 01:30:491516browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1517 const GURL& url) {
[email protected]2905f742011-10-13 03:51:581518 browser::NavigateParams params(
1519 this, url, content::PAGE_TRANSITION_AUTO_BOOKMARK);
[email protected]616381f02010-11-02 15:15:331520 params.disposition = SINGLETON_TAB;
[email protected]7d329992011-04-15 18:20:021521 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:351522 params.user_gesture = true;
[email protected]fee320542011-03-02 01:30:491523 return params;
1524}
1525
1526void Browser::ShowSingletonTab(const GURL& url) {
1527 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331528 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571529}
[email protected]d938aed92009-01-22 19:49:331530
[email protected]578c6962011-08-24 22:06:401531void Browser::ShowSingletonTabRespectRef(const GURL& url) {
1532 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1533 params.ref_behavior = browser::NavigateParams::RESPECT_REF;
1534 browser::Navigate(&params);
1535}
1536
[email protected]ddddfda2011-07-14 23:19:391537void Browser::ShowSingletonTabOverwritingNTP(
1538 const browser::NavigateParams& params) {
1539 browser::NavigateParams local_params(params);
[email protected]4ca15302012-01-03 05:53:201540 WebContents* contents = GetSelectedWebContents();
[email protected]842a648c2011-07-20 23:23:161541 if (contents) {
1542 const GURL& contents_url = contents->GetURL();
1543 if ((contents_url == GURL(chrome::kChromeUINewTabURL) ||
1544 contents_url == GURL(chrome::kAboutBlankURL)) &&
1545 browser::GetIndexOfSingletonTab(&local_params) < 0) {
1546 local_params.disposition = CURRENT_TAB;
1547 }
[email protected]ddddfda2011-07-14 23:19:391548 }
1549
1550 browser::Navigate(&local_params);
1551}
1552
[email protected]227393e2011-06-29 21:28:391553void Browser::WindowFullscreenStateChanged() {
[email protected]01a5a762011-11-21 05:40:551554 fullscreen_controller_->WindowFullscreenStateChanged();
[email protected]9adb8b12011-12-09 06:49:131555 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1556 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
[email protected]ae2622c2009-07-30 23:47:581557}
1558
[email protected]36b6dcb2008-11-12 01:19:571559///////////////////////////////////////////////////////////////////////////////
1560// Browser, Assorted browser commands:
1561
[email protected]d9083482012-01-06 00:38:461562WebContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291563 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491564 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]bbafdc72011-07-06 22:27:171565 switch (disposition) {
1566 case NEW_FOREGROUND_TAB:
1567 case NEW_BACKGROUND_TAB: {
1568 current_tab = current_tab->Clone();
1569 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]2905f742011-10-13 03:51:581570 current_tab, -1, content::PAGE_TRANSITION_LINK,
[email protected]bbafdc72011-07-06 22:27:171571 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
1572 TabStripModel::ADD_NONE);
1573 break;
1574 }
1575 case NEW_WINDOW: {
1576 current_tab = current_tab->Clone();
1577 Browser* browser = Browser::Create(profile_);
1578 browser->tabstrip_model()->AddTabContents(
[email protected]2905f742011-10-13 03:51:581579 current_tab, -1, content::PAGE_TRANSITION_LINK,
1580 TabStripModel::ADD_ACTIVE);
[email protected]bbafdc72011-07-06 22:27:171581 browser->window()->Show();
1582 break;
1583 }
1584 default:
1585 break;
[email protected]3698f172010-03-17 20:50:291586 }
[email protected]d9083482012-01-06 00:38:461587 return current_tab->web_contents();
[email protected]3698f172010-03-17 20:50:291588}
1589
[email protected]018cf362010-05-05 22:43:221590bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1591 bool check_fullscreen) const {
1592 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1593 // other platforms, we hide some controls when in fullscreen mode.
1594 bool hide_ui_for_fullscreen = false;
1595#if !defined(OS_MACOSX)
1596 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1597 window_->IsFullscreen();
1598#endif
1599
[email protected]3a80ea332012-01-09 19:53:291600 unsigned int features = FEATURE_INFOBAR;
[email protected]018cf362010-05-05 22:43:221601
[email protected]eab8c0f2011-11-18 22:33:501602#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]018cf362010-05-05 22:43:221603 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1604 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1605 features |= FEATURE_DOWNLOADSHELF;
[email protected]eab8c0f2011-11-18 22:33:501606#endif // !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]018cf362010-05-05 22:43:221607
[email protected]b35b26b32011-05-05 20:35:141608 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221609 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221610
1611 if (!hide_ui_for_fullscreen) {
[email protected]b35b26b32011-05-05 20:35:141612 if (!is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221613 features |= FEATURE_TITLEBAR;
1614
[email protected]b35b26b32011-05-05 20:35:141615 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221616 features |= FEATURE_TABSTRIP;
1617
[email protected]b35b26b32011-05-05 20:35:141618 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221619 features |= FEATURE_TOOLBAR;
1620
[email protected]b35b26b32011-05-05 20:35:141621 if (!is_app())
[email protected]018cf362010-05-05 22:43:221622 features |= FEATURE_LOCATIONBAR;
1623 }
1624 return !!(features & feature);
1625}
1626
[email protected]0b4d3382010-07-14 16:13:041627bool Browser::IsClosingPermitted() {
1628 TabCloseableStateWatcher* watcher =
1629 g_browser_process->tab_closeable_state_watcher();
1630 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1631 if (!can_close && is_attempting_to_close_browser_)
1632 CancelWindowClose();
1633 return can_close;
1634}
1635
[email protected]43c9dc722011-08-20 02:05:091636bool Browser::CanGoBack() const {
[email protected]3c790d22012-01-30 19:06:351637 return GetSelectedWebContents()->GetController().CanGoBack();
[email protected]43c9dc722011-08-20 02:05:091638}
1639
[email protected]485fba42009-03-24 23:27:291640void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381641 content::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271642
[email protected]3c9e1872010-11-18 16:17:491643 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]43c9dc722011-08-20 02:05:091644 if (CanGoBack()) {
[email protected]d9083482012-01-06 00:38:461645 WebContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061646 // If we are on an interstitial page and clone the tab, it won't be copied
1647 // to the new tab, so we don't need to go back.
[email protected]d9083482012-01-06 00:38:461648 if (current_tab->web_contents()->ShowingInterstitialPage() &&
1649 (new_tab != current_tab->web_contents()))
[email protected]d497b0782010-03-29 19:19:061650 return;
[email protected]f5fa20e2011-12-21 22:35:561651 new_tab->GetController().GoBack();
[email protected]485fba42009-03-24 23:27:291652 }
[email protected]36b6dcb2008-11-12 01:19:571653}
1654
[email protected]43c9dc722011-08-20 02:05:091655bool Browser::CanGoForward() const {
[email protected]3c790d22012-01-30 19:06:351656 return GetSelectedWebContents()->GetController().CanGoForward();
[email protected]43c9dc722011-08-20 02:05:091657}
1658
[email protected]3698f172010-03-17 20:50:291659void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381660 content::RecordAction(UserMetricsAction("Forward"));
[email protected]43c9dc722011-08-20 02:05:091661 if (CanGoForward())
[email protected]f5fa20e2011-12-21 22:35:561662 GetOrCloneTabForDisposition(disposition)->GetController().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571663}
1664
[email protected]cb84d642010-06-10 00:56:281665void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381666 content::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281667 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161668}
[email protected]fbd77592008-11-12 20:50:271669
[email protected]cb84d642010-06-10 00:56:281670void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381671 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281672 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161673}
1674
[email protected]cb84d642010-06-10 00:56:281675void Browser::ReloadInternal(WindowOpenDisposition disposition,
1676 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571677 // If we are showing an interstitial, treat this as an OpenURL.
[email protected]4ca15302012-01-03 05:53:201678 WebContents* current_tab = GetSelectedWebContents();
[email protected]0bfbf882011-12-22 18:19:271679 if (current_tab && current_tab->ShowingInterstitialPage()) {
[email protected]10f417c52011-12-28 21:04:231680 NavigationEntry* entry = current_tab->GetController().GetActiveEntry();
[email protected]cb84d642010-06-10 00:56:281681 DCHECK(entry); // Should exist if interstitial is showing.
[email protected]e5d549d2011-12-28 01:29:201682 OpenURL(OpenURLParams(
1683 entry->GetURL(), Referrer(), disposition,
1684 content::PAGE_TRANSITION_RELOAD, false));
[email protected]cb84d642010-06-10 00:56:281685 return;
[email protected]36b6dcb2008-11-12 01:19:571686 }
[email protected]cb84d642010-06-10 00:56:281687
1688 // As this is caused by a user action, give the focus to the page.
[email protected]6e3953dd2012-01-27 10:24:371689 //
1690 // Also notify RenderViewHostDelegate of the user gesture; this is
1691 // normally done in Browser::Navigate, but a reload bypasses Navigate.
[email protected]d9083482012-01-06 00:38:461692 WebContents* tab = GetOrCloneTabForDisposition(disposition);
[email protected]6e3953dd2012-01-27 10:24:371693 tab->GetRenderViewHost()->delegate()->OnUserGesture();
[email protected]3c9e1872010-11-18 16:17:491694 if (!tab->FocusLocationBarByDefault())
1695 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281696 if (ignore_cache)
[email protected]f5fa20e2011-12-21 22:35:561697 tab->GetController().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281698 else
[email protected]f5fa20e2011-12-21 22:35:561699 tab->GetController().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571700}
1701
[email protected]485fba42009-03-24 23:27:291702void Browser::Home(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381703 content::RecordAction(UserMetricsAction("Home"));
[email protected]e5d549d2011-12-28 01:29:201704 OpenURL(OpenURLParams(
1705 profile_->GetHomePage(), Referrer(), disposition,
[email protected]2905f742011-10-13 03:51:581706 content::PageTransitionFromInt(
1707 content::PAGE_TRANSITION_AUTO_BOOKMARK |
[email protected]e5d549d2011-12-28 01:29:201708 content::PAGE_TRANSITION_HOME_PAGE),
1709 false));
[email protected]36b6dcb2008-11-12 01:19:571710}
1711
[email protected]fbd77592008-11-12 20:50:271712void Browser::OpenCurrentURL() {
[email protected]7f6f44c2011-12-14 13:23:381713 content::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351714 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491715 if (!location_bar)
1716 return;
1717
[email protected]9d0306ea2009-09-02 19:38:391718 WindowOpenDisposition open_disposition =
1719 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271720 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301721 return;
[email protected]03bb953d2010-09-14 21:38:301722
[email protected]537de682011-08-08 18:10:141723 GURL url(location_bar->GetInputString());
[email protected]07d490bc2011-03-07 17:05:261724
1725 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1726 Browser* existing_browser = NULL;
[email protected]4ca15302012-01-03 05:53:201727 WebContents* existing_tab = TabFinder::GetInstance()->FindTab(
[email protected]07d490bc2011-03-07 17:05:261728 this, url, &existing_browser);
1729 if (existing_tab) {
1730 existing_browser->ActivateContents(existing_tab);
1731 return;
1732 }
1733 }
1734
[email protected]616381f02010-11-02 15:15:331735 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1736 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251737 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1738 // inherit the opener. In some cases the tabstrip will determine the group
1739 // should be inherited, in which case the group is inherited instead of the
1740 // opener.
[email protected]616381f02010-11-02 15:15:331741 params.tabstrip_add_types =
1742 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1743 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331744
[email protected]6e37fe32011-03-02 09:06:521745 DCHECK(profile_->GetExtensionService());
1746 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:331747 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1748 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1749 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1750 }
[email protected]fbd77592008-11-12 20:50:271751}
1752
[email protected]84214982008-12-10 18:49:101753void Browser::Stop() {
[email protected]7f6f44c2011-12-14 13:23:381754 content::RecordAction(UserMetricsAction("Stop"));
[email protected]41f022e2012-01-31 05:56:401755 GetSelectedWebContents()->Stop();
[email protected]84214982008-12-10 18:49:101756}
1757
1758void Browser::NewWindow() {
[email protected]eddcf7502012-02-09 22:43:481759 NewEmptyWindow(profile_->GetOriginalProfile());
[email protected]84214982008-12-10 18:49:101760}
1761
1762void Browser::NewIncognitoWindow() {
[email protected]eddcf7502012-02-09 22:43:481763 NewEmptyWindow(profile_->GetOffTheRecordProfile());
[email protected]84214982008-12-10 18:49:101764}
1765
[email protected]84214982008-12-10 18:49:101766void Browser::CloseWindow() {
[email protected]7f6f44c2011-12-14 13:23:381767 content::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101768 window_->Close();
1769}
1770
[email protected]fbd77592008-11-12 20:50:271771void Browser::NewTab() {
[email protected]7f6f44c2011-12-14 13:23:381772 content::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261773
[email protected]b35b26b32011-05-05 20:35:141774 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271775 AddBlankTab(true);
[email protected]41f022e2012-01-31 05:56:401776 GetSelectedWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271777 } else {
[email protected]1a6b30a2009-08-19 03:52:111778 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271779 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051780 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111781 // The call to AddBlankTab above did not set the focus to the tab as its
1782 // window was not active, so we have to do it explicitly.
1783 // See http://crbug.com/6380.
[email protected]41f022e2012-01-31 05:56:401784 b->GetSelectedWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271785 }
1786}
1787
1788void Browser::CloseTab() {
[email protected]7f6f44c2011-12-14 13:23:381789 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211790 if (CanCloseTab())
1791 tab_handler_->GetTabStripModel()->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271792}
1793
[email protected]fbd77592008-11-12 20:50:271794void Browser::SelectNextTab() {
[email protected]7f6f44c2011-12-14 13:23:381795 content::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]ecc523f62010-09-28 22:45:401796 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271797}
1798
1799void Browser::SelectPreviousTab() {
[email protected]7f6f44c2011-12-14 13:23:381800 content::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]ecc523f62010-09-28 22:45:401801 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271802}
1803
[email protected]91ac9202010-07-30 18:32:351804void Browser::OpenTabpose() {
1805#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031806 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1807 switches::kEnableExposeForTabs)) {
1808 return;
1809 }
1810
[email protected]7f6f44c2011-12-14 13:23:381811 content::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351812 window()->OpenTabpose();
1813#else
1814 NOTREACHED();
1815#endif
1816}
1817
[email protected]9ac7fcb2009-09-14 18:22:521818void Browser::MoveTabNext() {
[email protected]7f6f44c2011-12-14 13:23:381819 content::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]ecc523f62010-09-28 22:45:401820 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521821}
1822
1823void Browser::MoveTabPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381824 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]ecc523f62010-09-28 22:45:401825 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521826}
1827
[email protected]fbd77592008-11-12 20:50:271828void Browser::SelectNumberedTab(int index) {
1829 if (index < tab_count()) {
[email protected]7f6f44c2011-12-14 13:23:381830 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]41f022e2012-01-31 05:56:401831 ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271832 }
1833}
1834
1835void Browser::SelectLastTab() {
[email protected]7f6f44c2011-12-14 13:23:381836 content::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]ecc523f62010-09-28 22:45:401837 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271838}
1839
1840void Browser::DuplicateTab() {
[email protected]7f6f44c2011-12-14 13:23:381841 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441842 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271843}
1844
1845void Browser::RestoreTab() {
[email protected]7f6f44c2011-12-14 13:23:381846 content::RecordAction(UserMetricsAction("RestoreTab"));
[email protected]92371eb2011-04-28 11:50:151847 TabRestoreService* service =
1848 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]fbd77592008-11-12 20:50:271849 if (!service)
1850 return;
1851
[email protected]fb7da4132011-03-15 15:51:001852 service->RestoreMostRecentEntry(tab_restore_service_delegate());
[email protected]fbd77592008-11-12 20:50:271853}
1854
[email protected]0c4c3882009-10-01 21:42:141855void Browser::WriteCurrentURLToClipboard() {
1856 // TODO(ericu): There isn't currently a metric for this. Should there be?
1857 // We don't appear to track the action when it comes from the
1858 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141859
[email protected]4ca15302012-01-03 05:53:201860 WebContents* contents = GetSelectedWebContents();
[email protected]cd8d90db2011-10-06 19:31:271861 if (!toolbar_model_.ShouldDisplayURL())
[email protected]0c4c3882009-10-01 21:42:141862 return;
1863
[email protected]90f39902009-10-03 04:25:371864 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141865 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171866 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141867 g_browser_process->clipboard());
1868}
1869
[email protected]fbd77592008-11-12 20:50:271870void Browser::ConvertPopupToTabbedBrowser() {
[email protected]7f6f44c2011-12-14 13:23:381871 content::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]3c9e1872010-11-18 16:17:491872 TabContentsWrapper* contents =
[email protected]41f022e2012-01-31 05:56:401873 tab_handler_->GetTabStripModel()->DetachTabContentsAt(active_index());
[email protected]15952e462008-11-14 00:29:051874 Browser* browser = Browser::Create(profile_);
1875 browser->tabstrip_model()->AppendTabContents(contents, true);
1876 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271877}
1878
[email protected]184717d52012-02-22 04:46:161879void Browser::ToggleFullscreenMode() {
1880 fullscreen_controller_->ToggleFullscreenMode();
1881}
1882
[email protected]41d9faf2012-02-28 23:46:021883void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
1884 fullscreen_controller_->ToggleFullscreenModeWithExtension(extension_url);
[email protected]9282cea2009-02-18 18:49:001885}
1886
[email protected]d3766932011-08-04 22:18:231887#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:161888void Browser::TogglePresentationMode() {
1889 fullscreen_controller_->TogglePresentationMode();
[email protected]d3766932011-08-04 22:18:231890}
1891#endif
1892
[email protected]da17b372010-01-22 23:37:221893#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331894void Browser::Search() {
[email protected]64559862010-09-23 19:00:161895 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101896 if (window_->IsFullscreen()) {
[email protected]184717d52012-02-22 04:46:161897 ToggleFullscreenMode();
[email protected]ebdda9092010-10-22 17:59:101898 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1899 // visible at this point. Wait for next event cycle which toggles
1900 // the visibility of omnibox before creating new tab.
1901 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:361902 FROM_HERE, base::Bind(&Browser::Search, weak_factory_.GetWeakPtr()));
[email protected]ebdda9092010-10-22 17:59:101903 return;
1904 }
[email protected]64559862010-09-23 19:00:161905
[email protected]4ca15302012-01-03 05:53:201906 const GURL& url = GetSelectedWebContents()->GetURL();
[email protected]0080c4f2011-10-03 21:56:371907 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1908 url.host() == chrome::kChromeUINewTabHost) {
1909 // If the NTP is showing, focus the omnibox.
1910 window_->SetFocusToLocationBar(true);
1911 } else {
1912 // Otherwise, open the NTP.
1913 NewTab();
1914 }
[email protected]f97d7f632010-06-01 21:08:331915}
[email protected]d14af522010-12-02 03:54:501916
1917void Browser::ShowKeyboardOverlay() {
1918 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1919}
[email protected]20d17242009-10-26 20:21:051920#endif
1921
[email protected]fbd77592008-11-12 20:50:271922void Browser::Exit() {
[email protected]7f6f44c2011-12-14 13:23:381923 content::RecordAction(UserMetricsAction("Exit"));
[email protected]b8b60082011-12-13 14:16:021924 BrowserList::AttemptUserExit();
[email protected]fbd77592008-11-12 20:50:271925}
1926
[email protected]36b6dcb2008-11-12 01:19:571927void Browser::BookmarkCurrentPage() {
[email protected]7f6f44c2011-12-14 13:23:381928 content::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271929
[email protected]76624fde2009-10-09 18:13:231930 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571931 if (!model || !model->IsLoaded())
1932 return; // Ignore requests until bookmarks are loaded.
1933
[email protected]76624fde2009-10-09 18:13:231934 GURL url;
[email protected]261cd762010-08-20 05:45:371935 string16 title;
[email protected]b375c5d2011-05-03 21:15:041936 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
[email protected]d9083482012-01-06 00:38:461937 bookmark_utils::GetURLAndTitleToBookmark(tab->web_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441938 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211939 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321940 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211941 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041942 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211943 }
[email protected]4394f2b2011-09-03 03:07:561944 bookmark_utils::AddIfNotBookmarked(model, url, title);
[email protected]11dbbd22009-11-06 18:55:041945 // Make sure the model actually added a bookmark before showing the star. A
1946 // bookmark isn't created if the url is invalid.
1947 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271948 // Only show the bubble if the window is active, otherwise we may get into
1949 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441950 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271951 }
[email protected]36b6dcb2008-11-12 01:19:571952}
1953
[email protected]40bdb6d92009-02-25 00:22:271954void Browser::SavePage() {
[email protected]7f6f44c2011-12-14 13:23:381955 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]4ca15302012-01-03 05:53:201956 WebContents* current_tab = GetSelectedWebContents();
[email protected]0bfbf882011-12-22 18:19:271957 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
[email protected]7f6f44c2011-12-14 13:23:381958 content::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]4ca15302012-01-03 05:53:201959 GetSelectedWebContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271960}
1961
[email protected]77d8d622010-12-15 10:30:121962void Browser::ViewSelectedSource() {
1963 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571964}
initial.commit09911bf2008-07-26 23:55:291965
[email protected]4801ecc2009-04-05 04:52:581966void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171967 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581968}
1969
[email protected]a3e18c42009-03-04 23:36:051970bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221971 return SupportsWindowFeatureImpl(feature, true);
1972}
[email protected]f5bf8ccf2010-02-05 18:19:251973
[email protected]018cf362010-05-05 22:43:221974bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1975 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051976}
1977
[email protected]89d6e6e2009-12-03 23:06:511978void Browser::EmailPageLocation() {
[email protected]7f6f44c2011-12-14 13:23:381979 content::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]4ca15302012-01-03 05:53:201980 WebContents* wc = GetSelectedWebContents();
1981 DCHECK(wc);
[email protected]d221a392011-05-24 14:34:241982
[email protected]4a19be92011-09-22 14:25:021983 std::string title = net::EscapeQueryParamValue(
[email protected]4ca15302012-01-03 05:53:201984 UTF16ToUTF8(wc->GetTitle()), false);
1985 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
[email protected]d221a392011-05-24 14:34:241986 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1987 title + "&body=%0A%0A" + page_url;
1988 platform_util::OpenExternal(GURL(mailto));
[email protected]89d6e6e2009-12-03 23:06:511989}
1990
[email protected]fbd77592008-11-12 20:50:271991void Browser::Print() {
[email protected]47c7ec82012-01-18 03:29:211992 if (g_browser_process->local_state()->GetBoolean(
1993 prefs::kPrintPreviewDisabled)) {
[email protected]49fe2262011-04-15 20:56:151994 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]47c7ec82012-01-18 03:29:211995 } else {
1996 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1997 }
[email protected]fbd77592008-11-12 20:50:271998}
1999
[email protected]0996e9b2011-08-26 17:59:012000void Browser::AdvancedPrint() {
2001 GetSelectedTabContentsWrapper()->print_view_manager()->AdvancedPrintNow();
2002}
2003
[email protected]fbd77592008-11-12 20:50:272004void Browser::ToggleEncodingAutoDetect() {
[email protected]7f6f44c2011-12-14 13:23:382005 content::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:272006 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:182007 // If "auto detect" is turned on, then any current override encoding
2008 // is cleared. This also implicitly performs a reload.
2009 // OTOH, if "auto detect" is turned off, we don't change the currently
2010 // active encoding.
2011 if (encoding_auto_detect_.GetValue()) {
[email protected]4ca15302012-01-03 05:53:202012 WebContents* contents = GetSelectedWebContents();
[email protected]a697f4c2009-09-14 22:30:182013 if (contents)
[email protected]b2fe07d12010-02-09 14:38:082014 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:182015 }
[email protected]fbd77592008-11-12 20:50:272016}
2017
2018void Browser::OverrideEncoding(int encoding_id) {
[email protected]7f6f44c2011-12-14 13:23:382019 content::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:402020 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:272021 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]4ca15302012-01-03 05:53:202022 WebContents* contents = GetSelectedWebContents();
[email protected]57c6a652009-05-04 07:58:342023 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:082024 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:272025 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:402026 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:192027 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
2028 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:402029 encoding_id,
2030 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:272031 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:192032 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:272033 }
[email protected]36b6dcb2008-11-12 01:19:572034}
2035
[email protected]84214982008-12-10 18:49:102036void Browser::Cut() {
[email protected]7f6f44c2011-12-14 13:23:382037 content::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:232038 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:572039}
2040
[email protected]84214982008-12-10 18:49:102041void Browser::Copy() {
[email protected]7f6f44c2011-12-14 13:23:382042 content::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:232043 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:572044}
2045
[email protected]84214982008-12-10 18:49:102046void Browser::Paste() {
[email protected]7f6f44c2011-12-14 13:23:382047 content::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:232048 window()->Paste();
[email protected]84214982008-12-10 18:49:102049}
2050
2051void Browser::Find() {
[email protected]7f6f44c2011-12-14 13:23:382052 content::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:292053 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:102054}
2055
2056void Browser::FindNext() {
[email protected]7f6f44c2011-12-14 13:23:382057 content::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:292058 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:102059}
2060
2061void Browser::FindPrevious() {
[email protected]7f6f44c2011-12-14 13:23:382062 content::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:292063 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:102064}
2065
[email protected]54087fe2011-10-28 22:02:482066void Browser::Zoom(content::PageZoom zoom) {
[email protected]0bffaa322011-07-18 17:37:542067 if (is_devtools())
2068 return;
2069
[email protected]41f022e2012-01-31 05:56:402070 RenderViewHost* host = GetSelectedWebContents()->GetRenderViewHost();
[email protected]0f083402011-11-22 02:59:012071 if (zoom == content::PAGE_ZOOM_RESET) {
2072 host->SetZoomLevel(0);
[email protected]7f6f44c2011-12-14 13:23:382073 content::RecordAction(UserMetricsAction("ZoomNormal"));
[email protected]0f083402011-11-22 02:59:012074 return;
2075 }
[email protected]896220042010-03-23 18:14:282076
[email protected]4ca15302012-01-03 05:53:202077 double current_zoom_level = GetSelectedWebContents()->GetZoomLevel();
[email protected]0f083402011-11-22 02:59:012078 double default_zoom_level =
2079 profile_->GetPrefs()->GetDouble(prefs::kDefaultZoomLevel);
2080
2081 // Generate a vector of zoom levels from an array of known presets along with
2082 // the default level added if necessary.
2083 std::vector<double> zoom_levels =
2084 chrome_page_zoom::PresetZoomLevels(default_zoom_level);
2085
2086 if (zoom == content::PAGE_ZOOM_OUT) {
2087 // Iterate through the zoom levels in reverse order to find the next
2088 // lower level based on the current zoom level for this page.
2089 for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin();
2090 i != zoom_levels.rend(); ++i) {
2091 double zoom_level = *i;
2092 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
2093 continue;
2094 if (zoom_level < current_zoom_level) {
2095 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:382096 content::RecordAction(UserMetricsAction("ZoomMinus"));
[email protected]0f083402011-11-22 02:59:012097 return;
2098 }
[email protected]7f6f44c2011-12-14 13:23:382099 content::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum"));
[email protected]0f083402011-11-22 02:59:012100 }
2101 } else {
2102 // Iterate through the zoom levels in normal order to find the next
2103 // higher level based on the current zoom level for this page.
2104 for (std::vector<double>::const_iterator i = zoom_levels.begin();
2105 i != zoom_levels.end(); ++i) {
2106 double zoom_level = *i;
2107 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
2108 continue;
2109 if (zoom_level > current_zoom_level) {
2110 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:382111 content::RecordAction(UserMetricsAction("ZoomPlus"));
[email protected]0f083402011-11-22 02:59:012112 return;
2113 }
2114 }
[email protected]7f6f44c2011-12-14 13:23:382115 content::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum"));
[email protected]0f083402011-11-22 02:59:012116 }
[email protected]84214982008-12-10 18:49:102117}
2118
2119void Browser::FocusToolbar() {
[email protected]7f6f44c2011-12-14 13:23:382120 content::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:102121 window_->FocusToolbar();
2122}
2123
[email protected]bdb7ff62010-07-20 01:56:522124void Browser::FocusAppMenu() {
[email protected]7f6f44c2011-12-14 13:23:382125 content::RecordAction(UserMetricsAction("FocusAppMenu"));
[email protected]bdb7ff62010-07-20 01:56:522126 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:012127}
2128
[email protected]84214982008-12-10 18:49:102129void Browser::FocusLocationBar() {
[email protected]7f6f44c2011-12-14 13:23:382130 content::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:582131 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:102132}
2133
[email protected]83548a42010-06-18 13:53:372134void Browser::FocusBookmarksToolbar() {
[email protected]7f6f44c2011-12-14 13:23:382135 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:372136 window_->FocusBookmarksToolbar();
2137}
2138
2139void Browser::FocusChromeOSStatus() {
[email protected]7f6f44c2011-12-14 13:23:382140 content::RecordAction(UserMetricsAction("FocusChromeOSStatus"));
[email protected]83548a42010-06-18 13:53:372141 window_->FocusChromeOSStatus();
2142}
2143
2144void Browser::FocusNextPane() {
[email protected]7f6f44c2011-12-14 13:23:382145 content::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:372146 window_->RotatePaneFocus(true);
2147}
2148
2149void Browser::FocusPreviousPane() {
[email protected]7f6f44c2011-12-14 13:23:382150 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:372151 window_->RotatePaneFocus(false);
2152}
2153
[email protected]84214982008-12-10 18:49:102154void Browser::FocusSearch() {
2155 // TODO(beng): replace this with FocusLocationBar
[email protected]7f6f44c2011-12-14 13:23:382156 content::RecordAction(UserMetricsAction("FocusSearch"));
[email protected]7745b822009-01-27 20:15:352157 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:102158}
2159
2160void Browser::OpenFile() {
[email protected]7f6f44c2011-12-14 13:23:382161 content::RecordAction(UserMetricsAction("OpenFile"));
[email protected]84214982008-12-10 18:49:102162 if (!select_file_dialog_.get())
2163 select_file_dialog_ = SelectFileDialog::Create(this);
2164
[email protected]35896a32010-06-09 08:42:512165 const FilePath directory = profile_->last_selected_directory();
2166
[email protected]84214982008-12-10 18:49:102167 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:562168 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:102169 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:512170 string16(), directory,
[email protected]b949f1112009-04-12 20:03:082171 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]4ca15302012-01-03 05:53:202172 GetSelectedWebContents(),
[email protected]d56bcd22009-03-16 19:51:562173 parent_window, NULL);
[email protected]84214982008-12-10 18:49:102174}
2175
2176void Browser::OpenCreateShortcutsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382177 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:472178#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:492179 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
2180 DCHECK(current_tab &&
[email protected]d9083482012-01-06 00:38:462181 web_app::IsValidUrl(current_tab->web_contents()->GetURL())) <<
[email protected]3c9e1872010-11-18 16:17:492182 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:512183
[email protected]10f417c52011-12-28 21:04:232184 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:462185 current_tab->web_contents()->GetController().GetLastCommittedEntry();
[email protected]ed5431872009-11-17 08:39:512186 if (!entry)
2187 return;
2188
[email protected]eabfdae92009-12-11 06:13:512189 // RVH's GetApplicationInfo should not be called before it returns.
2190 DCHECK(pending_web_app_action_ == NONE);
2191 pending_web_app_action_ = CREATE_SHORTCUT;
2192
[email protected]a2cf65eb2010-01-18 08:20:382193 // Start fetching web app info for CreateApplicationShortcut dialog and show
2194 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]36fc0392011-12-25 03:59:512195 current_tab->extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]98f6e022009-06-05 22:49:532196#else
2197 NOTIMPLEMENTED();
2198#endif
[email protected]36b6dcb2008-11-12 01:19:572199}
2200
[email protected]2a8a98122010-07-16 11:58:482201void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
[email protected]e3791ce92011-08-09 01:03:322202 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
[email protected]7f6f44c2011-12-14 13:23:382203 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
[email protected]e3791ce92011-08-09 01:03:322204 else
[email protected]7f6f44c2011-12-14 13:23:382205 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]e3791ce92011-08-09 01:03:322206
[email protected]aebdd072011-07-07 12:36:592207 DevToolsWindow::ToggleDevToolsWindow(
[email protected]41f022e2012-01-31 05:56:402208 GetSelectedWebContents()->GetRenderViewHost(),
[email protected]4a63e242011-12-12 15:23:082209 action);
[email protected]fbd77592008-11-12 20:50:272210}
2211
[email protected]adb6a84d2011-02-07 16:58:402212void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]7f6f44c2011-12-14 13:23:382213 content::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:402214 if (highlight_background_resources)
2215 window_->ShowBackgroundPages();
2216 else
2217 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:102218}
2219
[email protected]daa9e382012-01-06 00:30:342220void Browser::OpenFeedbackDialog() {
2221 content::RecordAction(UserMetricsAction("Feedback"));
2222 browser::ShowHtmlFeedbackView(this, std::string(), std::string());
[email protected]84214982008-12-10 18:49:102223}
[email protected]44b2c8852009-03-18 00:57:492224
[email protected]84214982008-12-10 18:49:102225void Browser::ToggleBookmarkBar() {
[email protected]7f6f44c2011-12-14 13:23:382226 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:102227 window_->ToggleBookmarkBar();
2228}
2229
[email protected]84214982008-12-10 18:49:102230void Browser::OpenBookmarkManager() {
[email protected]7f6f44c2011-12-14 13:23:382231 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
2232 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]0af8f132011-07-16 01:37:022233 ShowSingletonTabOverwritingNTP(
[email protected]a179fac72011-08-29 22:22:422234 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIBookmarksURL)));
[email protected]0af8f132011-07-16 01:37:022235}
2236
[email protected]4c9ee222011-08-17 19:51:352237void Browser::OpenBookmarkManagerWithHash(const std::string& action,
2238 int64 node_id) {
[email protected]7f6f44c2011-12-14 13:23:382239 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
2240 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]f6c13362011-08-16 12:39:522241 browser::NavigateParams params(GetSingletonTabNavigateParams(
2242 GURL(chrome::kChromeUIBookmarksURL).Resolve(
[email protected]4c9ee222011-08-17 19:51:352243 StringPrintf("/#%s%s", action.c_str(),
2244 base::Int64ToString(node_id).c_str()))));
[email protected]f6c13362011-08-16 12:39:522245 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2246 ShowSingletonTabOverwritingNTP(params);
[email protected]84214982008-12-10 18:49:102247}
[email protected]8bf80e922009-03-09 20:56:362248
[email protected]4c9ee222011-08-17 19:51:352249void Browser::OpenBookmarkManagerForNode(int64 node_id) {
2250 OpenBookmarkManagerWithHash("", node_id);
2251}
2252
2253void Browser::OpenBookmarkManagerEditNode(int64 node_id) {
2254 OpenBookmarkManagerWithHash("e=", node_id);
2255}
2256
[email protected]4fdf6742012-01-10 20:14:362257bool Browser::MaybeCreateBackgroundContents(int route_id,
2258 SiteInstance* site,
2259 const GURL& opener_url,
2260 const string16& frame_name) {
2261 ExtensionService* extensions_service = profile_->GetExtensionService();
2262
2263 if (!opener_url.is_valid() ||
2264 frame_name.empty() ||
2265 !extensions_service ||
2266 !extensions_service->is_ready())
2267 return false;
2268
2269 // Only hosted apps have web extents, so this ensures that only hosted apps
2270 // can create BackgroundContents. We don't have to check for background
2271 // permission as that is checked in RenderMessageFilter when the CreateWindow
2272 // message is processed.
2273 const Extension* extension =
2274 extensions_service->extensions()->GetHostedAppByURL(
2275 ExtensionURLInfo(opener_url));
2276 if (!extension)
2277 return false;
2278
2279 // No BackgroundContents allowed if BackgroundContentsService doesn't exist.
2280 BackgroundContentsService* service =
2281 BackgroundContentsServiceFactory::GetForProfile(profile_);
2282 if (!service)
2283 return false;
2284
2285 // Ensure that we're trying to open this from the extension's process.
2286 extensions::ProcessMap* process_map = extensions_service->process_map();
2287 if (!site->GetProcess() ||
2288 !process_map->Contains(extension->id(), site->GetProcess()->GetID())) {
2289 return false;
2290 }
2291
2292 // Only allow a single background contents per app. If one already exists,
2293 // close it (even if it was specified in the manifest).
2294 BackgroundContents* existing =
2295 service->GetAppBackgroundContents(ASCIIToUTF16(extension->id()));
2296 if (existing) {
2297 DLOG(INFO) << "Closing existing BackgroundContents for " << opener_url;
2298 delete existing;
2299 }
2300
2301 // Passed all the checks, so this should be created as a BackgroundContents.
2302 BackgroundContents* contents =
2303 service->CreateBackgroundContents(site, route_id, profile_, frame_name,
2304 ASCIIToUTF16(extension->id()));
2305 return contents != NULL;
2306}
2307
[email protected]fdb98512009-08-26 01:37:102308void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:122309 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:102310 window_->ShowAppMenu();
2311}
2312
[email protected]7d2d08152011-10-25 22:58:472313void Browser::ShowAvatarMenu() {
2314 window_->ShowAvatarBubbleFromAvatarButton();
2315}
2316
[email protected]8bf80e922009-03-09 20:56:362317void Browser::ShowHistoryTab() {
[email protected]7f6f44c2011-12-14 13:23:382318 content::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]ddddfda2011-07-14 23:19:392319 ShowSingletonTabOverwritingNTP(
2320 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIHistoryURL)));
[email protected]8bf80e922009-03-09 20:56:362321}
[email protected]84214982008-12-10 18:49:102322
2323void Browser::ShowDownloadsTab() {
[email protected]7f6f44c2011-12-14 13:23:382324 content::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]efda32f92011-07-06 22:47:042325#if !defined(OS_CHROMEOS)
2326 // ChromiumOS uses ActiveDownloadsUI instead of of DownloadShelf.
[email protected]3d037ce72011-04-04 17:43:452327 if (window()) {
2328 DownloadShelf* shelf = window()->GetDownloadShelf();
2329 if (shelf->IsShowing())
2330 shelf->Close();
2331 }
[email protected]efda32f92011-07-06 22:47:042332#endif
[email protected]ddddfda2011-07-14 23:19:392333 ShowSingletonTabOverwritingNTP(
2334 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIDownloadsURL)));
[email protected]84214982008-12-10 18:49:102335}
2336
[email protected]34085a32009-11-06 22:49:482337void Browser::ShowExtensionsTab() {
[email protected]7f6f44c2011-12-14 13:23:382338 content::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]fa12e2d2012-02-06 21:03:102339 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableUberPage)) {
[email protected]f5ec7242012-01-27 07:15:152340 ShowOptionsTab(chrome::kExtensionsSubPage);
2341 } else {
2342 browser::NavigateParams params(GetSingletonTabNavigateParams(
2343 GURL(std::string(chrome::kChromeUIUberURL) +
2344 chrome::kChromeUIExtensionsHost)));
2345 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2346 ShowSingletonTabOverwritingNTP(params);
2347 }
[email protected]34085a32009-11-06 22:49:482348}
2349
[email protected]c1bbaa82010-11-08 11:17:052350void Browser::ShowAboutConflictsTab() {
[email protected]7f6f44c2011-12-14 13:23:382351 content::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:492352 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:052353}
2354
[email protected]d9083482012-01-06 00:38:462355void Browser::ShowBrokenPageTab(WebContents* contents) {
[email protected]daa9e382012-01-06 00:30:342356 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]10e457c2010-04-29 03:35:232357 string16 page_title = contents->GetTitle();
[email protected]10f417c52011-12-28 21:04:232358 NavigationEntry* entry = contents->GetController().GetActiveEntry();
[email protected]10e457c2010-04-29 03:35:232359 if (!entry)
2360 return;
[email protected]36fc0392011-12-25 03:59:512361 std::string page_url = entry->GetURL().spec();
[email protected]10e457c2010-04-29 03:35:232362 std::vector<std::string> subst;
2363 subst.push_back(UTF16ToASCII(page_title));
2364 subst.push_back(page_url);
2365 std::string report_page_url =
2366 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:492367 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:232368}
2369
[email protected]12e816bde2010-09-14 19:59:292370void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]fa12e2d2012-02-06 21:03:102371 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableUberPage)) {
[email protected]f5ec7242012-01-27 07:15:152372 browser::NavigateParams params(GetSingletonTabNavigateParams(
2373 GURL(chrome::kChromeUISettingsURL + sub_page)));
2374 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2375 ShowSingletonTabOverwritingNTP(params);
2376 } else {
[email protected]ba481132012-02-01 08:18:162377 std::string url;
2378 if (sub_page == chrome::kExtensionsSubPage) {
2379 url = std::string(chrome::kChromeUIUberURL) +
2380 chrome::kChromeUIExtensionsHost;
2381 } else {
2382 url = std::string(chrome::kChromeUIUberURL) +
2383 chrome::kChromeUISettingsHost + '/' + sub_page;
2384 }
2385 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
[email protected]f5ec7242012-01-27 07:15:152386 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2387 ShowSingletonTabOverwritingNTP(params);
2388 }
[email protected]4a42d272010-06-18 01:29:422389}
2390
[email protected]84214982008-12-10 18:49:102391void Browser::OpenClearBrowsingDataDialog() {
[email protected]7f6f44c2011-12-14 13:23:382392 content::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:052393 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:102394}
2395
[email protected]84214982008-12-10 18:49:102396void Browser::OpenOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382397 content::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]fcca741b2011-06-17 22:46:372398 ShowOptionsTab("");
[email protected]fbd77592008-11-12 20:50:272399}
2400
2401void Browser::OpenPasswordManager() {
[email protected]7f6f44c2011-12-14 13:23:382402 content::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:042403 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272404}
2405
[email protected]1bdf29e2009-05-11 23:45:252406void Browser::OpenImportSettingsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382407 content::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052408 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252409}
[email protected]1bdf29e2009-05-11 23:45:252410
[email protected]b99081b2011-03-10 17:43:472411void Browser::OpenInstantConfirmDialog() {
2412 ShowOptionsTab(chrome::kInstantConfirmPage);
2413}
2414
[email protected]fbd77592008-11-12 20:50:272415void Browser::OpenAboutChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382416 content::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]c3e589d2012-02-16 22:24:572417 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableUberPage)) {
[email protected]976e69f2010-08-13 18:28:172418#if defined(OS_CHROMEOS)
[email protected]c3e589d2012-02-16 22:24:572419 std::string chrome_settings(chrome::kChromeUISettingsURL);
2420 ShowSingletonTab(
2421 GURL(chrome_settings.append(chrome::kAboutOptionsSubPage)));
[email protected]976e69f2010-08-13 18:28:172422#else
[email protected]c3e589d2012-02-16 22:24:572423 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:172424#endif
[email protected]c3e589d2012-02-16 22:24:572425 } else {
[email protected]08b25962012-02-21 22:37:022426#if !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]c3e589d2012-02-16 22:24:572427 ShowSingletonTab(GURL(chrome::kChromeUIUberURL));
[email protected]4ea87862012-02-21 19:45:102428#else
2429 // crbug.com/115123.
2430 window_->ShowAboutChromeDialog();
2431#endif
[email protected]c3e589d2012-02-16 22:24:572432 }
[email protected]fbd77592008-11-12 20:50:272433}
2434
[email protected]b1b73942010-05-26 20:11:542435void Browser::OpenUpdateChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382436 content::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542437 window_->ShowUpdateChromeDialog();
2438}
2439
[email protected]202802e42011-07-06 11:40:462440void Browser::ShowHelpTab() {
[email protected]7f6f44c2011-12-14 13:23:382441 content::RecordAction(UserMetricsAction("ShowHelpTab"));
[email protected]adc8e852012-01-29 08:58:222442 ShowSingletonTab(GURL(chrome::kChromeHelpURL));
[email protected]fbd77592008-11-12 20:50:272443}
2444
[email protected]31cc1c022010-10-15 20:03:472445void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202446 OpenURL(OpenURLParams(
2447 GURL(kPrivacyDashboardUrl), Referrer(),
2448 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false));
[email protected]31cc1c022010-10-15 20:03:472449 window_->Activate();
2450}
2451
[email protected]663bd9e2011-03-21 01:07:012452void Browser::OpenAutofillHelpTabAndActivate() {
[email protected]adc8e852012-01-29 08:58:222453 AddSelectedTabWithURL(GURL(chrome::kAutofillHelpURL),
2454 content::PAGE_TRANSITION_LINK);
[email protected]bb8fe2d2010-06-28 20:04:222455}
2456
[email protected]024617a2010-08-20 05:08:052457void Browser::OpenSearchEngineOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382458 content::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052459 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052460}
2461
[email protected]45c52c9d2011-07-19 12:08:142462#if defined(FILE_MANAGER_EXTENSION)
[email protected]ec2fd5a2011-04-30 06:16:052463void Browser::OpenFileManager() {
[email protected]7f6f44c2011-12-14 13:23:382464 content::RecordAction(UserMetricsAction("OpenFileManager"));
[email protected]fc31b4b2012-02-01 13:19:562465 OpenURL(OpenURLParams(GURL(chrome::kChromeUIFileManagerURL), Referrer(),
2466 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false));
[email protected]ec2fd5a2011-04-30 06:16:052467}
[email protected]45c52c9d2011-07-19 12:08:142468#endif
[email protected]ec2fd5a2011-04-30 06:16:052469
[email protected]45c52c9d2011-07-19 12:08:142470#if defined(OS_CHROMEOS)
[email protected]05a44b6e2011-12-01 07:52:322471void Browser::LockScreen() {
[email protected]7f6f44c2011-12-14 13:23:382472 content::RecordAction(UserMetricsAction("LockScreen"));
[email protected]b0cfc1c2011-12-15 13:16:192473 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
[email protected]05a44b6e2011-12-01 07:52:322474 NotifyScreenLockRequested();
2475}
2476
[email protected]2166c432011-12-07 20:18:282477void Browser::Shutdown() {
[email protected]7f6f44c2011-12-14 13:23:382478 content::RecordAction(UserMetricsAction("Shutdown"));
[email protected]2166c432011-12-07 20:18:282479 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
2480 RequestShutdown();
2481}
2482
[email protected]b7a0efb12012-02-22 00:43:222483void Browser::OpenAdvancedOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382484 content::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"));
[email protected]b7a0efb12012-02-22 00:43:222485 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableUberPage))
2486 ShowOptionsTab(chrome::kSystemOptionsSubPage);
2487 else
2488 ShowOptionsTab(chrome::kAdvancedOptionsSubPage);
[email protected]5dcbc02f2010-01-26 22:32:062489}
2490
2491void Browser::OpenInternetOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382492 content::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"));
[email protected]445177652011-03-09 02:04:052493 ShowOptionsTab(chrome::kInternetOptionsSubPage);
[email protected]024617a2010-08-20 05:08:052494}
2495
2496void Browser::OpenLanguageOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382497 content::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"));
[email protected]445177652011-03-09 02:04:052498 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
[email protected]be715072009-07-07 15:43:202499}
[email protected]46b92f852010-10-06 13:12:052500
2501void Browser::OpenSystemTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202502 OpenURL(OpenURLParams(
2503 GURL(chrome::kChromeUISystemInfoURL), Referrer(), NEW_FOREGROUND_TAB,
2504 content::PAGE_TRANSITION_LINK, false));
[email protected]46b92f852010-10-06 13:12:052505 window_->Activate();
2506}
2507
[email protected]38017612010-10-13 18:46:002508void Browser::OpenMobilePlanTabAndActivate() {
[email protected]e7137b2c2011-10-24 20:16:552509 if (CommandLine::ForCurrentProcess()->HasSwitch(
2510 switches::kEnableMobileSetupDialog)) {
2511 window_->ShowMobileSetup();
2512 } else {
[email protected]e5d549d2011-12-28 01:29:202513 OpenURL(OpenURLParams(
2514 GURL(chrome::kChromeUIMobileSetupURL), Referrer(), NEW_FOREGROUND_TAB,
2515 content::PAGE_TRANSITION_LINK, false));
[email protected]e7137b2c2011-10-24 20:16:552516 window_->Activate();
2517 }
[email protected]38017612010-10-13 18:46:002518}
[email protected]be715072009-07-07 15:43:202519#endif
2520
[email protected]598e6c212012-02-01 04:57:562521#if defined(OS_CHROMEOS) && defined(USE_AURA)
2522void Browser::OpenCrosh() {
2523 GURL crosh_url = TerminalExtensionHelper::GetCroshExtensionURL(profile_);
2524 if (!crosh_url.is_valid())
2525 return;
2526 OpenURL(OpenURLParams(crosh_url, Referrer(), NEW_FOREGROUND_TAB,
2527 content::PAGE_TRANSITION_GENERATED,
2528 false));
2529}
2530#endif
2531
[email protected]a003d8e2010-10-02 21:03:352532void Browser::OpenPluginsTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202533 OpenURL(OpenURLParams(
2534 GURL(chrome::kChromeUIPluginsURL), Referrer(), NEW_FOREGROUND_TAB,
2535 content::PAGE_TRANSITION_LINK, false));
[email protected]a003d8e2010-10-02 21:03:352536 window_->Activate();
2537}
2538
[email protected]36b6dcb2008-11-12 01:19:572539///////////////////////////////////////////////////////////////////////////////
2540
2541// static
[email protected]79117172009-08-28 16:11:442542void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542543 const PrefService::Preference* home_page_pref =
2544 prefs->FindPreference(prefs::kHomePage);
2545 if (home_page_pref &&
2546 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192547 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:332548 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:192549 GoogleURLTracker::kDefaultGoogleHomepage);
2550 }
[email protected]8fe6e1c2010-05-27 08:21:542551 const PrefService::Preference* home_page_is_new_tab_page_pref =
2552 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2553 if (home_page_is_new_tab_page_pref &&
2554 !home_page_is_new_tab_page_pref->IsManaged() &&
2555 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332556 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442557}
2558
2559// static
[email protected]36b6dcb2008-11-12 01:19:572560void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572561 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]d9898912011-04-15 21:10:002562 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]4e72ebb2011-10-18 05:02:182563 prefs->RegisterBooleanPref(prefs::kShouldShowFirstRunBubble, false);
[email protected]47c7ec82012-01-18 03:29:212564 prefs->RegisterBooleanPref(prefs::kPrintPreviewDisabled,
2565#if defined(GOOGLE_CHROME_BUILD)
2566 false
2567#else
2568 true
2569#endif
2570 );
[email protected]36b6dcb2008-11-12 01:19:572571}
2572
2573// static
2574void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182575 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]d36f941b2011-05-09 06:19:162576 chrome::kChromeUINewTabURL,
2577 PrefService::SYNCABLE_PREF);
[email protected]6c6b02d2011-09-02 03:36:472578 prefs->RegisterBooleanPref(prefs::kHomePageChanged,
2579 false,
2580 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162581 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2582 true,
2583 PrefService::SYNCABLE_PREF);
2584 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2585 false,
2586 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092587#if defined(OS_MACOSX)
2588 // This really belongs in platform code, but there's no good place to
2589 // initialize it between the time when the AppController is created
2590 // (where there's no profile) and the time the controller gets another
2591 // crack at the start of the main event loop. By that time, BrowserInit
2592 // has already created the browser window, and it's too late: we need the
2593 // pref to be already initialized. Doing it here also saves us from having
2594 // to hard-code pref registration in the several unit tests that use
2595 // this preference.
[email protected]d36f941b2011-05-09 06:19:162596 prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
2597 false,
2598 PrefService::SYNCABLE_PREF);
2599 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2600 true,
2601 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092602#endif
[email protected]d36f941b2011-05-09 06:19:162603 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2604 true,
2605 PrefService::SYNCABLE_PREF);
2606 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2607 true,
2608 PrefService::SYNCABLE_PREF);
2609 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2610 true,
2611 PrefService::SYNCABLE_PREF);
2612 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2613 true,
2614 PrefService::SYNCABLE_PREF);
2615 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2616 false,
2617 PrefService::SYNCABLE_PREF);
2618 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2619 false,
2620 PrefService::SYNCABLE_PREF);
2621 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2622 0,
2623 PrefService::SYNCABLE_PREF);
2624 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2625 true,
2626 PrefService::UNSYNCABLE_PREF);
2627 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2628 true,
2629 PrefService::UNSYNCABLE_PREF);
2630 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2631 true,
2632 PrefService::UNSYNCABLE_PREF);
2633 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2634 true,
2635 PrefService::UNSYNCABLE_PREF);
2636 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2637 true,
2638 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162639 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2640 true,
2641 PrefService::SYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162642 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2643 std::string(),
2644 PrefService::UNSYNCABLE_PREF);
2645 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2646 true,
2647 PrefService::UNSYNCABLE_PREF);
[email protected]1af419c2011-10-31 23:45:412648 prefs->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled,
2649 true,
2650 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162651 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2652 false,
2653 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162654 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
2655 -1,
2656 PrefService::UNSYNCABLE_PREF);
2657 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2658 PrefService::UNSYNCABLE_PREF);
2659 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2660 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122661 prefs->RegisterBooleanPref(prefs::kImportBookmarks,
2662 true,
2663 PrefService::UNSYNCABLE_PREF);
2664 prefs->RegisterBooleanPref(prefs::kImportHistory,
2665 true,
2666 PrefService::UNSYNCABLE_PREF);
2667 prefs->RegisterBooleanPref(prefs::kImportHomepage,
2668 true,
2669 PrefService::UNSYNCABLE_PREF);
2670 prefs->RegisterBooleanPref(prefs::kImportSearchEngine,
2671 true,
2672 PrefService::UNSYNCABLE_PREF);
2673 prefs->RegisterBooleanPref(prefs::kImportSavedPasswords,
2674 true,
2675 PrefService::UNSYNCABLE_PREF);
[email protected]f6e680912011-09-21 20:26:192676 // The map of timestamps of the last used file browser handlers.
2677 prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers,
2678 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122679
[email protected]2bf2bd92011-03-31 07:12:442680 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162681 // them even though they're only typically controlled via policy.
2682 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2683 false,
2684 PrefService::UNSYNCABLE_PREF);
2685 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2686 false,
2687 PrefService::UNSYNCABLE_PREF);
2688 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2689 false,
2690 PrefService::UNSYNCABLE_PREF);
2691 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2692 true,
2693 PrefService::UNSYNCABLE_PREF);
2694 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2695 true,
2696 PrefService::UNSYNCABLE_PREF);
[email protected]781be952011-08-31 20:22:142697 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled,
2698 true,
2699 PrefService::UNSYNCABLE_PREF);
[email protected]80b07612011-12-12 16:04:302700 prefs->RegisterBooleanPref(prefs::kEnableMemoryInfo,
2701 false,
2702 PrefService::UNSYNCABLE_PREF);
[email protected]f2df3112011-11-18 10:21:482703
2704 // Initialize the disk cache prefs.
2705 prefs->RegisterFilePathPref(prefs::kDiskCacheDir,
2706 FilePath(),
2707 PrefService::UNSYNCABLE_PREF);
2708 prefs->RegisterIntegerPref(prefs::kDiskCacheSize,
2709 0,
2710 PrefService::UNSYNCABLE_PREF);
2711 prefs->RegisterIntegerPref(prefs::kMediaCacheSize,
2712 0,
2713 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572714}
2715
2716// static
[email protected]d9083482012-01-06 00:38:462717bool Browser::RunUnloadEventsHelper(WebContents* contents) {
[email protected]ecc523f62010-09-28 22:45:402718 // If the TabContents is not connected yet, then there's no unload
2719 // handler we can fire even if the TabContents has an unload listener.
2720 // One case where we hit this is in a tab that has an infinite loop
2721 // before load.
[email protected]5aab5e22010-12-08 22:13:292722 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402723 // If the page has unload listeners, then we tell the renderer to fire
2724 // them. Once they have fired, we'll get a message back saying whether
2725 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292726 // with the NeedToFireBeforeUnload bit cleared.
[email protected]151a63d2011-12-20 22:32:522727 contents->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]ecc523f62010-09-28 22:45:402728 return true;
2729 }
2730 return false;
2731}
2732
2733// static
[email protected]36b6dcb2008-11-12 01:19:572734Browser* Browser::GetBrowserForController(
[email protected]c5eed492012-01-04 17:07:502735 const NavigationController* controller, int* index_result) {
[email protected]36b6dcb2008-11-12 01:19:572736 BrowserList::const_iterator it;
2737 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]41f022e2012-01-31 05:56:402738 int index = (*it)->GetIndexOfController(controller);
[email protected]36b6dcb2008-11-12 01:19:572739 if (index != TabStripModel::kNoTab) {
2740 if (index_result)
2741 *index_result = index;
2742 return *it;
2743 }
2744 }
2745
2746 return NULL;
2747}
2748
[email protected]3a29a6e2011-08-24 18:26:212749// static
2750void Browser::RunFileChooserHelper(
[email protected]2a6bc3e2011-12-28 23:51:332751 WebContents* tab, const content::FileChooserParams& params) {
[email protected]3a29a6e2011-08-24 18:26:212752 Profile* profile =
[email protected]627e0512011-12-21 22:55:302753 Profile::FromBrowserContext(tab->GetBrowserContext());
[email protected]9f054aa12011-09-29 19:13:452754 // FileSelectHelper adds a reference to itself and only releases it after
2755 // sending the result message. It won't be destroyed when this reference
2756 // goes out of scope.
2757 scoped_refptr<FileSelectHelper> file_select_helper(
2758 new FileSelectHelper(profile));
[email protected]151a63d2011-12-20 22:32:522759 file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params);
[email protected]3a29a6e2011-08-24 18:26:212760}
2761
2762// static
[email protected]2a6bc3e2011-12-28 23:51:332763void Browser::EnumerateDirectoryHelper(WebContents* tab, int request_id,
[email protected]3a29a6e2011-08-24 18:26:212764 const FilePath& path) {
[email protected]3a29a6e2011-08-24 18:26:212765 Profile* profile =
[email protected]627e0512011-12-21 22:55:302766 Profile::FromBrowserContext(tab->GetBrowserContext());
[email protected]9f054aa12011-09-29 19:13:452767 // FileSelectHelper adds a reference to itself and only releases it after
2768 // sending the result message. It won't be destroyed when this reference
2769 // goes out of scope.
2770 scoped_refptr<FileSelectHelper> file_select_helper(
2771 new FileSelectHelper(profile));
[email protected]3a29a6e2011-08-24 18:26:212772 file_select_helper->EnumerateDirectory(request_id,
[email protected]151a63d2011-12-20 22:32:522773 tab->GetRenderViewHost(),
[email protected]3a29a6e2011-08-24 18:26:212774 path);
2775}
2776
[email protected]7d189022011-08-25 22:54:202777// static
[email protected]2a6bc3e2011-12-28 23:51:332778void Browser::JSOutOfMemoryHelper(WebContents* tab) {
[email protected]7d189022011-08-25 22:54:202779 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2780 tab);
[email protected]2a6bc3e2011-12-28 23:51:332781 if (!tcw)
2782 return;
2783
2784 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2785 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
2786 infobar_helper,
2787 NULL,
2788 l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT),
2789 true));
[email protected]7d189022011-08-25 22:54:202790}
2791
2792// static
[email protected]2a6bc3e2011-12-28 23:51:332793void Browser::RegisterProtocolHandlerHelper(WebContents* tab,
[email protected]7d189022011-08-25 22:54:202794 const std::string& protocol,
2795 const GURL& url,
2796 const string16& title) {
2797 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2798 tab);
2799 if (!tcw || tcw->profile()->IsOffTheRecord())
2800 return;
2801
[email protected]7d189022011-08-25 22:54:202802 ProtocolHandler handler =
2803 ProtocolHandler::CreateProtocolHandler(protocol, url, title);
2804
2805 ProtocolHandlerRegistry* registry =
2806 tcw->profile()->GetProtocolHandlerRegistry();
[email protected]7d189022011-08-25 22:54:202807
[email protected]a50af292011-10-25 03:07:402808 if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) {
[email protected]7f6f44c2011-12-14 13:23:382809 content::RecordAction(
[email protected]7d189022011-08-25 22:54:202810 UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown"));
[email protected]95a33ed62011-09-30 15:07:082811 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
[email protected]d3ddb6d2012-01-06 02:51:172812
2813 RegisterProtocolHandlerInfoBarDelegate* rph_delegate =
[email protected]95a33ed62011-09-30 15:07:082814 new RegisterProtocolHandlerInfoBarDelegate(infobar_helper,
2815 registry,
[email protected]d3ddb6d2012-01-06 02:51:172816 handler);
2817
2818 for (size_t i = 0; i < infobar_helper->infobar_count(); i++) {
2819 InfoBarDelegate* delegate = infobar_helper->GetInfoBarDelegateAt(i);
2820 RegisterProtocolHandlerInfoBarDelegate* cast_delegate =
2821 delegate->AsRegisterProtocolHandlerInfoBarDelegate();
2822 if (cast_delegate != NULL && cast_delegate->IsReplacedBy(rph_delegate)) {
2823 infobar_helper->ReplaceInfoBar(cast_delegate, rph_delegate);
2824 rph_delegate = NULL;
2825 break;
2826 }
2827 }
2828
2829 if (rph_delegate != NULL)
2830 infobar_helper->AddInfoBar(rph_delegate);
[email protected]7d189022011-08-25 22:54:202831 }
2832}
2833
2834// static
[email protected]2a6bc3e2011-12-28 23:51:332835void Browser::RegisterIntentHandlerHelper(WebContents* tab,
[email protected]7d189022011-08-25 22:54:202836 const string16& action,
2837 const string16& type,
2838 const string16& href,
[email protected]63c239322011-10-31 23:56:302839 const string16& title,
2840 const string16& disposition) {
[email protected]8f0bbd62012-02-22 03:37:182841 if (!web_intents::IsWebIntentsEnabled())
[email protected]8229b5e2011-11-18 05:49:562842 return;
2843
[email protected]7d189022011-08-25 22:54:202844 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2845 tab);
2846 if (!tcw || tcw->profile()->IsOffTheRecord())
2847 return;
2848
[email protected]8229b5e2011-11-18 05:49:562849 FaviconService* favicon_service =
2850 tcw->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
[email protected]7d189022011-08-25 22:54:202851
[email protected]8229b5e2011-11-18 05:49:562852 // |href| can be relative to originating URL. Resolve if necessary.
[email protected]7d189022011-08-25 22:54:202853 GURL service_url(href);
2854 if (!service_url.is_valid()) {
2855 const GURL& url = tab->GetURL();
2856 service_url = url.Resolve(href);
2857 }
2858
[email protected]56624422011-11-01 22:11:272859 webkit_glue::WebIntentServiceData service;
[email protected]ce9751942011-09-21 01:57:242860 service.service_url = service_url;
2861 service.action = action;
2862 service.type = type;
2863 service.title = title;
[email protected]63c239322011-10-31 23:56:302864 service.setDisposition(disposition);
2865
[email protected]3826a8a02011-11-11 17:03:312866 RegisterIntentHandlerInfoBarDelegate::MaybeShowIntentInfoBar(
2867 tcw->infobar_tab_helper(),
[email protected]95a33ed62011-09-30 15:07:082868 WebIntentsRegistryFactory::GetForProfile(tcw->profile()),
[email protected]8229b5e2011-11-18 05:49:562869 service,
2870 favicon_service,
2871 tab->GetURL());
[email protected]7d189022011-08-25 22:54:202872}
2873
2874// static
[email protected]2a6bc3e2011-12-28 23:51:332875void Browser::FindReplyHelper(WebContents* tab,
[email protected]b888919c2011-09-02 00:32:162876 int request_id,
2877 int number_of_matches,
2878 const gfx::Rect& selection_rect,
2879 int active_match_ordinal,
2880 bool final_update) {
2881 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2882 tab);
2883 if (!tcw || !tcw->find_tab_helper())
2884 return;
2885
2886 tcw->find_tab_helper()->HandleFindReply(request_id, number_of_matches,
2887 selection_rect, active_match_ordinal,
2888 final_update);
2889}
2890
[email protected]d952a052011-09-06 18:42:452891// static
[email protected]2a6bc3e2011-12-28 23:51:332892void Browser::CrashedPluginHelper(WebContents* tab,
[email protected]d952a052011-09-06 18:42:452893 const FilePath& plugin_path) {
2894 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2895 tab);
2896 if (!tcw)
2897 return;
2898
2899 DCHECK(!plugin_path.value().empty());
2900
2901 string16 plugin_name = plugin_path.LossyDisplayName();
2902 webkit::WebPluginInfo plugin_info;
[email protected]88ca4912011-10-12 14:00:432903 if (PluginService::GetInstance()->GetPluginInfoByPath(
[email protected]d952a052011-09-06 18:42:452904 plugin_path, &plugin_info) &&
2905 !plugin_info.name.empty()) {
2906 plugin_name = plugin_info.name;
2907#if defined(OS_MACOSX)
2908 // Many plugins on the Mac have .plugin in the actual name, which looks
2909 // terrible, so look for that and strip it off if present.
2910 const std::string kPluginExtension = ".plugin";
2911 if (EndsWith(plugin_name, ASCIIToUTF16(kPluginExtension), true))
2912 plugin_name.erase(plugin_name.length() - kPluginExtension.length());
2913#endif // OS_MACOSX
2914 }
2915 gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
2916 IDR_INFOBAR_PLUGIN_CRASHED);
[email protected]95a33ed62011-09-30 15:07:082917 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2918 infobar_helper->AddInfoBar(
[email protected]d952a052011-09-06 18:42:452919 new SimpleAlertInfoBarDelegate(
[email protected]95a33ed62011-09-30 15:07:082920 infobar_helper,
[email protected]d952a052011-09-06 18:42:452921 icon,
2922 l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, plugin_name),
2923 true));
2924}
2925
2926// static
[email protected]2a6bc3e2011-12-28 23:51:332927void Browser::UpdateTargetURLHelper(WebContents* tab, int32 page_id,
[email protected]d952a052011-09-06 18:42:452928 const GURL& url) {
2929 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2930 tab);
2931 if (!tcw || !tcw->prerender_tab_helper())
2932 return;
2933 tcw->prerender_tab_helper()->UpdateTargetURL(page_id, url);
2934}
2935
[email protected]485fba42009-03-24 23:27:292936void Browser::ExecuteCommandWithDisposition(
2937 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142938 // No commands are enabled if there is not yet any selected tab.
2939 // TODO(pkasting): It seems like we should not need this, because either
2940 // most/all commands should not have been enabled yet anyway or the ones that
2941 // are enabled should be global, or safe themselves against having no selected
2942 // tab. However, Ben says he tried removing this before and got lots of
2943 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2944 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492945 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142946 return;
2947
[email protected]59c9f002010-11-19 00:38:052948 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2949 << id;
[email protected]36b6dcb2008-11-12 01:19:572950
[email protected]867125a02009-12-10 06:01:482951 // If command execution is blocked then just record the command and return.
2952 if (block_command_execution_) {
2953 // We actually only allow no more than one blocked command, otherwise some
2954 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062955 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482956 last_blocked_command_id_ = id;
2957 last_blocked_command_disposition_ = disposition;
2958 return;
2959 }
2960
[email protected]fbd77592008-11-12 20:50:272961 // The order of commands in this switch statement must match the function
2962 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572963 switch (id) {
[email protected]84214982008-12-10 18:49:102964 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282965 case IDC_BACK: GoBack(disposition); break;
2966 case IDC_FORWARD: GoForward(disposition); break;
2967 case IDC_RELOAD: Reload(disposition); break;
2968 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2969 case IDC_HOME: Home(disposition); break;
2970 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282971 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572972
[email protected]84214982008-12-10 18:49:102973 // Window management commands
[email protected]cb84d642010-06-10 00:56:282974 case IDC_NEW_WINDOW: NewWindow(); break;
2975 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282976 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2977 case IDC_NEW_TAB: NewTab(); break;
2978 case IDC_CLOSE_TAB: CloseTab(); break;
2979 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2980 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352981 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282982 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2983 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572984 case IDC_SELECT_TAB_0:
2985 case IDC_SELECT_TAB_1:
2986 case IDC_SELECT_TAB_2:
2987 case IDC_SELECT_TAB_3:
2988 case IDC_SELECT_TAB_4:
2989 case IDC_SELECT_TAB_5:
2990 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542991 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282992 break;
2993 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2994 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2995 case IDC_RESTORE_TAB: RestoreTab(); break;
2996 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2997 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
[email protected]184717d52012-02-22 04:46:162998 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
[email protected]d3766932011-08-04 22:18:232999#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:163000 case IDC_PRESENTATION_MODE: TogglePresentationMode(); break;
[email protected]d3766932011-08-04 22:18:233001#endif
[email protected]cb84d642010-06-10 00:56:283002 case IDC_EXIT: Exit(); break;
[email protected]da17b372010-01-22 23:37:223003#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:283004 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:503005 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:053006#endif
[email protected]36b6dcb2008-11-12 01:19:573007
[email protected]84214982008-12-10 18:49:103008 // Page-related commands
[email protected]cb84d642010-06-10 00:56:283009 case IDC_SAVE_PAGE: SavePage(); break;
3010 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
3011 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:123012 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:283013 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
3014 case IDC_PRINT: Print(); break;
[email protected]0996e9b2011-08-26 17:59:013015 case IDC_ADVANCED_PRINT: AdvancedPrint(); break;
[email protected]cb84d642010-06-10 00:56:283016 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:573017 case IDC_ENCODING_UTF8:
3018 case IDC_ENCODING_UTF16LE:
3019 case IDC_ENCODING_ISO88591:
3020 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:493021 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:573022 case IDC_ENCODING_GB18030:
3023 case IDC_ENCODING_BIG5HKSCS:
3024 case IDC_ENCODING_BIG5:
3025 case IDC_ENCODING_KOREAN:
3026 case IDC_ENCODING_SHIFTJIS:
3027 case IDC_ENCODING_ISO2022JP:
3028 case IDC_ENCODING_EUCJP:
3029 case IDC_ENCODING_THAI:
3030 case IDC_ENCODING_ISO885915:
3031 case IDC_ENCODING_MACINTOSH:
3032 case IDC_ENCODING_ISO88592:
3033 case IDC_ENCODING_WINDOWS1250:
3034 case IDC_ENCODING_ISO88595:
3035 case IDC_ENCODING_WINDOWS1251:
3036 case IDC_ENCODING_KOI8R:
3037 case IDC_ENCODING_KOI8U:
3038 case IDC_ENCODING_ISO88597:
3039 case IDC_ENCODING_WINDOWS1253:
3040 case IDC_ENCODING_ISO88594:
3041 case IDC_ENCODING_ISO885913:
3042 case IDC_ENCODING_WINDOWS1257:
3043 case IDC_ENCODING_ISO88593:
3044 case IDC_ENCODING_ISO885910:
3045 case IDC_ENCODING_ISO885914:
3046 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:573047 case IDC_ENCODING_WINDOWS1254:
3048 case IDC_ENCODING_ISO88596:
3049 case IDC_ENCODING_WINDOWS1256:
3050 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:003051 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:573052 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:283053 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:573054
[email protected]84214982008-12-10 18:49:103055 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:283056 case IDC_CUT: Cut(); break;
3057 case IDC_COPY: Copy(); break;
3058 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:103059
3060 // Find-in-page
[email protected]cb84d642010-06-10 00:56:283061 case IDC_FIND: Find(); break;
3062 case IDC_FIND_NEXT: FindNext(); break;
3063 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:103064
3065 // Zoom
[email protected]54087fe2011-10-28 22:02:483066 case IDC_ZOOM_PLUS: Zoom(content::PAGE_ZOOM_IN); break;
3067 case IDC_ZOOM_NORMAL: Zoom(content::PAGE_ZOOM_RESET); break;
3068 case IDC_ZOOM_MINUS: Zoom(content::PAGE_ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:103069
3070 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:283071 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
3072 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
3073 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:523074 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:373075 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
3076 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
3077 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
3078 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:103079
3080 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:283081 case IDC_OPEN_FILE: OpenFile(); break;
3082 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:483083 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
3084 DEVTOOLS_TOGGLE_ACTION_NONE);
3085 break;
3086 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
3087 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
3088 break;
3089 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
3090 DEVTOOLS_TOGGLE_ACTION_INSPECT);
3091 break;
[email protected]adb6a84d2011-02-07 16:58:403092 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
3093 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]daa9e382012-01-06 00:30:343094 case IDC_FEEDBACK: OpenFeedbackDialog(); break;
[email protected]44b2c8852009-03-18 00:57:493095
[email protected]cb84d642010-06-10 00:56:283096 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:253097 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:493098
[email protected]cb84d642010-06-10 00:56:283099 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
3100 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]7d2d08152011-10-25 22:58:473101 case IDC_SHOW_AVATAR_MENU: ShowAvatarMenu(); break;
[email protected]cb84d642010-06-10 00:56:283102 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
3103 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
3104 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
[email protected]cb84d642010-06-10 00:56:283105 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:053106 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:283107 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
3108 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
3109 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:413110 case IDC_ABOUT: OpenAboutChromeDialog(); break;
3111 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:053112 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]202802e42011-07-06 11:40:463113 case IDC_HELP_PAGE: ShowHelpTab(); break;
[email protected]16779842009-07-08 23:45:293114#if defined(OS_CHROMEOS)
[email protected]05a44b6e2011-12-01 07:52:323115 case IDC_LOCK_SCREEN: LockScreen(); break;
[email protected]2166c432011-12-07 20:18:283116 case IDC_SHUTDOWN: Shutdown(); break;
[email protected]ec2fd5a2011-04-30 06:16:053117 case IDC_FILE_MANAGER: OpenFileManager(); break;
[email protected]cb84d642010-06-10 00:56:283118 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:053119 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:203120#endif
[email protected]598e6c212012-02-01 04:57:563121#if defined(OS_CHROMEOS) && defined(USE_AURA)
3122 case IDC_NEW_CROSH_TAB: OpenCrosh(); break;
3123#endif
[email protected]2e2cacc2011-07-12 21:54:263124 case IDC_SHOW_SYNC_SETUP: ShowSyncSetup(); break;
[email protected]afcb43562011-09-02 23:33:383125 case IDC_TOGGLE_SPEECH_INPUT: ToggleSpeechInput(); break;
[email protected]d938aed92009-01-22 19:49:333126
[email protected]36b6dcb2008-11-12 01:19:573127 default:
[email protected]84214982008-12-10 18:49:103128 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:273129 break;
[email protected]36b6dcb2008-11-12 01:19:573130 }
3131}
3132
[email protected]dee11352011-09-05 13:34:083133void Browser::ExecuteCommand(int id, int event_flags) {
3134 ExecuteCommandWithDisposition(
3135 id, browser::DispositionFromEventFlags(event_flags));
3136}
3137
[email protected]3ab6796d32010-12-21 23:56:073138bool Browser::ExecuteCommandIfEnabled(int id) {
3139 if (command_updater_.SupportsCommand(id) &&
3140 command_updater_.IsCommandEnabled(id)) {
3141 ExecuteCommand(id);
3142 return true;
3143 }
3144 return false;
3145}
3146
[email protected]06181422011-02-09 17:44:213147bool Browser::IsReservedCommandOrKey(int command_id,
3148 const NativeWebKeyboardEvent& event) {
[email protected]06181422011-02-09 17:44:213149#if defined(OS_CHROMEOS)
3150 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
3151 // aren't able to block Chrome from performing the standard actions for F1-F4
3152 // (F5-7 are grabbed by other X clients and hence don't need this protection,
3153 // and F8-10 are handled separately in Chrome via a GDK event filter, but
3154 // let's future-proof this).
3155 ui::KeyboardCode key_code =
[email protected]6a1ae6cd2011-02-11 20:06:093156 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]06181422011-02-09 17:44:213157 if (key_code == ui::VKEY_F1 ||
3158 key_code == ui::VKEY_F2 ||
3159 key_code == ui::VKEY_F3 ||
3160 key_code == ui::VKEY_F4 ||
3161 key_code == ui::VKEY_F5 ||
3162 key_code == ui::VKEY_F6 ||
3163 key_code == ui::VKEY_F7 ||
3164 key_code == ui::VKEY_F8 ||
3165 key_code == ui::VKEY_F9 ||
3166 key_code == ui::VKEY_F10) {
[email protected]6a1ae6cd2011-02-11 20:06:093167 return true;
[email protected]06181422011-02-09 17:44:213168 }
3169#endif
3170
[email protected]fa2d2ce22011-09-19 08:21:063171 if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN)
3172 return true;
[email protected]6a1ae6cd2011-02-11 20:06:093173 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:483174 command_id == IDC_CLOSE_WINDOW ||
3175 command_id == IDC_NEW_INCOGNITO_WINDOW ||
3176 command_id == IDC_NEW_TAB ||
3177 command_id == IDC_NEW_WINDOW ||
3178 command_id == IDC_RESTORE_TAB ||
3179 command_id == IDC_SELECT_NEXT_TAB ||
3180 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:553181 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:333182 command_id == IDC_EXIT ||
3183 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:483184}
3185
3186void Browser::SetBlockCommandExecution(bool block) {
3187 block_command_execution_ = block;
3188 if (block) {
3189 last_blocked_command_id_ = -1;
3190 last_blocked_command_disposition_ = CURRENT_TAB;
3191 }
3192}
3193
3194int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
3195 if (disposition)
3196 *disposition = last_blocked_command_disposition_;
3197 return last_blocked_command_id_;
3198}
3199
[email protected]3c9e1872010-11-18 16:17:493200void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]2905f742011-10-13 03:51:583201 content::PageTransition transition,
[email protected]19d9f3a2010-10-14 21:49:363202 bool user_initiated) {
[email protected]41f022e2012-01-31 05:56:403203 tab_handler_->GetTabStripModel()->TabNavigating(contents, transition);
[email protected]19d9f3a2010-10-14 21:49:363204
[email protected]3c9e1872010-11-18 16:17:493205 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:363206 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
3207 // Forcibly reset the location bar if the url is going to change in the
3208 // current tab, since otherwise it won't discard any ongoing user edits,
3209 // since it doesn't realize this is a user-initiated action.
3210 window()->GetLocationBar()->Revert();
3211 }
3212
3213 if (GetStatusBubble())
3214 GetStatusBubble()->Hide();
3215
3216 // Update the location bar. This is synchronous. We specifically don't
3217 // update the load state since the load hasn't started yet and updating it
3218 // will put it out of sync with the actual state like whether we're
3219 // displaying a favicon, which controls the throbber. If we updated it here,
3220 // the throbber will show the default favicon for a split second when
3221 // navigating away from the new tab page.
[email protected]d9083482012-01-06 00:38:463222 ScheduleUIUpdate(contents->web_contents(), content::INVALIDATE_TYPE_URL);
[email protected]19d9f3a2010-10-14 21:49:363223
3224 if (contents_is_selected)
[email protected]d9083482012-01-06 00:38:463225 contents->web_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:363226}
3227
[email protected]36b6dcb2008-11-12 01:19:573228///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:403229// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:363230
[email protected]e5d549d2011-12-28 01:29:203231WebContents* Browser::OpenURL(const OpenURLParams& params) {
[email protected]00c37fc2011-08-02 00:22:503232 return OpenURLFromTab(NULL, params);
[email protected]ecc523f62010-09-28 22:45:403233}
3234
3235///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:293236// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
3237
3238void Browser::ExecuteCommand(int id) {
3239 ExecuteCommandWithDisposition(id, CURRENT_TAB);
3240}
3241
3242///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:403243// Browser, TabHandlerDelegate implementation:
3244
3245Profile* Browser::GetProfile() const {
3246 return profile();
3247}
3248
3249Browser* Browser::AsBrowser() {
3250 return this;
3251}
3252
3253///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573254// Browser, TabStripModelDelegate implementation:
3255
[email protected]3c9e1872010-11-18 16:17:493256TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:583257 return AddBlankTabAt(-1, foreground);
3258}
3259
[email protected]3c9e1872010-11-18 16:17:493260TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:053261 // Time new tab page creation time. We keep track of the timing data in
3262 // TabContents, but we want to include the time it takes to create the
3263 // TabContents object too.
3264 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:333265 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
[email protected]2905f742011-10-13 03:51:583266 content::PAGE_TRANSITION_TYPED);
[email protected]616381f02010-11-02 15:15:333267 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
3268 params.tabstrip_index = index;
3269 browser::Navigate(&params);
[email protected]d9083482012-01-06 00:38:463270 params.target_contents->web_contents()->SetNewTabStartTime(
[email protected]3c9e1872010-11-18 16:17:493271 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:333272 return params.target_contents;
[email protected]15952e462008-11-14 00:29:053273}
3274
[email protected]3c9e1872010-11-18 16:17:493275Browser* Browser::CreateNewStripWithContents(
3276 TabContentsWrapper* detached_contents,
3277 const gfx::Rect& window_bounds,
3278 const DockInfo& dock_info,
3279 bool maximize) {
[email protected]018cf362010-05-05 22:43:223280 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:063281
[email protected]5e495462008-11-20 23:07:413282 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:413283 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
3284 dock_info.AdjustOtherWindowBounds();
3285
[email protected]36b6dcb2008-11-12 01:19:573286 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:143287 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:413288 browser->set_override_bounds(new_window_bounds);
[email protected]400eaf82011-08-22 15:47:393289 browser->set_show_state(
3290 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
[email protected]9800de5e2011-03-11 18:19:493291 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:053292 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:273293 // Make sure the loading state is updated correctly, otherwise the throbber
3294 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:333295 browser->LoadingStateChanged(detached_contents->web_contents());
[email protected]3d1104f2009-03-26 15:30:283296 return browser;
[email protected]36b6dcb2008-11-12 01:19:573297}
3298
3299int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:403300 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
3301 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:573302}
3303
[email protected]3c9e1872010-11-18 16:17:493304TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]3ebe558b2011-12-06 08:05:083305 const GURL& url, const content::Referrer& referrer, Profile* profile,
[email protected]2905f742011-10-13 03:51:583306 content::PageTransition transition, bool defer_load,
[email protected]36b6dcb2008-11-12 01:19:573307 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:493308 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:403309 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:443310 GetSelectedWebContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:573311 if (!defer_load) {
3312 // Load the initial URL before adding the new tab contents to the tab strip
3313 // so that the tab contents has navigation state.
[email protected]d9083482012-01-06 00:38:463314 contents->web_contents()->GetController().LoadURL(
[email protected]4a63e242011-12-12 15:23:083315 url, referrer, transition, std::string());
[email protected]36b6dcb2008-11-12 01:19:573316 }
3317
3318 return contents;
3319}
3320
3321bool Browser::CanDuplicateContentsAt(int index) {
[email protected]c5eed492012-01-04 17:07:503322 NavigationController& nc = GetWebContentsAt(index)->GetController();
[email protected]fbc5e5f92012-01-02 06:08:323323 return nc.GetWebContents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:573324}
3325
3326void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:493327 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:333328 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:123329 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:563330
3331 bool pinned = false;
3332 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
3333 // If this is a tabbed browser, just create a duplicate tab inside the same
3334 // window next to the tab being duplicated.
3335 int index = tab_handler_->GetTabStripModel()->
3336 GetIndexOfTabContents(contents);
[email protected]41f022e2012-01-31 05:56:403337 pinned = IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:413338 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:563339 TabStripModel::ADD_INHERIT_GROUP |
3340 (pinned ? TabStripModel::ADD_PINNED : 0);
3341 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
3342 contents_dupe,
3343 add_types);
3344 } else {
3345 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:143346 if (is_app()) {
3347 CHECK(!is_type_popup());
3348 CHECK(!is_type_panel());
[email protected]5c209242011-06-06 20:36:173349 browser = Browser::CreateForApp(TYPE_POPUP, app_name_, gfx::Rect(),
[email protected]b35b26b32011-05-05 20:35:143350 profile_);
3351 } else if (is_type_popup()) {
[email protected]47b309f2010-12-28 17:35:563352 browser = Browser::CreateForType(TYPE_POPUP, profile_);
3353 }
3354
3355 // Preserve the size of the original window. The new window has already
3356 // been given an offset by the OS, so we shouldn't copy the old bounds.
3357 BrowserWindow* new_window = browser->window();
3358 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
3359 window()->GetRestoredBounds().size()));
3360
[email protected]4e595682011-02-09 17:07:023361 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]47b309f2010-12-28 17:35:563362 // TabContents is invisible and won't size it.
3363 browser->window()->Show();
3364
3365 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:583366 browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK);
[email protected]47b309f2010-12-28 17:35:563367 }
3368
[email protected]92371eb2011-04-28 11:50:153369 SessionService* session_service =
3370 SessionServiceFactory::GetForProfileIfExisting(profile_);
3371 if (session_service)
[email protected]81898992011-06-14 22:15:003372 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:573373}
3374
[email protected]36b6dcb2008-11-12 01:19:573375void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:473376#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:573377 // This is scheduled to run after we return to the message loop because
3378 // otherwise the frame will think the drag session is still active and ignore
3379 // the request.
[email protected]d6a3c772009-01-27 19:41:203380 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:373381 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363382 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]d6a3c772009-01-27 19:41:203383#endif
initial.commit09911bf2008-07-26 23:55:293384}
3385
[email protected]3c9e1872010-11-18 16:17:493386void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:583387 // We don't create historical tabs for incognito windows or windows without
3388 // profiles.
[email protected]92371eb2011-04-28 11:50:153389 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:583390 return;
[email protected]92371eb2011-04-28 11:50:153391
[email protected]0d4ef7f2011-05-12 22:38:573392 // We don't create historical tabs for print preview tabs.
[email protected]d9083482012-01-06 00:38:463393 if (contents->web_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
[email protected]0d4ef7f2011-05-12 22:38:573394 return;
3395
[email protected]92371eb2011-04-28 11:50:153396 TabRestoreService* service =
3397 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:583398
[email protected]fb5ff422010-05-03 20:46:103399 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:153400 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]d9083482012-01-06 00:38:463401 service->CreateHistoricalTab(&contents->web_contents()->GetController(),
[email protected]fb7da4132011-03-15 15:51:003402 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:583403 }
3404}
3405
[email protected]3c9e1872010-11-18 16:17:493406bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
[email protected]d9083482012-01-06 00:38:463407 return Browser::RunUnloadEventsHelper(contents->web_contents());
[email protected]505323e22009-01-24 02:47:583408}
3409
[email protected]2a6bc3e2011-12-28 23:51:333410bool Browser::CanReloadContents(WebContents* source) const {
[email protected]b35b26b32011-05-05 20:35:143411 return !is_devtools();
[email protected]8e48e982009-12-25 11:22:463412}
3413
[email protected]2db5a2042011-04-26 17:13:473414bool Browser::CanCloseContents(std::vector<int>* indices) {
3415 DCHECK(!indices->empty());
3416 TabCloseableStateWatcher* watcher =
3417 g_browser_process->tab_closeable_state_watcher();
3418 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
3419 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:043420 return false;
[email protected]2db5a2042011-04-26 17:13:473421 // Now, handle cases where at least one tab can be closed.
3422 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:103423 // in-progress downloads.
3424 // Note that the next call when it returns false will ask the user for
3425 // confirmation before closing the browser if the user decides so.
[email protected]41f022e2012-01-31 05:56:403426 if (tab_count() == static_cast<int>(indices->size()) &&
[email protected]2db5a2042011-04-26 17:13:473427 !CanCloseWithInProgressDownloads()) {
3428 indices->clear();
3429 can_close_all = false;
3430 }
3431 return can_close_all;
[email protected]940ccb22009-04-30 17:11:103432}
[email protected]d6a3c772009-01-27 19:41:203433
[email protected]a206b442009-10-08 23:20:203434bool Browser::CanBookmarkAllTabs() const {
3435 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:583436 return (model && model->IsLoaded()) &&
3437 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:043438 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:203439}
3440
[email protected]b3ac5c82009-10-08 20:56:543441void Browser::BookmarkAllTabs() {
[email protected]9d603392011-11-18 05:45:283442 BookmarkEditor::ShowBookmarkAllTabsDialog(this);
[email protected]b3ac5c82009-10-08 20:56:543443}
3444
[email protected]0b4d3382010-07-14 16:13:043445bool Browser::CanCloseTab() const {
3446 TabCloseableStateWatcher* watcher =
3447 g_browser_process->tab_closeable_state_watcher();
3448 return !watcher || watcher->CanCloseTab(this);
3449}
3450
[email protected]b283a7532010-08-12 21:24:593451bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:443452 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
3453 // for those windows, we already have a big icon in the top-left outside any
3454 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:333455 return true;
[email protected]b283a7532010-08-12 21:24:593456}
3457
[email protected]2d46c842008-11-14 19:24:313458///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573459// Browser, TabStripModelObserver implementation:
3460
[email protected]3c9e1872010-11-18 16:17:493461void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573462 int index,
3463 bool foreground) {
[email protected]9219d262011-02-15 21:05:123464 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:003465 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:583466
[email protected]c37e3b62010-01-22 00:15:173467 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:573468
[email protected]159f7762008-12-19 14:58:273469 // Make sure the loading state is updated correctly, otherwise the throbber
3470 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:333471 LoadingStateChanged(contents->web_contents());
[email protected]159f7762008-12-19 14:58:273472
[email protected]36b6dcb2008-11-12 01:19:573473 // If the tab crashes in the beforeunload or unload handler, it won't be
3474 // able to ack. But we know we can close it.
[email protected]fbc5e5f92012-01-02 06:08:323475 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
3476 content::Source<WebContents>(contents->web_contents()));
[email protected]93f230e02011-06-01 14:40:003477
[email protected]432115822011-07-10 15:52:273478 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:323479 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:503480
3481 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]fbc5e5f92012-01-02 06:08:323482 content::Source<WebContents>(contents->web_contents()));
[email protected]36b6dcb2008-11-12 01:19:573483}
3484
[email protected]f2cc7382010-10-15 18:03:053485void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:493486 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:053487 int index) {
[email protected]d9083482012-01-06 00:38:463488 fullscreen_controller_->OnTabClosing(contents->web_contents());
[email protected]ad50def52011-10-19 23:17:073489 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273490 content::NOTIFICATION_TAB_CLOSING,
[email protected]c5eed492012-01-04 17:07:503491 content::Source<NavigationController>(
[email protected]cca0f1e2012-01-03 18:27:463492 &contents->web_contents()->GetController()),
[email protected]ad50def52011-10-19 23:17:073493 content::NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:573494
3495 // Sever the TabContents' connection back to us.
[email protected]9219d262011-02-15 21:05:123496 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:573497}
3498
[email protected]3c9e1872010-11-18 16:17:493499void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:173500 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:573501}
3502
[email protected]9ac8a242011-06-07 19:42:523503void Browser::TabDeactivated(TabContentsWrapper* contents) {
[email protected]01a5a762011-11-21 05:40:553504 fullscreen_controller_->OnTabDeactivated(contents);
[email protected]6b723f82010-10-05 20:14:273505 if (instant())
[email protected]3e481282011-10-15 15:39:503506 instant()->Hide();
[email protected]03bb953d2010-09-14 21:38:303507
[email protected]85ff2c42009-05-29 21:22:033508 // Save what the user's currently typing, so it can be restored when we
3509 // switch back to this tab.
[email protected]83a2610a2012-01-05 01:00:273510 window_->GetLocationBar()->SaveStateToContents(contents->web_contents());
[email protected]85ff2c42009-05-29 21:22:033511}
3512
[email protected]3aca95d42011-05-24 22:06:543513void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
3514 TabContentsWrapper* new_contents,
3515 int index,
3516 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:163517 // On some platforms we want to automatically reload tabs that are
3518 // killed when the user selects them.
[email protected]d9083482012-01-06 00:38:463519 if (user_gesture && new_contents->web_contents()->GetCrashedStatus() ==
[email protected]a8f024392011-01-13 21:50:163520 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
3521 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:563522 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]a8f024392011-01-13 21:50:163523 Reload(CURRENT_TAB);
[email protected]f8a35772011-02-02 23:17:563524 return;
3525 }
[email protected]a8f024392011-01-13 21:50:163526 }
3527
[email protected]002efb042011-10-07 17:30:243528 // Discarded tabs always get reloaded.
3529 if (IsTabDiscarded(index)) {
3530 Reload(CURRENT_TAB);
3531 return;
3532 }
3533
[email protected]36b6dcb2008-11-12 01:19:573534 // If we have any update pending, do it now.
[email protected]24f1477532011-11-22 22:55:363535 if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
[email protected]36b6dcb2008-11-12 01:19:573536 ProcessPendingUIUpdates();
3537
[email protected]36b6dcb2008-11-12 01:19:573538 // Propagate the profile to the location bar.
3539 UpdateToolbar(true);
3540
[email protected]943d8122010-06-11 02:13:453541 // Update reload/stop state.
[email protected]d9083482012-01-06 00:38:463542 UpdateReloadStopState(new_contents->web_contents()->IsLoading(), true);
[email protected]36b6dcb2008-11-12 01:19:573543
[email protected]84214982008-12-10 18:49:103544 // Update commands to reflect current state.
3545 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:573546
3547 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:103548 StatusBubble* status_bubble = GetStatusBubble();
3549 if (status_bubble) {
3550 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:573551
[email protected]be3877f2009-01-14 15:51:103552 // Show the loading state (if any).
[email protected]51d83bdf2011-12-09 16:09:293553 status_bubble->SetStatus(
3554 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:103555 }
[email protected]36b6dcb2008-11-12 01:19:573556
[email protected]24db8a072009-10-29 20:35:373557 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:243558 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:173559 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:583560 }
3561
[email protected]36b6dcb2008-11-12 01:19:573562 // Update sessions. Don't force creation of sessions. If sessions doesn't
3563 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:153564 SessionService* session_service =
3565 SessionServiceFactory::GetForProfileIfExisting(profile_);
3566 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
[email protected]41f022e2012-01-31 05:56:403567 session_service->SetSelectedTabInWindow(session_id(), active_index());
[email protected]36b6dcb2008-11-12 01:19:573568 }
[email protected]09b29342011-06-24 19:18:483569
3570 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:573571}
3572
[email protected]3c9e1872010-11-18 16:17:493573void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573574 int from_index,
[email protected]1a242c32010-02-02 21:20:543575 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:573576 DCHECK(from_index >= 0 && to_index >= 0);
3577 // Notify the history service.
3578 SyncHistoryWithTabs(std::min(from_index, to_index));
3579}
3580
[email protected]da25dd52011-01-11 19:06:303581void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
3582 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:493583 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:433584 int index) {
[email protected]c37e3b62010-01-22 00:15:173585 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
[email protected]41f022e2012-01-31 05:56:403586 TabInsertedAt(new_contents, index, (index == active_index()));
[email protected]c37e3b62010-01-22 00:15:173587
[email protected]a26023822011-12-29 00:23:553588 int entry_count =
[email protected]d9083482012-01-06 00:38:463589 new_contents->web_contents()->GetController().GetEntryCount();
[email protected]c37e3b62010-01-22 00:15:173590 if (entry_count > 0) {
3591 // Send out notification so that observers are updated appropriately.
[email protected]d9083482012-01-06 00:38:463592 new_contents->web_contents()->GetController().NotifyEntryChanged(
3593 new_contents->web_contents()->GetController().GetEntryAtIndex(
[email protected]4a63e242011-12-12 15:23:083594 entry_count - 1),
[email protected]c37e3b62010-01-22 00:15:173595 entry_count - 1);
3596 }
[email protected]47e020a2010-10-15 14:43:373597
[email protected]92371eb2011-04-28 11:50:153598 SessionService* session_service =
3599 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:373600 if (session_service) {
3601 // The new_contents may end up with a different navigation stack. Force
3602 // the session service to update itself.
[email protected]41f022e2012-01-31 05:56:403603 session_service->TabRestored(new_contents, IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373604 }
[email protected]2914600d2011-01-31 23:25:143605
[email protected]0e12d7d2011-12-01 16:21:443606 content::DevToolsManager::GetInstance()->TabReplaced(
[email protected]d9083482012-01-06 00:38:463607 old_contents->web_contents(), new_contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:173608}
3609
[email protected]3c9e1872010-11-18 16:17:493610void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153611 SessionService* session_service =
3612 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093613 if (session_service) {
3614 session_service->SetPinnedState(
3615 session_id(),
[email protected]81898992011-06-14 22:15:003616 GetTabContentsWrapperAt(index)->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:403617 IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093618 }
3619}
3620
[email protected]36b6dcb2008-11-12 01:19:573621void Browser::TabStripEmpty() {
3622 // Close the frame after we return to the message loop (not immediately,
3623 // otherwise it will destroy this object before the stack has a chance to
3624 // cleanly unwind.)
3625 // Note: This will be called several times if TabStripEmpty is called several
3626 // times. This is because it does not close the window if tabs are
3627 // still present.
3628 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3629 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373630 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363631 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]36b6dcb2008-11-12 01:19:573632}
3633
3634///////////////////////////////////////////////////////////////////////////////
[email protected]674bc592011-12-20 23:00:423635// Browser, content::WebContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293636
[email protected]e5d549d2011-12-28 01:29:203637WebContents* Browser::OpenURLFromTab(WebContents* source,
[email protected]00c37fc2011-08-02 00:22:503638 const OpenURLParams& params) {
3639 browser::NavigateParams nav_params(this, params.url, params.transition);
[email protected]41f022e2012-01-31 05:56:403640 nav_params.source_contents = GetTabContentsWrapperAt(
3641 tab_handler_->GetTabStripModel()->GetWrapperIndex(source));
[email protected]cb8fb01a2011-12-05 21:01:143642 nav_params.referrer = params.referrer;
[email protected]00c37fc2011-08-02 00:22:503643 nav_params.disposition = params.disposition;
3644 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
3645 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
3646 nav_params.user_gesture = true;
3647 nav_params.override_encoding = params.override_encoding;
[email protected]e47ae9472011-10-13 19:48:343648 nav_params.is_renderer_initiated = params.is_renderer_initiated;
[email protected]4ad5d77d2011-12-03 02:00:483649 nav_params.transferred_global_request_id =
3650 params.transferred_global_request_id;
[email protected]00c37fc2011-08-02 00:22:503651 browser::Navigate(&nav_params);
3652
3653 return nav_params.target_contents ?
[email protected]d9083482012-01-06 00:38:463654 nav_params.target_contents->web_contents() : NULL;
initial.commit09911bf2008-07-26 23:55:293655}
3656
[email protected]2a6bc3e2011-12-28 23:51:333657void Browser::NavigationStateChanged(const WebContents* source,
initial.commit09911bf2008-07-26 23:55:293658 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293659 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403660 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293661 ScheduleUIUpdate(source, changed_flags);
3662
[email protected]83c2e232011-10-07 21:36:463663 // We can synchronously update commands since they will only change once per
3664 // navigation, so we don't have to worry about flickering. We do, however,
3665 // need to update the command state early on load to always present usable
3666 // actions in the face of slow-to-commit pages.
[email protected]d9083482012-01-06 00:38:463667 if (changed_flags & (content::INVALIDATE_TYPE_URL |
3668 content::INVALIDATE_TYPE_LOAD))
[email protected]84214982008-12-10 18:49:103669 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293670}
3671
[email protected]2a6bc3e2011-12-28 23:51:333672void Browser::AddNewContents(WebContents* source,
3673 WebContents* new_contents,
initial.commit09911bf2008-07-26 23:55:293674 WindowOpenDisposition disposition,
3675 const gfx::Rect& initial_pos,
3676 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373677 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333678 DCHECK(disposition != SAVE_TO_DISK);
3679 // Can't create a new contents for the current tab - invalid case.
3680 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293681
[email protected]e7cfdbd2011-04-22 14:41:373682 TabContentsWrapper* source_wrapper = NULL;
3683 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453684 TabContentsWrapper* new_wrapper =
3685 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
[email protected]2a6bc3e2011-12-28 23:51:333686 if (!new_wrapper) {
[email protected]d9083482012-01-06 00:38:463687 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]2a6bc3e2011-12-28 23:51:333688 }
[email protected]e7cfdbd2011-04-22 14:41:373689 if (source) {
3690 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3691 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3692 }
3693
3694 if (source_wrapper) {
3695 // Handle blocking of all contents.
3696 if (source_blocked_content->all_contents_blocked()) {
3697 source_blocked_content->AddTabContents(new_wrapper,
3698 disposition,
3699 initial_pos,
3700 user_gesture);
3701 return;
3702 }
3703
3704 // Handle blocking of popups.
3705 if ((disposition == NEW_POPUP) && !user_gesture &&
3706 !CommandLine::ForCurrentProcess()->HasSwitch(
3707 switches::kDisablePopupBlocking)) {
3708 // Unrequested popups from normal pages are constrained unless they're in
3709 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363710 GetConstrainingContentsWrapper(source_wrapper)->
3711 blocked_content_tab_helper()->
3712 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373713 return;
3714 }
3715
[email protected]151a63d2011-12-20 22:32:523716 new_contents->GetRenderViewHost()->DisassociateFromPopupCount();
[email protected]e7cfdbd2011-04-22 14:41:373717 }
3718
[email protected]e7cfdbd2011-04-22 14:41:373719 browser::NavigateParams params(this, new_wrapper);
[email protected]41f022e2012-01-31 05:56:403720 params.source_contents = source ? GetTabContentsWrapperAt(
3721 tab_handler_->GetTabStripModel()->GetWrapperIndex(source))
3722 : NULL;
[email protected]3c9e1872010-11-18 16:17:493723 params.disposition = disposition;
3724 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353725 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3726 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493727 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293728}
3729
[email protected]2a6bc3e2011-12-28 23:51:333730void Browser::ActivateContents(WebContents* contents) {
[email protected]41f022e2012-01-31 05:56:403731 ActivateTabAt(tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
3732 false);
[email protected]f3e99e32008-07-30 04:48:393733 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293734}
3735
[email protected]2a6bc3e2011-12-28 23:51:333736void Browser::DeactivateContents(WebContents* contents) {
[email protected]ea42e7782010-08-23 23:58:123737 window_->Deactivate();
3738}
3739
[email protected]2a6bc3e2011-12-28 23:51:333740void Browser::LoadingStateChanged(WebContents* source) {
[email protected]ecc523f62010-09-28 22:45:403741 window_->UpdateLoadingAnimations(
3742 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393743 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293744
[email protected]4ca15302012-01-03 05:53:203745 WebContents* selected_contents = GetSelectedWebContents();
[email protected]3c9e1872010-11-18 16:17:493746 if (source == selected_contents) {
[email protected]f5d978c2011-07-21 14:43:513747 bool is_loading = source->IsLoading();
3748 UpdateReloadStopState(is_loading, false);
[email protected]43d259d2010-09-03 21:37:463749 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443750 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:293751 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463752 }
[email protected]eabfdae92009-12-11 06:13:513753
[email protected]f5d978c2011-07-21 14:43:513754 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333755 // Schedule a shortcut update when web application info is available if
3756 // last committed entry is not NULL. Last committed entry could be NULL
3757 // when an interstitial page is injected (e.g. bad https certificate,
3758 // malware site etc). When this happens, we abort the shortcut update.
[email protected]10f417c52011-12-28 21:04:233759 NavigationEntry* entry = source->GetController().GetLastCommittedEntry();
[email protected]eabfdae92009-12-11 06:13:513760 if (entry) {
[email protected]553602e12011-04-05 17:01:183761 TabContentsWrapper::GetCurrentWrapperForContents(source)->
[email protected]36fc0392011-12-25 03:59:513762 extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]eabfdae92009-12-11 06:13:513763 } else {
3764 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513765 }
3766 }
initial.commit09911bf2008-07-26 23:55:293767 }
3768}
3769
[email protected]a81343d232011-12-27 07:39:203770void Browser::CloseContents(WebContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473771 if (is_attempting_to_close_browser_) {
3772 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063773 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473774 // will go down the slow shutdown path instead of the fast path of killing
3775 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213776 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473777 return;
3778 }
3779
[email protected]3c9e1872010-11-18 16:17:493780 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293781 if (index == TabStripModel::kNoTab) {
3782 NOTREACHED() << "CloseContents called for tab not in our strip";
3783 return;
3784 }
[email protected]ecc523f62010-09-28 22:45:403785 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:393786 index,
3787 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293788}
3789
[email protected]2a6bc3e2011-12-28 23:51:333790void Browser::MoveContents(WebContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143791 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293792 NOTREACHED() << "moving invalid browser type";
3793 return;
3794 }
[email protected]e561e202010-03-24 17:57:123795 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293796}
3797
[email protected]2a6bc3e2011-12-28 23:51:333798void Browser::DetachContents(WebContents* source) {
[email protected]3c9e1872010-11-18 16:17:493799 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313800 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:403801 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313802}
3803
[email protected]2a6bc3e2011-12-28 23:51:333804bool Browser::IsPopupOrPanel(const WebContents* source) const {
initial.commit09911bf2008-07-26 23:55:293805 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143806 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293807}
3808
[email protected]b8595e92009-11-14 01:18:003809void Browser::ContentsMouseEvent(
[email protected]2a6bc3e2011-12-28 23:51:333810 WebContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:103811 if (!GetStatusBubble())
3812 return;
3813
[email protected]4ca15302012-01-03 05:53:203814 if (source == GetSelectedWebContents()) {
[email protected]b8595e92009-11-14 01:18:003815 GetStatusBubble()->MouseMoved(location, !motion);
3816 if (!motion)
[email protected]65233052011-08-22 19:02:483817 GetStatusBubble()->SetURL(GURL(), std::string());
[email protected]36b6dcb2008-11-12 01:19:573818 }
3819}
3820
[email protected]2a6bc3e2011-12-28 23:51:333821void Browser::UpdateTargetURL(WebContents* source, int32 page_id,
[email protected]d952a052011-09-06 18:42:453822 const GURL& url) {
3823 Browser::UpdateTargetURLHelper(source, page_id, url);
3824
[email protected]be3877f2009-01-14 15:51:103825 if (!GetStatusBubble())
3826 return;
3827
[email protected]4ca15302012-01-03 05:53:203828 if (source == GetSelectedWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:573829 PrefService* prefs = profile_->GetPrefs();
[email protected]65233052011-08-22 19:02:483830 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
[email protected]36b6dcb2008-11-12 01:19:573831 }
3832}
3833
[email protected]3a6a3b62009-05-27 21:36:203834void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:233835 if (GetStatusBubble())
3836 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:203837}
3838
[email protected]36b6dcb2008-11-12 01:19:573839void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253840 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573841}
3842
[email protected]2a6bc3e2011-12-28 23:51:333843void Browser::WebContentsFocused(WebContents* contents) {
3844 window_->WebContentsFocused(contents);
[email protected]7e383692009-06-12 19:14:543845}
3846
[email protected]130efb02009-09-18 18:54:353847bool Browser::TakeFocus(bool reverse) {
[email protected]ad50def52011-10-19 23:17:073848 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273849 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
[email protected]6c2381d2011-10-19 02:52:533850 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:073851 content::NotificationService::NoDetails());
[email protected]130efb02009-09-18 18:54:353852 return false;
3853}
3854
[email protected]36b6dcb2008-11-12 01:19:573855bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143856 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573857}
3858
[email protected]2a6bc3e2011-12-28 23:51:333859void Browser::ConvertContentsToApplication(WebContents* contents) {
[email protected]36fc0392011-12-25 03:59:513860 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
[email protected]57ecc4b2010-08-11 03:02:513861 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573862
[email protected]b6c874582009-05-08 19:38:313863 DetachContents(contents);
[email protected]94ce7252010-12-20 21:46:333864 Browser* app_browser = Browser::CreateForApp(
[email protected]5c209242011-06-06 20:36:173865 TYPE_POPUP, app_name, gfx::Rect(), profile_);
[email protected]ae2f2a772011-05-04 16:30:273866 TabContentsWrapper* wrapper =
3867 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3868 if (!wrapper)
[email protected]d9083482012-01-06 00:38:463869 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323870 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3871
3872 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:523873 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]75aef122010-12-06 21:48:323874 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573875}
3876
[email protected]b7a756d42012-01-23 18:08:173877gfx::Rect Browser::GetRootWindowResizerRect() const {
3878 return window_->GetRootWindowResizerRect();
3879}
3880
[email protected]2a6bc3e2011-12-28 23:51:333881void Browser::BeforeUnloadFired(WebContents* tab,
[email protected]36b6dcb2008-11-12 01:19:573882 bool proceed,
3883 bool* proceed_to_fire_unload) {
3884 if (!is_attempting_to_close_browser_) {
3885 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393886 if (!proceed)
[email protected]0bfbf882011-12-22 18:19:273887 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573888 return;
3889 }
3890
3891 if (!proceed) {
3892 CancelWindowClose();
3893 *proceed_to_fire_unload = false;
[email protected]0bfbf882011-12-22 18:19:273894 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573895 return;
3896 }
3897
[email protected]06b42f032008-12-03 18:43:053898 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313899 // Now that beforeunload has fired, put the tab on the queue to fire
3900 // unload.
[email protected]06b42f032008-12-03 18:43:053901 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573902 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063903 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573904 // fire all the beforeunload events before attempting to fire the unload
3905 // events should the user cancel closing the browser.
3906 *proceed_to_fire_unload = false;
3907 return;
3908 }
3909
3910 *proceed_to_fire_unload = true;
3911}
3912
[email protected]a26dc362010-04-23 01:48:583913void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133914 // Two differences between this and FocusLocationBar():
3915 // (1) This doesn't get recorded in user metrics, since it's called
3916 // internally.
3917 // (2) This checks whether the location bar can be focused, and if not, clears
3918 // the focus. FocusLocationBar() is only reached when the location bar is
3919 // focusable, but this may be reached at other times, e.g. while in
3920 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583921 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573922}
3923
[email protected]7d5925a2009-03-03 02:59:123924void Browser::RenderWidgetShowing() {
3925 window_->DisableInactiveFrame();
3926}
[email protected]a239c3f2009-02-17 22:13:193927
[email protected]0a2aeb82009-05-15 21:52:483928int Browser::GetExtraRenderViewHeight() const {
3929 return window_->GetExtraRenderViewHeight();
3930}
3931
[email protected]a0e4b072011-08-17 01:47:073932namespace {
3933
3934bool DisplayOldDownloadsUI() {
3935 return !CommandLine::ForCurrentProcess()->HasSwitch(
3936 switches::kDownloadsNewUI);
3937}
3938
3939} // anonymous namespace
3940
[email protected]2a6bc3e2011-12-28 23:51:333941void Browser::OnStartDownload(WebContents* source,
[email protected]e582fdd2011-12-20 16:48:173942 content::DownloadItem* download) {
[email protected]686493142011-07-15 21:47:223943 TabContentsWrapper* wrapper =
3944 TabContentsWrapper::GetCurrentWrapperForContents(source);
3945 TabContentsWrapper* constrained = GetConstrainingContentsWrapper(wrapper);
3946 if (constrained != wrapper) {
3947 // Download in a constrained popup is shown in the tab that opened it.
[email protected]d9083482012-01-06 00:38:463948 WebContents* constrained_tab = constrained->web_contents();
[email protected]6934a702011-12-20 00:04:513949 constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download);
[email protected]686493142011-07-15 21:47:223950 return;
3951 }
3952
3953 if (!window())
3954 return;
3955
[email protected]a0e4b072011-08-17 01:47:073956 if (DisplayOldDownloadsUI()) {
[email protected]eab8c0f2011-11-18 22:33:503957#if defined(OS_CHROMEOS) && !defined(USE_AURA)
[email protected]603a502a2011-12-15 20:18:173958 if (ActiveDownloadsUI::ShouldShowPopup(profile_, download))
[email protected]a0e4b072011-08-17 01:47:073959 ActiveDownloadsUI::OpenPopup(profile_);
[email protected]eab8c0f2011-11-18 22:33:503960#else
[email protected]a0e4b072011-08-17 01:47:073961 // GetDownloadShelf creates the download shelf if it was not yet created.
3962 DownloadShelf* shelf = window()->GetDownloadShelf();
3963 shelf->AddDownload(new DownloadItemModel(download));
3964 // Don't show the animation for "Save file" downloads.
3965 // For non-theme extensions, we don't show the download animation.
3966 // Show animation in same window as the download shelf. Download shelf
3967 // may not be in the same window that initiated the download, e.g.
3968 // Panels.
3969 // Don't show the animation if the selected tab is not visible (i.e. the
3970 // window is minimized, we're in a unit test, etc.).
[email protected]bb81f382012-01-03 22:45:443971 WebContents* shelf_tab = shelf->browser()->GetSelectedWebContents();
[email protected]c09a8fd2011-11-21 19:54:503972 if ((download->GetTotalBytes() > 0) &&
[email protected]b0cfcee2011-10-27 03:55:373973 !ChromeDownloadManagerDelegate::IsExtensionDownload(download) &&
[email protected]a0e4b072011-08-17 01:47:073974 platform_util::IsVisible(shelf_tab->GetNativeView()) &&
3975 ui::Animation::ShouldRenderRichAnimation()) {
3976 DownloadStartedAnimation::Show(shelf_tab);
3977 }
[email protected]686493142011-07-15 21:47:223978#endif
[email protected]a0e4b072011-08-17 01:47:073979 }
[email protected]686493142011-07-15 21:47:223980
3981 // If the download occurs in a new tab, close it.
[email protected]f5fa20e2011-12-21 22:35:563982 if (source->GetController().IsInitialNavigation() && tab_count() > 1)
[email protected]686493142011-07-15 21:47:223983 CloseContents(source);
3984}
3985
[email protected]b8e681e82012-02-20 10:18:473986void Browser::ShowPageInfo(content::WebContents* web_contents,
3987 const GURL& url,
[email protected]d583e3f22011-12-27 21:38:173988 const SSLStatus& ssl,
[email protected]4d677202009-07-19 07:37:123989 bool show_history) {
[email protected]b8e681e82012-02-20 10:18:473990 Profile* profile = Profile::FromBrowserContext(
3991 web_contents->GetBrowserContext());
3992 TabContentsWrapper* wrapper =
3993 TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
3994
3995 if (CommandLine::ForCurrentProcess()->HasSwitch(
3996 switches::kEnableWebsiteSettings)) {
3997 window()->ShowWebsiteSettings(profile, wrapper, url, ssl, show_history);
3998 } else {
3999 window()->ShowPageInfo(profile, url, ssl, show_history);
4000 }
[email protected]4d677202009-07-19 07:37:124001}
4002
[email protected]2a6bc3e2011-12-28 23:51:334003void Browser::ViewSourceForTab(WebContents* source, const GURL& page_url) {
[email protected]1788e772010-12-15 16:40:504004 DCHECK(source);
[email protected]41f022e2012-01-31 05:56:404005 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(
4006 tab_handler_->GetTabStripModel()->GetWrapperIndex(source));
[email protected]77d8d622010-12-15 10:30:124007 ViewSource(wrapper);
4008}
4009
[email protected]2a6bc3e2011-12-28 23:51:334010void Browser::ViewSourceForFrame(WebContents* source,
[email protected]932b7a12011-03-09 12:50:274011 const GURL& frame_url,
4012 const std::string& frame_content_state) {
4013 DCHECK(source);
[email protected]41f022e2012-01-31 05:56:404014 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(
4015 tab_handler_->GetTabStripModel()->GetWrapperIndex(source));
[email protected]932b7a12011-03-09 12:50:274016 ViewSource(wrapper, frame_url, frame_content_state);
4017}
4018
[email protected]867125a02009-12-10 06:01:484019bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
4020 bool* is_keyboard_shortcut) {
[email protected]85804b52011-10-15 06:56:274021 // Escape exits tabbed fullscreen mode.
4022 // TODO(koz): Write a test for this http://crbug.com/100441.
[email protected]01a5a762011-11-21 05:40:554023 if (event.windowsKeyCode == 27 &&
4024 fullscreen_controller_->HandleUserPressedEscape()) {
[email protected]85804b52011-10-15 06:56:274025 return true;
4026 }
[email protected]867125a02009-12-10 06:01:484027 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
4028}
[email protected]97df4b332009-10-02 01:25:414029
[email protected]867125a02009-12-10 06:01:484030void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
4031 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:414032}
4033
[email protected]4fdf6742012-01-10 20:14:364034void Browser::ShowRepostFormWarningDialog(WebContents* source) {
[email protected]67baffc82011-12-19 18:03:074035 browser::ShowTabModalConfirmDialog(
[email protected]2a6bc3e2011-12-28 23:51:334036 new RepostFormWarningController(source),
4037 TabContentsWrapper::GetCurrentWrapperForContents(source));
[email protected]14f3408a2009-08-31 20:53:534038}
4039
[email protected]579e3192011-03-11 22:37:454040void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
[email protected]445177652011-03-09 02:04:054041 ShowOptionsTab(
4042 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
4043 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
[email protected]63543142010-02-09 23:22:204044}
4045
[email protected]a3627e62011-09-07 00:04:574046void Browser::ShowCollectedCookiesDialog(TabContentsWrapper* wrapper) {
4047 window()->ShowCollectedCookiesDialog(wrapper);
[email protected]a503c97c2010-07-16 13:05:484048}
4049
[email protected]ec0b6c42010-08-26 03:16:584050bool Browser::ShouldAddNavigationToHistory(
4051 const history::HistoryAddPageArgs& add_page_args,
[email protected]610cbb82011-10-18 16:35:084052 content::NavigationType navigation_type) {
[email protected]2e29d922009-10-22 22:13:354053 // Don't update history if running as app.
4054 return !IsApplication();
4055}
4056
[email protected]4fdf6742012-01-10 20:14:364057bool Browser::ShouldCreateWebContents(
4058 WebContents* web_contents,
4059 int route_id,
4060 WindowContainerType window_container_type,
4061 const string16& frame_name) {
4062 if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
4063 // If a BackgroundContents is created, suppress the normal WebContents.
4064 return !MaybeCreateBackgroundContents(
4065 route_id,
4066 web_contents->GetSiteInstance(),
4067 web_contents->GetURL(),
4068 frame_name);
4069 }
4070
4071 return true;
4072}
4073
4074void Browser::WebContentsCreated(WebContents* source_contents,
4075 int64 source_frame_id,
4076 const GURL& target_url,
4077 WebContents* new_contents) {
[email protected]80c7b802011-10-28 19:59:084078 // Create a TabContentsWrapper now, so all observers are in place, as the
4079 // network requests for its initial navigation will start immediately. The
4080 // TabContents will later be inserted into this browser using
4081 // Browser::Navigate via AddNewContents. The latter will retrieve the newly
4082 // created TabContentsWrapper from TabContents object.
[email protected]d9083482012-01-06 00:38:464083 new TabContentsWrapper(new_contents);
[email protected]4fdf6742012-01-10 20:14:364084
4085 // Notify.
4086 RetargetingDetails details;
4087 details.source_web_contents = source_contents;
4088 details.source_frame_id = source_frame_id;
4089 details.target_url = target_url;
4090 details.target_web_contents = new_contents;
4091 details.not_yet_in_tabstrip = true;
4092 content::NotificationService::current()->Notify(
4093 chrome::NOTIFICATION_RETARGETING,
4094 content::Source<Profile>(profile_),
4095 content::Details<RetargetingDetails>(&details));
[email protected]80c7b802011-10-28 19:59:084096}
4097
[email protected]2a6bc3e2011-12-28 23:51:334098void Browser::ContentRestrictionsChanged(WebContents* source) {
[email protected]9e823662010-10-13 23:36:004099 UpdateCommandsForContentRestrictionState();
4100}
4101
[email protected]2a6bc3e2011-12-28 23:51:334102void Browser::RendererUnresponsive(WebContents* source) {
[email protected]c19d9542011-11-15 22:26:424103 // Ignore hangs if print preview is open.
4104 TabContentsWrapper* source_wrapper =
4105 TabContentsWrapper::GetCurrentWrapperForContents(source);
4106 if (source_wrapper) {
4107 printing::PrintPreviewTabController* controller =
4108 printing::PrintPreviewTabController::GetInstance();
4109 if (controller) {
4110 TabContentsWrapper* preview_tab =
4111 controller->GetPrintPreviewForTab(source_wrapper);
4112 if (preview_tab && preview_tab != source_wrapper) {
4113 return;
4114 }
4115 }
4116 }
4117
[email protected]55452902011-06-01 21:57:474118 browser::ShowHungRendererDialog(source);
4119}
4120
[email protected]2a6bc3e2011-12-28 23:51:334121void Browser::RendererResponsive(WebContents* source) {
[email protected]55452902011-06-01 21:57:474122 browser::HideHungRendererDialog(source);
4123}
4124
[email protected]2a6bc3e2011-12-28 23:51:334125void Browser::WorkerCrashed(WebContents* source) {
[email protected]55452902011-06-01 21:57:474126 TabContentsWrapper* wrapper =
4127 TabContentsWrapper::GetCurrentWrapperForContents(source);
[email protected]95a33ed62011-09-30 15:07:084128 InfoBarTabHelper* infobar_helper = wrapper->infobar_tab_helper();
4129 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
4130 infobar_helper,
4131 NULL,
4132 l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
[email protected]55452902011-06-01 21:57:474133 true));
[email protected]0dd3a0ab2011-02-18 08:17:444134}
4135
[email protected]2a6bc3e2011-12-28 23:51:334136void Browser::DidNavigateMainFramePostCommit(WebContents* tab) {
[email protected]4ca15302012-01-03 05:53:204137 if (tab == GetSelectedWebContents())
[email protected]09b29342011-06-24 19:18:484138 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:004139}
4140
[email protected]2a6bc3e2011-12-28 23:51:334141void Browser::DidNavigateToPendingEntry(WebContents* tab) {
[email protected]4ca15302012-01-03 05:53:204142 if (tab == GetSelectedWebContents())
[email protected]09b29342011-06-24 19:18:484143 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:004144}
4145
[email protected]3ab9cb82011-06-03 18:02:074146content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
4147 return GetJavaScriptDialogCreatorInstance();
4148}
4149
[email protected]2a6bc3e2011-12-28 23:51:334150void Browser::RunFileChooser(WebContents* tab,
[email protected]8caadeb2011-11-22 02:45:234151 const content::FileChooserParams& params) {
[email protected]b888919c2011-09-02 00:32:164152 RunFileChooserHelper(tab, params);
[email protected]3a29a6e2011-08-24 18:26:214153}
4154
[email protected]2a6bc3e2011-12-28 23:51:334155void Browser::EnumerateDirectory(WebContents* tab, int request_id,
[email protected]3a29a6e2011-08-24 18:26:214156 const FilePath& path) {
[email protected]b888919c2011-09-02 00:32:164157 EnumerateDirectoryHelper(tab, request_id, path);
[email protected]3a29a6e2011-08-24 18:26:214158}
4159
[email protected]2a6bc3e2011-12-28 23:51:334160void Browser::ToggleFullscreenModeForTab(WebContents* tab,
[email protected]01a5a762011-11-21 05:40:554161 bool enter_fullscreen) {
4162 fullscreen_controller_->ToggleFullscreenModeForTab(tab, enter_fullscreen);
[email protected]8a5e0ca2011-08-25 06:30:474163}
4164
[email protected]2a6bc3e2011-12-28 23:51:334165bool Browser::IsFullscreenForTab(const WebContents* tab) const {
[email protected]01a5a762011-11-21 05:40:554166 return fullscreen_controller_->IsFullscreenForTab(tab);
[email protected]5d5f7af2011-10-01 01:38:124167}
4168
[email protected]2a6bc3e2011-12-28 23:51:334169void Browser::JSOutOfMemory(WebContents* tab) {
[email protected]b888919c2011-09-02 00:32:164170 JSOutOfMemoryHelper(tab);
[email protected]7d189022011-08-25 22:54:204171}
4172
[email protected]2a6bc3e2011-12-28 23:51:334173void Browser::RegisterProtocolHandler(WebContents* tab,
[email protected]7d189022011-08-25 22:54:204174 const std::string& protocol,
4175 const GURL& url,
4176 const string16& title) {
[email protected]b888919c2011-09-02 00:32:164177 RegisterProtocolHandlerHelper(tab, protocol, url, title);
[email protected]7d189022011-08-25 22:54:204178}
4179
[email protected]2a6bc3e2011-12-28 23:51:334180void Browser::RegisterIntentHandler(WebContents* tab,
[email protected]7d189022011-08-25 22:54:204181 const string16& action,
4182 const string16& type,
4183 const string16& href,
[email protected]63c239322011-10-31 23:56:304184 const string16& title,
4185 const string16& disposition) {
4186 RegisterIntentHandlerHelper(tab, action, type, href, title, disposition);
[email protected]7d189022011-08-25 22:54:204187}
4188
[email protected]0d9989d2011-12-21 20:26:004189void Browser::WebIntentDispatch(
[email protected]2a6bc3e2011-12-28 23:51:334190 WebContents* tab, content::WebIntentsDispatcher* intents_dispatcher) {
[email protected]8f0bbd62012-02-22 03:37:184191 if (!web_intents::IsWebIntentsEnabled())
[email protected]828e61af2011-09-14 19:45:064192 return;
4193
4194 TabContentsWrapper* tcw =
4195 TabContentsWrapper::GetCurrentWrapperForContents(tab);
[email protected]0d9989d2011-12-21 20:26:004196 tcw->web_intent_picker_controller()->SetIntentsDispatcher(intents_dispatcher);
[email protected]ada02b312011-12-01 21:54:534197 tcw->web_intent_picker_controller()->ShowDialog(
[email protected]0d9989d2011-12-21 20:26:004198 this,
4199 intents_dispatcher->GetIntent().action,
4200 intents_dispatcher->GetIntent().type);
[email protected]b888919c2011-09-02 00:32:164201}
4202
[email protected]2a6bc3e2011-12-28 23:51:334203void Browser::FindReply(WebContents* tab,
[email protected]b888919c2011-09-02 00:32:164204 int request_id,
4205 int number_of_matches,
4206 const gfx::Rect& selection_rect,
4207 int active_match_ordinal,
4208 bool final_update) {
4209 FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
4210 active_match_ordinal, final_update);
[email protected]7d189022011-08-25 22:54:204211}
4212
[email protected]2a6bc3e2011-12-28 23:51:334213void Browser::CrashedPlugin(WebContents* tab, const FilePath& plugin_path) {
[email protected]d952a052011-09-06 18:42:454214 CrashedPluginHelper(tab, plugin_path);
4215}
4216
[email protected]2a6bc3e2011-12-28 23:51:334217void Browser::UpdatePreferredSize(WebContents* source,
[email protected]0548c5352011-09-07 00:33:334218 const gfx::Size& pref_size) {
4219 window_->UpdatePreferredSize(source, pref_size);
4220}
4221
[email protected]2a6bc3e2011-12-28 23:51:334222void Browser::RequestToLockMouse(WebContents* tab) {
[email protected]01a5a762011-11-21 05:40:554223 fullscreen_controller_->RequestToLockMouse(tab);
[email protected]55c87fa2011-10-15 07:28:284224}
4225
[email protected]5ef8e372011-10-18 04:25:554226void Browser::LostMouseLock() {
[email protected]01a5a762011-11-21 05:40:554227 fullscreen_controller_->LostMouseLock();
[email protected]5ef8e372011-10-18 04:25:554228}
4229
4230void Browser::OnAcceptFullscreenPermission(
4231 const GURL& url,
4232 FullscreenExitBubbleType bubble_type) {
[email protected]01a5a762011-11-21 05:40:554233 fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type);
[email protected]5ef8e372011-10-18 04:25:554234}
4235
4236void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) {
[email protected]01a5a762011-11-21 05:40:554237 fullscreen_controller_->OnDenyFullscreenPermission(bubble_type);
[email protected]55c87fa2011-10-15 07:28:284238}
4239
[email protected]fc9bf18f2011-10-22 00:41:174240
[email protected]36b6dcb2008-11-12 01:19:574241///////////////////////////////////////////////////////////////////////////////
[email protected]51d83bdf2011-12-09 16:09:294242// Browser, CoreTabHelperDelegate implementation:
[email protected]a0366a52011-02-04 20:04:214243
[email protected]553602e12011-04-05 17:01:184244void Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
4245 int32 page_id) {
4246 if (GetSelectedTabContentsWrapper() != source)
4247 return;
4248
[email protected]10f417c52011-12-28 21:04:234249 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:464250 source->web_contents()->GetController().GetLastCommittedEntry();
[email protected]36fc0392011-12-25 03:59:514251 if (!entry || (entry->GetPageID() != page_id))
[email protected]553602e12011-04-05 17:01:184252 return;
4253
4254 switch (pending_web_app_action_) {
4255 case CREATE_SHORTCUT: {
4256 window()->ShowCreateWebAppShortcutsDialog(source);
4257 break;
4258 }
4259 case UPDATE_SHORTCUT: {
4260 web_app::UpdateShortcutForTabContents(source);
4261 break;
4262 }
4263 default:
4264 NOTREACHED();
4265 break;
4266 }
4267
4268 pending_web_app_action_ = NONE;
4269}
4270
4271void Browser::OnInstallApplication(TabContentsWrapper* source,
4272 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:364273 ExtensionService* extension_service = profile()->GetExtensionService();
4274 if (!extension_service)
[email protected]553602e12011-04-05 17:01:184275 return;
4276
[email protected]d8c8f25f2011-11-02 18:18:014277 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(
4278 extension_service,
[email protected]14908b72011-04-20 06:54:364279 extension_service->show_extensions_prompts() ?
4280 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:184281 installer->InstallWebApp(web_app);
4282}
4283
[email protected]c90c6ca2011-02-16 20:11:384284///////////////////////////////////////////////////////////////////////////////
4285// Browser, SearchEngineTabHelperDelegate implementation:
4286
[email protected]9219d262011-02-15 21:05:124287void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
4288 Profile* profile) {
[email protected]a6420df2012-01-06 04:41:024289 window()->ConfirmAddSearchProvider(template_url, profile);
[email protected]9219d262011-02-15 21:05:124290}
4291
[email protected]a0366a52011-02-04 20:04:214292///////////////////////////////////////////////////////////////////////////////
[email protected]e7cfdbd2011-04-22 14:41:374293// Browser, BlockedContentTabHelperDelegate implementation:
4294
[email protected]393c0ed02011-04-22 14:55:364295TabContentsWrapper* Browser::GetConstrainingContentsWrapper(
[email protected]e7cfdbd2011-04-22 14:41:374296 TabContentsWrapper* source) {
4297 return source;
4298}
4299
4300///////////////////////////////////////////////////////////////////////////////
[email protected]35699d572011-05-11 19:46:144301// Browser, BookmarkTabHelperDelegate implementation:
[email protected]52cc59b2011-05-06 14:42:384302
4303void Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
4304 if (source == GetSelectedTabContentsWrapper())
4305 window_->SetStarredState(starred);
4306}
4307
4308///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574309// Browser, SelectFileDialog::Listener implementation:
4310
[email protected]561abe62009-04-06 18:08:344311void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:514312 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:124313 GURL file_url = net::FilePathToFileURL(path);
[email protected]e5d549d2011-12-28 01:29:204314 if (file_url.is_empty())
4315 return;
4316
4317 OpenURL(OpenURLParams(
4318 file_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED,
4319 false));
[email protected]36b6dcb2008-11-12 01:19:574320}
4321
4322///////////////////////////////////////////////////////////////////////////////
[email protected]6c2381d2011-10-19 02:52:534323// Browser, content::NotificationObserver implementation:
[email protected]36b6dcb2008-11-12 01:19:574324
[email protected]432115822011-07-10 15:52:274325void Browser::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:534326 const content::NotificationSource& source,
4327 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:274328 switch (type) {
[email protected]fbc5e5f92012-01-02 06:08:324329 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:404330 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:214331 // Pass in false so that we delay processing. We need to delay the
4332 // processing as it may close the tab, which is currently on the call
4333 // stack above us.
[email protected]fbc5e5f92012-01-02 06:08:324334 ClearUnloadState(content::Source<WebContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:404335 }
4336 break;
4337
[email protected]432115822011-07-10 15:52:274338 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:404339 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:324340 // bar to reflect the new state. Note that it's possible for the selected
4341 // tab contents to be NULL. This is because we listen for all sources
4342 // (NavigationControllers) for convenience, so the notification could
4343 // actually be for a different window while we're doing asynchronous
4344 // closing of this one.
[email protected]4ca15302012-01-03 05:53:204345 if (GetSelectedWebContents() &&
4346 &GetSelectedWebContents()->GetController() ==
[email protected]c5eed492012-01-04 17:07:504347 content::Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:574348 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:404349 break;
4350
[email protected]432115822011-07-10 15:52:274351 case chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED: {
[email protected]e6090e42010-03-23 22:44:084352 // Show the UI if the extension was disabled for escalated permissions.
[email protected]6c2381d2011-10-19 02:52:534353 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]bc535ee52010-08-31 18:40:324354 if (profile_->IsSameProfile(profile)) {
[email protected]eaa7dd182010-12-14 11:09:004355 ExtensionService* service = profile->GetExtensionService();
[email protected]bc535ee52010-08-31 18:40:324356 DCHECK(service);
[email protected]6c2381d2011-10-19 02:52:534357 const Extension* extension =
4358 content::Details<const Extension>(details).ptr();
[email protected]bc535ee52010-08-31 18:40:324359 if (service->extension_prefs()->DidExtensionEscalatePermissions(
4360 extension->id()))
4361 ShowExtensionDisabledUI(service, profile_, extension);
4362 }
[email protected]0c6da502009-08-14 22:32:394363 break;
4364 }
4365
[email protected]432115822011-07-10 15:52:274366 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:364367 if (window()->GetLocationBar())
4368 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:384369
[email protected]b3f7fe22011-11-11 19:27:564370 // Close any tabs from the unloaded extension, unless it's terminated,
4371 // in which case let the sad tabs remain.
4372 if (content::Details<UnloadedExtensionInfo>(details)->reason !=
4373 extension_misc::UNLOAD_REASON_TERMINATE) {
4374 const Extension* extension =
4375 content::Details<UnloadedExtensionInfo>(details)->extension;
4376 TabStripModel* model = tab_handler_->GetTabStripModel();
4377 for (int i = model->count() - 1; i >= 0; --i) {
[email protected]d9083482012-01-06 00:38:464378 WebContents* tc = model->GetTabContentsAt(i)->web_contents();
[email protected]b3f7fe22011-11-11 19:27:564379 bool close_tab_contents =
4380 tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
4381 tc->GetURL().host() == extension->id();
4382 // We want to close all panels originated by the unloaded extension.
4383 close_tab_contents = close_tab_contents ||
4384 (type_ == TYPE_PANEL &&
4385 (web_app::GetExtensionIdFromApplicationName(app_name_) ==
[email protected]f9e82d92011-10-29 00:50:454386 extension->id()));
[email protected]b3f7fe22011-11-11 19:27:564387 if (close_tab_contents) {
4388 CloseTabContents(tc);
4389 }
[email protected]894bb502009-05-21 22:39:574390 }
4391 }
4392 break;
4393 }
4394
[email protected]432115822011-07-10 15:52:274395 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
[email protected]6c2381d2011-10-19 02:52:534396 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]fe8944f2011-08-30 17:47:324397 if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364398 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:464399 break;
4400 }
4401
[email protected]432115822011-07-10 15:52:274402 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
4403 case chrome::NOTIFICATION_EXTENSION_LOADED:
[email protected]1797f4a2011-08-30 18:00:284404 // During window creation on Windows we may end up calling into
4405 // SHAppBarMessage, which internally spawns a nested message loop. This
4406 // makes it possible for us to end up here before window creation has
4407 // completed,at which point window_ is NULL. See 94752 for details.
4408 if (window() && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364409 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:364410 break;
[email protected]ad0c2e1b2010-01-30 00:00:104411
[email protected]432115822011-07-10 15:52:274412 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
[email protected]e001d412009-06-26 20:53:254413 window()->UserChangedTheme();
4414 break;
4415
[email protected]432115822011-07-10 15:52:274416 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]6c2381d2011-10-19 02:52:534417 const std::string& pref_name =
4418 *content::Details<std::string>(details).ptr();
[email protected]3cf345b2011-10-06 17:51:254419 if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:374420 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]3819f2ee2011-08-21 09:44:384421 } else if (pref_name == prefs::kInstantEnabled ||
4422 pref_name == prefs::kMetricsReportingEnabled ||
4423 pref_name == prefs::kSearchSuggestEnabled) {
[email protected]73de26a2010-10-17 03:23:254424 if (!InstantController::IsEnabled(profile())) {
4425 if (instant()) {
4426 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:294427 instant_.reset();
4428 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:254429 }
4430 } else {
4431 CreateInstantIfNecessary();
4432 }
[email protected]4e94ab32011-08-05 05:28:274433 } else if (pref_name == prefs::kIncognitoModeAvailability) {
[email protected]93ad8e1c2011-11-08 21:34:054434 UpdateCommandsForIncognitoAvailability();
[email protected]543432ee2010-10-22 16:32:134435 } else if (pref_name == prefs::kDevToolsDisabled) {
4436 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:044437 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]0e12d7d2011-12-01 16:21:444438 content::DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:584439 } else if (pref_name == prefs::kEditBookmarksEnabled) {
4440 UpdateCommandsForBookmarkEditing();
[email protected]3710d0002011-10-11 00:35:004441 } else if (pref_name == prefs::kShowBookmarkBar) {
[email protected]a007e732011-08-05 13:32:194442 UpdateCommandsForBookmarkBar();
[email protected]3710d0002011-10-11 00:35:004443 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]6c6b02d2011-09-02 03:36:474444 } else if (pref_name == prefs::kHomePage) {
[email protected]6c2381d2011-10-19 02:52:534445 PrefService* pref_service = content::Source<PrefService>(source).ptr();
[email protected]6c6b02d2011-09-02 03:36:474446 MarkHomePageAsChanged(pref_service);
[email protected]97b46382011-05-02 13:23:044447 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
4448 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
4449 UpdateOpenFileState();
[email protected]2a7e7c152010-10-01 20:12:094450 } else {
[email protected]b9c505b2010-04-30 15:05:104451 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:094452 }
[email protected]b9c505b2010-04-30 15:05:104453 break;
4454 }
4455
[email protected]ea049a02011-12-25 21:37:094456 case chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED: {
4457 WebContents* web_contents = content::Source<WebContents>(source).ptr();
[email protected]4ca15302012-01-03 05:53:204458 if (web_contents == GetSelectedWebContents()) {
[email protected]9a9a9e22011-05-13 22:20:354459 LocationBar* location_bar = window()->GetLocationBar();
4460 if (location_bar)
4461 location_bar->UpdateContentSettingsIcons();
4462 }
4463 break;
4464 }
4465
[email protected]432115822011-07-10 15:52:274466 case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:484467 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]e397a4472011-12-21 21:47:504468 UpdateCommandsForTabState();
4469 break;
4470
4471 case content::NOTIFICATION_INTERSTITIAL_DETACHED:
4472 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
4473 UpdateCommandsForTabState();
[email protected]09b29342011-06-24 19:18:484474 break;
4475
[email protected]e83f1682008-09-07 23:57:404476 default:
4477 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:294478 }
4479}
4480
[email protected]d3b98c82010-07-14 07:45:594481///////////////////////////////////////////////////////////////////////////////
4482// Browser, ProfileSyncServiceObserver implementation:
4483
4484void Browser::OnStateChanged() {
[email protected]5e61afb92012-01-27 20:09:134485 DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
4486 profile_));
[email protected]99e652f2012-01-22 04:05:074487 // For unit tests, we don't have a window.
4488 if (!window_)
4489 return;
[email protected]93ad8e1c2011-11-08 21:34:054490 const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen());
[email protected]65549182012-02-25 00:45:404491 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
[email protected]49385da692011-08-05 04:03:394492 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]d3b98c82010-07-14 07:45:594493}
[email protected]88d74942009-01-21 22:04:444494
[email protected]36b6dcb2008-11-12 01:19:574495///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:274496// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:304497
[email protected]3c9e1872010-11-18 16:17:494498void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
4499 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:144500 window_->ShowInstant(preview_contents);
[email protected]42f027fb2011-10-27 16:37:484501
[email protected]4ca15302012-01-03 05:53:204502 GetSelectedWebContents()->HideContents();
4503 preview_contents->web_contents()->ShowContents();
[email protected]03bb953d2010-09-14 21:38:304504}
4505
[email protected]6b723f82010-10-05 20:14:274506void Browser::HideInstant() {
[email protected]3e481282011-10-15 15:39:504507 window_->HideInstant();
[email protected]4ca15302012-01-03 05:53:204508 if (GetSelectedWebContents())
4509 GetSelectedWebContents()->ShowContents();
[email protected]42f027fb2011-10-27 16:37:484510 if (instant_->GetPreviewContents())
[email protected]4ca15302012-01-03 05:53:204511 instant_->GetPreviewContents()->web_contents()->HideContents();
[email protected]03bb953d2010-09-14 21:38:304512}
4513
[email protected]3c9e1872010-11-18 16:17:494514void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
4515 TabContentsWrapper* tab_contents = instant_->tab_contents();
4516 int index =
4517 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
4518 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:304519 // TabStripModel takes ownership of preview_contents.
[email protected]43032342011-03-21 14:10:314520 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
4521 index, preview_contents);
4522 // InstantUnloadHandler takes ownership of tab_contents.
4523 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:334524
[email protected]d9083482012-01-06 00:38:464525 GURL url = preview_contents->web_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:524526 DCHECK(profile_->GetExtensionService());
4527 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:334528 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
4529 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
4530 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
4531 }
[email protected]03bb953d2010-09-14 21:38:304532}
4533
[email protected]c98fd5d82011-05-04 15:20:094534void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
4535 TabContentsWrapper* new_tab_contents) {
4536 int index =
4537 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(old_tab_contents);
[email protected]71b5d242011-04-30 02:27:204538 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]c98fd5d82011-05-04 15:20:094539 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(index,
4540 new_tab_contents);
[email protected]71b5d242011-04-30 02:27:204541}
4542
[email protected]31145092011-09-30 01:49:444543void Browser::SetTabContentBlocked(TabContentsWrapper* wrapper, bool blocked) {
[email protected]41f022e2012-01-31 05:56:404544 int index = tab_handler_->GetTabStripModel()->GetIndexOfTabContents(wrapper);
[email protected]31145092011-09-30 01:49:444545 if (index == TabStripModel::kNoTab) {
4546 NOTREACHED();
4547 return;
4548 }
[email protected]41f022e2012-01-31 05:56:404549 tab_handler_->GetTabStripModel()->SetTabBlocked(index, blocked);
[email protected]d9083482012-01-06 00:38:464550 UpdatePrintingState(wrapper->web_contents()->GetContentRestrictions());
[email protected]41f022e2012-01-31 05:56:404551 if (!blocked && GetSelectedTabContentsWrapper() == wrapper)
4552 wrapper->web_contents()->Focus();
[email protected]31145092011-09-30 01:49:444553}
4554
[email protected]33b8b8e2011-03-15 14:51:554555void Browser::SetSuggestedText(const string16& text,
4556 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:364557 if (window()->GetLocationBar())
4558 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:304559}
4560
[email protected]6b723f82010-10-05 20:14:274561gfx::Rect Browser::GetInstantBounds() {
4562 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:474563}
4564
[email protected]43b95172012-02-04 01:36:004565void Browser::OnWindowDidShow() {
4566 if (window_has_shown_)
4567 return;
4568 window_has_shown_ = true;
4569
4570 // Nothing to do for non-tabbed windows.
4571 if (!is_type_tabbed())
4572 return;
4573
4574 // Show any pending global error bubble.
4575 GlobalErrorService* service =
4576 GlobalErrorServiceFactory::GetForProfile(profile());
4577 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
4578 if (error)
4579 error->ShowBubbleView(this);
4580}
4581
4582void Browser::ShowFirstRunBubble() {
4583 window()->GetLocationBar()->ShowFirstRunBubble();
4584}
4585
[email protected]03bb953d2010-09-14 21:38:304586///////////////////////////////////////////////////////////////////////////////
[email protected]9800de5e2011-03-11 18:19:494587// Browser, protected:
4588
4589BrowserWindow* Browser::CreateBrowserWindow() {
[email protected]d313bf6c2011-12-29 22:25:494590 bool create_panel = false;
[email protected]815567d2012-02-15 18:47:424591#if !defined(OS_CHROMEOS) || defined(USE_AURA)
4592 create_panel = is_type_panel();
[email protected]d5c14062011-10-27 00:02:134593#endif
[email protected]d313bf6c2011-12-29 22:25:494594 if (create_panel)
4595 return PanelManager::GetInstance()->CreatePanel(this);
[email protected]011396a2011-04-13 23:35:284596
[email protected]9800de5e2011-03-11 18:19:494597 return BrowserWindow::CreateBrowserWindow(this);
4598}
4599
4600
4601///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574602// Browser, Command and state updating (private):
4603
4604void Browser::InitCommandState() {
4605 // All browser commands whose state isn't set automagically some other way
4606 // (like Back & Forward with initial page load) must have their state
4607 // initialized here, otherwise they will be forever disabled.
4608
[email protected]84214982008-12-10 18:49:104609 // Navigation commands
[email protected]1fc025202009-01-20 23:03:144610 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:164611 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:104612
4613 // Window management commands
[email protected]1fc025202009-01-20 23:03:144614 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
4615 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
[email protected]598e6c212012-02-01 04:57:564616#if defined(OS_CHROMEOS) && defined(USE_AURA)
4617 command_updater_.UpdateCommandEnabled(IDC_NEW_CROSH_TAB, true);
4618#endif
[email protected]1fc025202009-01-20 23:03:144619 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
4620 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:134621 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:144622 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]cdc05ec2011-05-18 15:15:594623 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:104624
4625 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:514626 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:144627 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
4628 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
4629 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
4630 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
4631 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
4632 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
4633 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
4634 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
4635 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
4636 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
4637 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
4638 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
4639 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
4640 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
4641 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
4642 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
4643 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
4644 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
4645 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
4646 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
4647 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
4648 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
4649 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
4650 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
4651 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
4652 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
4653 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
4654 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
4655 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
4656 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
4657 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
4658 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
4659 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
4660 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
4661 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:004662 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:144663 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
4664 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:104665
[email protected]63b02932009-06-05 09:40:514666 // Zoom
4667 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
4668 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
4669 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
4670 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
4671
[email protected]84214982008-12-10 18:49:104672 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:044673 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:144674 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:134675 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:144676 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:144677 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]1fc025202009-01-20 23:03:144678 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
4679 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]d6852fd2011-05-20 17:19:124680 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:294681
[email protected]96e34672010-02-09 21:40:294682#if defined(OS_CHROMEOS)
[email protected]f41fc932012-01-20 21:17:334683 // Don't allow screen lock for guest sessions.
4684 command_updater_.UpdateCommandEnabled(
4685 IDC_LOCK_SCREEN,
4686 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession));
[email protected]2166c432011-12-07 20:18:284687 command_updater_.UpdateCommandEnabled(IDC_SHUTDOWN, true);
[email protected]ec2fd5a2011-04-30 06:16:054688 command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
[email protected]f97d7f632010-06-01 21:08:334689 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:504690 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:474691 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:294692#endif
[email protected]a038159b2011-08-18 02:55:364693 command_updater_.UpdateCommandEnabled(
4694 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]c8b59f92010-05-28 21:45:474695
[email protected]64ff7942008-12-17 18:11:234696 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:144697 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:234698
[email protected]11f4857282009-11-13 19:56:174699 // Navigation commands
4700 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:234701
[email protected]11f4857282009-11-13 19:56:174702 // Window management commands
[email protected]d3766932011-08-04 22:18:234703 // TODO(rohitrao): Disable fullscreen on non-Lion?
[email protected]cf299bc2010-08-12 20:27:094704 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:144705 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:174706 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
4707 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
4708 normal_window);
4709 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
4710 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
4711 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
4712 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
4713 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
4714 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
4715 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
4716 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
4717 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
4718 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
4719 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:554720#if defined(OS_MACOSX)
4721 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
[email protected]d3766932011-08-04 22:18:234722 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
4723 !(is_type_panel() && is_app()));
[email protected]c1d0d812010-07-27 20:21:554724#endif
[email protected]e662ade2009-06-08 18:20:144725
[email protected]fc33e9992010-04-08 19:40:134726 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:144727 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134728
4729 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:144730 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
4731 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
4732 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134733
[email protected]11f4857282009-11-13 19:56:174734 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:134735 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:004736
[email protected]c1bbaa82010-11-08 11:17:054737 // The upgrade entry and the view incompatibility entry should always be
4738 // enabled. Whether they are visible is a separate matter determined on menu
4739 // show.
[email protected]b21d6912010-08-31 19:22:414740 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:054741 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:414742
[email protected]b569c112010-11-22 20:53:444743 // View Background Pages entry is always enabled, but is hidden if there are
4744 // no background pages.
4745 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
4746
[email protected]afcb43562011-09-02 23:33:384747 // Toggle speech input
4748 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
4749
[email protected]9282cea2009-02-18 18:49:004750 // Initialize other commands whose state changes based on fullscreen mode.
4751 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:004752
4753 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584754
4755 UpdateCommandsForBookmarkEditing();
[email protected]93ad8e1c2011-11-08 21:34:054756
4757 UpdateCommandsForIncognitoAvailability();
4758}
4759
4760bool Browser::IsShowingMainUI(bool is_fullscreen) {
4761#if !defined(OS_MACOSX)
4762 return is_type_tabbed() && !is_fullscreen;
4763#else
4764 return is_type_tabbed();
4765#endif
4766}
4767
4768void Browser::UpdateCommandsForIncognitoAvailability() {
4769 IncognitoModePrefs::Availability incognito_availability =
4770 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
4771 command_updater_.UpdateCommandEnabled(
4772 IDC_NEW_WINDOW,
4773 incognito_availability != IncognitoModePrefs::FORCED);
4774 command_updater_.UpdateCommandEnabled(
4775 IDC_NEW_INCOGNITO_WINDOW,
4776 incognito_availability != IncognitoModePrefs::DISABLED);
4777
4778 // Bookmark manager and settings page/subpages are forced to open in normal
4779 // mode. For this reason we disable these commands when incognito is forced.
4780 const bool command_enabled =
4781 incognito_availability != IncognitoModePrefs::FORCED;
4782 command_updater_.UpdateCommandEnabled(
4783 IDC_SHOW_BOOKMARK_MANAGER,
4784 browser_defaults::bookmarks_enabled && command_enabled);
4785 ExtensionService* extension_service = profile()->GetExtensionService();
4786 bool enable_extensions =
4787 extension_service && extension_service->extensions_enabled();
4788 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
4789 enable_extensions && command_enabled);
4790
4791 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4792 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
4793 show_main_ui && command_enabled);
4794 command_updater_.UpdateCommandEnabled(IDC_OPTIONS,
4795 show_main_ui && command_enabled);
[email protected]36b6dcb2008-11-12 01:19:574796}
4797
[email protected]227393e2011-06-29 21:28:394798void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
[email protected]93ad8e1c2011-11-08 21:34:054799 const bool show_main_ui = IsShowingMainUI(is_fullscreen);
[email protected]227393e2011-06-29 21:28:394800 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
4801
4802 // Navigation commands
4803 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
4804
4805 // Window management commands
4806 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
4807 type_ != TYPE_TABBED && !is_fullscreen);
4808
4809 // Focus various bits of UI
4810 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
4811 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
4812 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
4813 command_updater_.UpdateCommandEnabled(
4814 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
4815 command_updater_.UpdateCommandEnabled(
4816 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
4817 command_updater_.UpdateCommandEnabled(
4818 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
4819 command_updater_.UpdateCommandEnabled(
4820 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
4821 command_updater_.UpdateCommandEnabled(
4822 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
4823
4824 // Show various bits of UI
4825 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
4826 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]65549182012-02-25 00:45:404827 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
[email protected]49385da692011-08-05 04:03:394828 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]227393e2011-06-29 21:28:394829
[email protected]93ad8e1c2011-11-08 21:34:054830 // Settings page/subpages are forced to open in normal mode. We disable these
4831 // commands when incognito is forced.
4832 const bool options_enabled = show_main_ui &&
4833 IncognitoModePrefs::GetAvailability(
4834 profile_->GetPrefs()) != IncognitoModePrefs::FORCED;
4835 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
4836 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
4837
[email protected]227393e2011-06-29 21:28:394838 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
4839 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
4840 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
4841 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]7d2d08152011-10-25 22:58:474842 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
4843 show_main_ui && !profile()->IsOffTheRecord());
[email protected]227393e2011-06-29 21:28:394844#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
4845 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
4846#endif
[email protected]a007e732011-08-05 13:32:194847
4848 UpdateCommandsForBookmarkBar();
[email protected]227393e2011-06-29 21:28:394849}
4850
[email protected]84214982008-12-10 18:49:104851void Browser::UpdateCommandsForTabState() {
[email protected]4ca15302012-01-03 05:53:204852 WebContents* current_tab = GetSelectedWebContents();
[email protected]a0366a52011-02-04 20:04:214853 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
4854 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:394855 return;
[email protected]d8375fd2008-11-25 22:45:394856
[email protected]84214982008-12-10 18:49:104857 // Navigation commands
[email protected]c5eed492012-01-04 17:07:504858 NavigationController& nc = current_tab->GetController();
[email protected]ce3fa3c2009-04-20 19:55:574859 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
4860 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:134861 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
4862 CanReloadContents(current_tab));
4863 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
4864 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:294865
[email protected]84214982008-12-10 18:49:104866 // Window management commands
[email protected]1fc025202009-01-20 23:03:144867 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:144868 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:104869
[email protected]57c6a652009-05-04 07:58:344870 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:384871 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:144872 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:344873 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]f5fa20e2011-12-21 22:35:564874 current_tab->GetController().CanViewSource());
[email protected]151666e2010-10-21 17:05:254875 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
[email protected]cd8d90db2011-10-06 19:31:274876 toolbar_model_.ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:404877 if (is_devtools())
4878 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:254879
4880 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]e397a4472011-12-21 21:47:504881 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
[email protected]0bfbf882011-12-22 18:19:274882 current_tab->ShowingInterstitialPage();
[email protected]c0f82ec52010-07-27 14:22:144883 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
[email protected]a53209b2012-01-20 16:48:164884 !is_chrome_internal && current_tab->IsSavable());
[email protected]c0f82ec52010-07-27 14:22:144885
[email protected]57c6a652009-05-04 07:58:344886 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254887 // TODO(pinkerton): Disable app-mode in the model until we implement it
4888 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4889#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344890 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234891 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:254892#endif
[email protected]9e823662010-10-13 23:36:004893
4894 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584895 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004896}
4897
4898void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374899 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004900
4901 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184902 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
[email protected]9e823662010-10-13 23:36:004903 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184904 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
[email protected]9e823662010-10-13 23:36:004905 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184906 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044907 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004908 UpdatePrintingState(restrictions);
4909}
4910
4911void Browser::UpdatePrintingState(int content_restrictions) {
[email protected]43401bc02011-10-13 20:43:434912 bool print_enabled = true;
4913 bool advanced_print_enabled = true;
4914 if (g_browser_process->local_state()) {
4915 print_enabled =
4916 g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled);
4917 advanced_print_enabled = print_enabled;
[email protected]9e823662010-10-13 23:36:004918 }
[email protected]43401bc02011-10-13 20:43:434919 if (print_enabled) {
4920 // Do not print when a constrained window is showing. It's confusing.
4921 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
4922 bool has_constrained_window = (wrapper &&
4923 wrapper->constrained_window_tab_helper()->constrained_window_count());
4924 if (has_constrained_window ||
[email protected]4573fbd2011-10-31 20:25:184925 content_restrictions & content::CONTENT_RESTRICTION_PRINT) {
[email protected]43401bc02011-10-13 20:43:434926 print_enabled = false;
4927 advanced_print_enabled = false;
4928 }
4929
4930 // The exception is print preview,
4931 // where advanced printing is always enabled.
4932 printing::PrintPreviewTabController* controller =
4933 printing::PrintPreviewTabController::GetInstance();
[email protected]c19d9542011-11-15 22:26:424934 if (controller && (controller->GetPrintPreviewForTab(wrapper) ||
4935 controller->is_creating_print_preview_tab())) {
[email protected]43401bc02011-10-13 20:43:434936 advanced_print_enabled = true;
4937 }
4938 }
4939 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
[email protected]0996e9b2011-08-26 17:59:014940 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
[email protected]43401bc02011-10-13 20:43:434941 advanced_print_enabled);
initial.commit09911bf2008-07-26 23:55:294942}
4943
[email protected]943d8122010-06-11 02:13:454944void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4945 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:144946 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:234947}
4948
[email protected]543432ee2010-10-22 16:32:134949void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044950 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424951 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134952 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4953 dev_tools_enabled);
4954 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4955 dev_tools_enabled);
4956 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4957 dev_tools_enabled);
4958}
4959
[email protected]a13f47d12011-04-14 11:41:584960void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044961 bool enabled =
4962 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4963 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584964
4965 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144966 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584967 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4968 enabled && CanBookmarkAllTabs());
4969}
4970
[email protected]a007e732011-08-05 13:32:194971void Browser::UpdateCommandsForBookmarkBar() {
[email protected]93ad8e1c2011-11-08 21:34:054972 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
[email protected]a007e732011-08-05 13:32:194973 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
4974 browser_defaults::bookmarks_enabled &&
[email protected]3710d0002011-10-11 00:35:004975 !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
[email protected]a007e732011-08-05 13:32:194976 show_main_ui);
4977}
4978
[email protected]6c6b02d2011-09-02 03:36:474979void Browser::MarkHomePageAsChanged(PrefService* pref_service) {
4980 pref_service->SetBoolean(prefs::kHomePageChanged, true);
[email protected]6c6b02d2011-09-02 03:36:474981}
4982
[email protected]97b46382011-05-02 13:23:044983void Browser::UpdateSaveAsState(int content_restrictions) {
[email protected]4573fbd2011-10-31 20:25:184984 bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE);
[email protected]97b46382011-05-02 13:23:044985 PrefService* state = g_browser_process->local_state();
4986 if (state)
4987 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4988
4989 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4990}
4991
4992void Browser::UpdateOpenFileState() {
4993 bool enabled = true;
4994 PrefService* local_state = g_browser_process->local_state();
4995 if (local_state)
4996 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4997
4998 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4999}
5000
[email protected]36b6dcb2008-11-12 01:19:575001///////////////////////////////////////////////////////////////////////////////
5002// Browser, UI update coalescing and handling (private):
5003
5004void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:495005 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:295006}
5007
[email protected]2a6bc3e2011-12-28 23:51:335008void Browser::ScheduleUIUpdate(const WebContents* source,
[email protected]36b6dcb2008-11-12 01:19:575009 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:005010 if (!source)
5011 return;
5012
[email protected]2b4355c2009-04-04 17:55:465013 // Do some synchronous updates.
[email protected]d9083482012-01-06 00:38:465014 if (changed_flags & content::INVALIDATE_TYPE_URL &&
[email protected]4ca15302012-01-03 05:53:205015 source == GetSelectedWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:575016 // Only update the URL for the current tab. Note that we do not update
5017 // the navigation commands since those would have already been updated
5018 // synchronously by NavigationStateChanged.
5019 UpdateToolbar(false);
[email protected]d9083482012-01-06 00:38:465020 changed_flags &= ~content::INVALIDATE_TYPE_URL;
[email protected]36b6dcb2008-11-12 01:19:575021 }
[email protected]d9083482012-01-06 00:38:465022 if (changed_flags & content::INVALIDATE_TYPE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:575023 // Update the loading state synchronously. This is so the throbber will
5024 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:005025 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:405026 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:405027 GetIndexOfController(&source->GetController()),
[email protected]6ebdc9b2010-09-27 16:55:575028 TabStripModelObserver::LOADING_ONLY);
[email protected]d9083482012-01-06 00:38:465029 // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too,
5030 // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from
[email protected]6ebdc9b2010-09-27 16:55:575031 // changed_flags.
[email protected]8030f012009-09-25 18:09:375032 }
5033
[email protected]d9083482012-01-06 00:38:465034 if (changed_flags & content::INVALIDATE_TYPE_TITLE && !source->IsLoading()) {
[email protected]f1cd5e82009-10-23 17:19:035035 // To correctly calculate whether the title changed while not loading
5036 // we need to process the update synchronously. This state only matters for
5037 // the TabStripModel, so we notify the TabStripModel now and notify others
5038 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:405039 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:405040 GetIndexOfController(&source->GetController()),
[email protected]f1cd5e82009-10-23 17:19:035041 TabStripModelObserver::TITLE_NOT_LOADING);
5042 }
5043
[email protected]2b4355c2009-04-04 17:55:465044 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:375045 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:465046 return;
[email protected]36b6dcb2008-11-12 01:19:575047
5048 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:405049 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:575050
[email protected]24f1477532011-11-22 22:55:365051 if (!chrome_updater_factory_.HasWeakPtrs()) {
[email protected]36b6dcb2008-11-12 01:19:575052 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:375053 MessageLoop::current()->PostDelayedTask(
5054 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:365055 base::Bind(&Browser::ProcessPendingUIUpdates,
5056 chrome_updater_factory_.GetWeakPtr()),
[email protected]11d6ab1a2012-01-12 21:37:265057 base::TimeDelta::FromMilliseconds(kUIUpdateCoalescingTimeMS));
[email protected]36b6dcb2008-11-12 01:19:575058 }
5059}
5060
5061void Browser::ProcessPendingUIUpdates() {
5062#ifndef NDEBUG
5063 // Validate that all tabs we have pending updates for exist. This is scary
5064 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:005065 // deleted tabs.
[email protected]85354982009-09-25 19:58:405066 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
5067 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:575068 bool found = false;
5069 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]6acde6352012-01-04 16:52:205070 if (GetWebContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:575071 found = true;
5072 break;
5073 }
5074 }
5075 DCHECK(found);
5076 }
5077#endif
5078
[email protected]24f1477532011-11-22 22:55:365079 chrome_updater_factory_.InvalidateWeakPtrs();
[email protected]36b6dcb2008-11-12 01:19:575080
[email protected]85354982009-09-25 19:58:405081 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
5082 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:575083 // Do not dereference |contents|, it may be out-of-date!
[email protected]2a6bc3e2011-12-28 23:51:335084 const WebContents* contents = i->first;
[email protected]85354982009-09-25 19:58:405085 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:575086
[email protected]4ca15302012-01-03 05:53:205087 if (contents == GetSelectedWebContents()) {
[email protected]a5231662009-09-26 00:56:005088 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:345089
[email protected]d9083482012-01-06 00:38:465090 if (flags & content::INVALIDATE_TYPE_PAGE_ACTIONS) {
[email protected]9800de5e2011-03-11 18:19:495091 LocationBar* location_bar = window()->GetLocationBar();
5092 if (location_bar)
5093 location_bar->UpdatePageActions();
5094 }
[email protected]6ebdc9b2010-09-27 16:55:575095 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]d9083482012-01-06 00:38:465096 if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:445097 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:295098 GetSelectedTabContentsWrapper()->
5099 core_tab_helper()->GetStatusText());
[email protected]0dd3a0ab2011-02-18 08:17:445100 }
[email protected]a5231662009-09-26 00:56:005101
[email protected]d9083482012-01-06 00:38:465102 if (flags & (content::INVALIDATE_TYPE_TAB |
5103 content::INVALIDATE_TYPE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:255104// TODO(pinkerton): Disable app-mode in the model until we implement it
5105// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
5106#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:005107 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:235108 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:255109#endif
[email protected]a5231662009-09-26 00:56:005110 window_->UpdateTitleBar();
5111 }
[email protected]4d34e2e2009-05-26 22:55:285112 }
[email protected]36b6dcb2008-11-12 01:19:575113
[email protected]a5231662009-09-26 00:56:005114 // Updates that don't depend upon the selected state go here.
[email protected]d9083482012-01-06 00:38:465115 if (flags &
5116 (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:405117 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:495118 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:035119 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:575120 }
5121
5122 // We don't need to process INVALIDATE_STATE, since that's not visible.
5123 }
5124
5125 scheduled_updates_.clear();
5126}
5127
[email protected]d9083482012-01-06 00:38:465128void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
[email protected]36b6dcb2008-11-12 01:19:575129 if (!contents)
5130 return;
5131
[email protected]85354982009-09-25 19:58:405132 UpdateMap::iterator i = scheduled_updates_.find(contents);
5133 if (i != scheduled_updates_.end())
5134 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:295135}
5136
[email protected]d938aed92009-01-22 19:49:335137
[email protected]36b6dcb2008-11-12 01:19:575138///////////////////////////////////////////////////////////////////////////////
5139// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:295140
[email protected]36b6dcb2008-11-12 01:19:575141StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:095142#if !defined(OS_MACOSX)
5143 // In kiosk mode, we want to always hide the status bubble.
5144 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
5145 return NULL;
5146#endif
[email protected]9b032bf2009-07-21 17:34:235147 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:295148}
5149
[email protected]36b6dcb2008-11-12 01:19:575150///////////////////////////////////////////////////////////////////////////////
5151// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:295152
5153void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:155154 SessionService* session_service =
5155 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:295156 if (session_service) {
5157 for (int i = index; i < tab_count(); ++i) {
[email protected]81898992011-06-14 22:15:005158 TabContentsWrapper* tab = GetTabContentsWrapperAt(i);
5159 if (tab) {
initial.commit09911bf2008-07-26 23:55:295160 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:005161 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:405162 session_service->SetPinnedState(
5163 session_id(),
[email protected]81898992011-06-14 22:15:005164 tab->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:405165 IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:295166 }
5167 }
5168 }
5169}
5170
[email protected]36b6dcb2008-11-12 01:19:575171///////////////////////////////////////////////////////////////////////////////
5172// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:295173
[email protected]04b4a6c2008-08-02 00:44:475174void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:215175 if (!is_attempting_to_close_browser_) {
5176 // Because we might invoke this after a delay it's possible for the value of
5177 // is_attempting_to_close_browser_ to have changed since we scheduled the
5178 // task.
5179 return;
5180 }
initial.commit09911bf2008-07-26 23:55:295181
[email protected]04b4a6c2008-08-02 00:44:475182 if (HasCompletedUnloadProcessing()) {
5183 // We've finished all the unload events and can proceed to close the
5184 // browser.
5185 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:295186 return;
5187 }
5188
[email protected]04b4a6c2008-08-02 00:44:475189 // Process beforeunload tabs first. When that queue is empty, process
5190 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:475191 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]a81343d232011-12-27 07:39:205192 WebContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:245193 // Null check render_view_host here as this gets called on a PostTask and
5194 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:525195 if (tab->GetRenderViewHost()) {
5196 tab->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:245197 } else {
[email protected]08f0d612011-01-13 23:58:215198 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:245199 }
[email protected]04b4a6c2008-08-02 00:44:475200 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:295201 // We've finished firing all beforeunload events and can proceed with unload
5202 // events.
5203 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
5204 // somewhere around here so that we have accurate measurements of shutdown
5205 // time.
[email protected]04b4a6c2008-08-02 00:44:475206 // TODO(ojan): We can probably fire all the unload events in parallel and
5207 // get a perf benefit from that in the cases where the tab hangs in it's
5208 // unload handler or takes a long time to page in.
[email protected]a81343d232011-12-27 07:39:205209 WebContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:245210 // Null check render_view_host here as this gets called on a PostTask and
5211 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:525212 if (tab->GetRenderViewHost()) {
5213 tab->GetRenderViewHost()->ClosePage();
[email protected]22484622009-06-10 21:17:245214 } else {
[email protected]08f0d612011-01-13 23:58:215215 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:245216 }
initial.commit09911bf2008-07-26 23:55:295217 } else {
[email protected]04b4a6c2008-08-02 00:44:475218 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:295219 }
5220}
5221
[email protected]d043c2cc2009-03-25 18:30:455222bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:475223 return is_attempting_to_close_browser_ &&
5224 tabs_needing_before_unload_fired_.empty() &&
5225 tabs_needing_unload_fired_.empty();
5226}
5227
5228void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:045229 // Closing of window can be canceled from:
5230 // - canceling beforeunload
5231 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:475232 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:285233 tabs_needing_before_unload_fired_.clear();
5234 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:475235 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:045236
5237 // Inform TabCloseableStateWatcher that closing of window has been canceled.
5238 TabCloseableStateWatcher* watcher =
5239 g_browser_process->tab_closeable_state_watcher();
5240 if (watcher)
5241 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:475242}
5243
[email protected]a81343d232011-12-27 07:39:205244bool Browser::RemoveFromSet(UnloadListenerSet* set, WebContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:475245 DCHECK(is_attempting_to_close_browser_);
5246
[email protected]06b42f032008-12-03 18:43:055247 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
5248 if (iter != set->end()) {
5249 set->erase(iter);
5250 return true;
[email protected]04b4a6c2008-08-02 00:44:475251 }
5252 return false;
5253}
initial.commit09911bf2008-07-26 23:55:295254
[email protected]a81343d232011-12-27 07:39:205255void Browser::ClearUnloadState(WebContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:045256 // Closing of browser could be canceled (via IsClosingPermitted) between the
5257 // time when request was initiated and when this method is called, so check
5258 // for is_attempting_to_close_browser_ flag before proceeding.
5259 if (is_attempting_to_close_browser_) {
5260 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
5261 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:215262 if (process_now) {
5263 ProcessPendingTabs();
5264 } else {
5265 MessageLoop::current()->PostTask(
5266 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:365267 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr()));
[email protected]08f0d612011-01-13 23:58:215268 }
[email protected]0b4d3382010-07-14 16:13:045269 }
initial.commit09911bf2008-07-26 23:55:295270}
5271
[email protected]36b6dcb2008-11-12 01:19:575272///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:065273// Browser, In-progress download termination handling (private):
5274
[email protected]b6a4ac2b2011-10-17 20:05:485275bool Browser::CanCloseWithInProgressDownloads() {
[email protected]5a17d492011-10-24 19:37:035276 // If we've prompted, we need to hear from the user before we
5277 // can close.
5278 if (cancel_download_confirmation_state_ != NOT_PROMPTED)
5279 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
5280
5281 int num_downloads_blocking;
5282 if (DOWNLOAD_CLOSE_OK ==
5283 OkToCloseWithInProgressDownloads(&num_downloads_blocking))
[email protected]446295a2010-04-19 23:43:005284 return true;
5285
[email protected]5a17d492011-10-24 19:37:035286 // Closing this window will kill some downloads; prompt to make sure
5287 // that's ok.
[email protected]69444cc2009-04-09 20:40:065288 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
5289 window_->ConfirmBrowserCloseWithPendingDownloads();
5290
5291 // Return false so the browser does not close. We'll close if the user
5292 // confirms in the dialog.
5293 return false;
5294}
5295
5296///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:575297// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:295298
[email protected]1a6b30a2009-08-19 03:52:115299// static
[email protected]de4e7632010-09-01 06:24:045300Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
[email protected]b35b26b32011-05-05 20:35:145301 return BrowserList::FindTabbedBrowser(profile, match_incognito);
[email protected]de4e7632010-09-01 06:24:045302}
5303
5304// static
[email protected]1a6b30a2009-08-19 03:52:115305Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:045306 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:055307 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:115308 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:295309 return browser;
5310}
5311
[email protected]9219d262011-02-15 21:05:125312void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]e7cfdbd2011-04-22 14:41:375313 // TabContents...
[email protected]d9083482012-01-06 00:38:465314 tab->web_contents()->SetDelegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:375315
5316 // ...and all the helpers.
5317 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:145318 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]31145092011-09-30 01:49:445319 tab->constrained_window_tab_helper()->set_delegate(delegate);
[email protected]51d83bdf2011-12-09 16:09:295320 tab->core_tab_helper()->set_delegate(delegate);
[email protected]1739e57d2011-11-30 21:18:255321 tab->extension_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:125322 tab->search_engine_tab_helper()->set_delegate(delegate);
5323}
5324
[email protected]4f3dc372009-02-24 00:10:295325void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:585326 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:295327 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:005328 string16 find_text;
5329#if defined(OS_MACOSX)
5330 // We always want to search for the contents of the find pasteboard on OS X.
5331 find_text = GetFindPboardText();
5332#endif
[email protected]9c318862011-02-01 22:27:245333 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:385334 find_tab_helper()->StartFinding(find_text,
5335 forward_direction,
5336 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:295337 }
[email protected]fbd77592008-11-12 20:50:275338}
[email protected]cb17f7f2009-02-06 18:14:485339
[email protected]36b6dcb2008-11-12 01:19:575340void Browser::CloseFrame() {
5341 window_->Close();
initial.commit09911bf2008-07-26 23:55:295342}
5343
[email protected]3c9e1872010-11-18 16:17:495344void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:175345 DetachType type) {
5346 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:155347 // Save the current location bar state, but only if the tab being detached
5348 // is the selected tab. Because saving state can conditionally revert the
5349 // location bar, saving the current tab's location bar state to a
5350 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:495351 if (contents == GetSelectedTabContentsWrapper()) {
5352 LocationBar* location_bar = window()->GetLocationBar();
5353 if (location_bar)
[email protected]83a2610a2012-01-05 01:00:275354 location_bar->SaveStateToContents(contents->web_contents());
[email protected]9800de5e2011-03-11 18:19:495355 }
[email protected]c37e3b62010-01-22 00:15:175356
[email protected]ecc523f62010-09-28 22:45:405357 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:175358 SyncHistoryWithTabs(0);
5359 }
5360
[email protected]9219d262011-02-15 21:05:125361 SetAsDelegate(contents, NULL);
[email protected]d9083482012-01-06 00:38:465362 RemoveScheduledUpdatesFor(contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:175363
[email protected]41f022e2012-01-31 05:56:405364 if (find_bar_controller_.get() && index == active_index()) {
[email protected]c37e3b62010-01-22 00:15:175365 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:405366 }
[email protected]c37e3b62010-01-22 00:15:175367
[email protected]08f0d612011-01-13 23:58:215368 if (is_attempting_to_close_browser_) {
5369 // If this is the last tab with unload handlers, then ProcessPendingTabs
5370 // would call back into the TabStripModel (which is invoking this method on
5371 // us). Avoid that by passing in false so that the call to
5372 // ProcessPendingTabs is delayed.
[email protected]d9083482012-01-06 00:38:465373 ClearUnloadState(contents->web_contents(), false);
[email protected]08f0d612011-01-13 23:58:215374 }
5375
[email protected]432115822011-07-10 15:52:275376 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:325377 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:505378 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]4b19ea52012-01-02 20:15:255379 content::Source<WebContents>(contents->web_contents()));
[email protected]fbc5e5f92012-01-02 06:08:325380 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
5381 content::Source<WebContents>(contents->web_contents()));
[email protected]c37e3b62010-01-22 00:15:175382}
5383
initial.commit09911bf2008-07-26 23:55:295384// static
[email protected]f87919d72011-02-02 18:46:165385void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:295386 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:515387 std::string window_pref(prefs::kBrowserWindowPlacement);
5388 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:295389 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:145390 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:165391 if (!prefs->FindPreference(window_pref.c_str())) {
5392 prefs->RegisterDictionaryPref(window_pref.c_str(),
5393 PrefService::UNSYNCABLE_PREF);
5394 }
initial.commit09911bf2008-07-26 23:55:295395}
[email protected]5c238752009-06-13 10:29:075396
[email protected]281918912010-05-27 22:05:135397void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
5398 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
5399 !service->entries().empty());
5400}
5401
5402void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
5403 if (!tab_restore_service_)
5404 return;
5405
5406 DCHECK_EQ(tab_restore_service_, service);
5407 tab_restore_service_->RemoveObserver(this);
5408 tab_restore_service_ = NULL;
5409}
[email protected]97b6c4f2010-09-27 19:31:265410
[email protected]3c9e1872010-11-18 16:17:495411// Centralized method for creating a TabContents, configuring and installing
5412// all its supporting objects and observers.
5413TabContentsWrapper* Browser::TabContentsFactory(
5414 Profile* profile,
5415 SiteInstance* site_instance,
5416 int routing_id,
[email protected]bb81f382012-01-03 22:45:445417 const WebContents* base_web_contents,
[email protected]adbfb8df2012-02-24 01:19:435418 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]bb81f382012-01-03 22:45:445419 WebContents* new_contents = WebContents::Create(
5420 profile, site_instance, routing_id, base_web_contents,
5421 session_storage_namespace);
[email protected]d9083482012-01-06 00:38:465422 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
[email protected]3c9e1872010-11-18 16:17:495423 return wrapper;
5424}
5425
[email protected]6b723f82010-10-05 20:14:275426bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]3e481282011-10-15 15:39:505427 if (!instant() || !instant()->PrepareForCommit() ||
[email protected]35242602011-01-06 16:38:535428 disposition == NEW_BACKGROUND_TAB) {
5429 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
5430 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:265431 return false;
[email protected]35242602011-01-06 16:38:535432 }
[email protected]97b6c4f2010-09-27 19:31:265433
5434 if (disposition == CURRENT_TAB) {
[email protected]ad50def52011-10-19 23:17:075435 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275436 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535437 content::Source<TabContentsWrapper>(instant()->CommitCurrentPreview(
[email protected]094b0522011-10-06 00:55:275438 INSTANT_COMMIT_PRESSED_ENTER)),
[email protected]ad50def52011-10-19 23:17:075439 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265440 return true;
5441 }
[email protected]35242602011-01-06 16:38:535442 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:495443 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]5419ff92012-01-06 21:17:155444 INSTANT_COMMIT_PRESSED_ENTER, NULL);
[email protected]a0df03c122011-01-05 00:22:555445 // HideInstant is invoked after release so that InstantController is not
5446 // active when HideInstant asks it for its state.
5447 HideInstant();
[email protected]d9083482012-01-06 00:38:465448 preview_contents->web_contents()->GetController().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:405449 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:265450 preview_contents,
5451 -1,
[email protected]6b723f82010-10-05 20:14:275452 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:415453 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:375454 instant()->CompleteRelease(preview_contents);
[email protected]ad50def52011-10-19 23:17:075455 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275456 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535457 content::Source<TabContentsWrapper>(preview_contents),
[email protected]ad50def52011-10-19 23:17:075458 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265459 return true;
5460 }
5461 // The omnibox currently doesn't use other dispositions, so we don't attempt
5462 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
5463 // support for the new disposition.
5464 NOTREACHED();
5465 return false;
5466}
[email protected]2031cf9d2010-10-12 05:05:375467
5468void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:145469 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:375470 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:195471 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:295472 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:375473 }
5474}
[email protected]77d8d622010-12-15 10:30:125475
5476void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:275477 DCHECK(contents);
5478
[email protected]10f417c52011-12-28 21:04:235479 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:465480 contents->web_contents()->GetController().GetActiveEntry();
[email protected]932b7a12011-03-09 12:50:275481 if (!active_entry)
5482 return;
5483
[email protected]36fc0392011-12-25 03:59:515484 ViewSource(contents, active_entry->GetURL(), active_entry->GetContentState());
[email protected]932b7a12011-03-09 12:50:275485}
5486
5487void Browser::ViewSource(TabContentsWrapper* contents,
5488 const GURL& url,
5489 const std::string& content_state) {
[email protected]7f6f44c2011-12-14 13:23:385490 content::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:125491 DCHECK(contents);
5492
5493 TabContentsWrapper* view_source_contents = contents->Clone();
[email protected]d9083482012-01-06 00:38:465494 view_source_contents->web_contents()->GetController().PruneAllButActive();
[email protected]10f417c52011-12-28 21:04:235495 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:465496 view_source_contents->web_contents()->GetController().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:505497 if (!active_entry)
5498 return;
5499
[email protected]932b7a12011-03-09 12:50:275500 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
5501 url.spec());
[email protected]36fc0392011-12-25 03:59:515502 active_entry->SetVirtualURL(view_source_url);
[email protected]1436beff2010-12-16 19:47:045503
[email protected]932b7a12011-03-09 12:50:275504 // Do not restore scroller position.
[email protected]36fc0392011-12-25 03:59:515505 active_entry->SetContentState(
[email protected]932b7a12011-03-09 12:50:275506 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
5507
[email protected]cd3d50d2010-12-18 21:03:295508 // Do not restore title, derive it from the url.
[email protected]36fc0392011-12-25 03:59:515509 active_entry->SetTitle(string16());
[email protected]77d8d622010-12-15 10:30:125510
[email protected]47b309f2010-12-28 17:35:565511 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:125512 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
5513 // If this is a tabbed browser, just create a duplicate tab inside the same
5514 // window next to the tab being duplicated.
[email protected]41f022e2012-01-31 05:56:405515 int index =
5516 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:415517 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:565518 TabStripModel::ADD_INHERIT_GROUP;
[email protected]77d8d622010-12-15 10:30:125519 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]47b309f2010-12-28 17:35:565520 view_source_contents,
[email protected]77d8d622010-12-15 10:30:125521 add_types);
5522 } else {
[email protected]b35b26b32011-05-05 20:35:145523 Browser* browser = Browser::CreateForType(TYPE_TABBED, profile_);
[email protected]77d8d622010-12-15 10:30:125524
5525 // Preserve the size of the original window. The new window has already
5526 // been given an offset by the OS, so we shouldn't copy the old bounds.
5527 BrowserWindow* new_window = browser->window();
5528 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
5529 window()->GetRestoredBounds().size()));
5530
5531 // We need to show the browser now. Otherwise ContainerWin assumes the
5532 // TabContents is invisible and won't size it.
5533 browser->window()->Show();
5534
5535 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:585536 browser->AddTab(view_source_contents, content::PAGE_TRANSITION_LINK);
[email protected]77d8d622010-12-15 10:30:125537 }
5538
[email protected]92371eb2011-04-28 11:50:155539 SessionService* session_service =
5540 SessionServiceFactory::GetForProfileIfExisting(profile_);
5541 if (session_service)
[email protected]81898992011-06-14 22:15:005542 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:125543}
[email protected]b9163e02011-04-20 16:03:375544
5545int Browser::GetContentRestrictionsForSelectedTab() {
5546 int content_restrictions = 0;
[email protected]4ca15302012-01-03 05:53:205547 WebContents* current_tab = GetSelectedWebContents();
[email protected]b9163e02011-04-20 16:03:375548 if (current_tab) {
[email protected]0bfbf882011-12-22 18:19:275549 content_restrictions = current_tab->GetContentRestrictions();
[email protected]10f417c52011-12-28 21:04:235550 NavigationEntry* active_entry =
[email protected]f5fa20e2011-12-21 22:35:565551 current_tab->GetController().GetActiveEntry();
[email protected]b9163e02011-04-20 16:03:375552 // See comment in UpdateCommandsForTabState about why we call url().
[email protected]a53209b2012-01-20 16:48:165553 if (!download_util::IsSavableURL(
[email protected]36fc0392011-12-25 03:59:515554 active_entry ? active_entry->GetURL() : GURL())
[email protected]0bfbf882011-12-22 18:19:275555 || current_tab->ShowingInterstitialPage())
[email protected]4573fbd2011-10-31 20:25:185556 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
[email protected]0bfbf882011-12-22 18:19:275557 if (current_tab->ShowingInterstitialPage())
[email protected]e397a4472011-12-21 21:47:505558 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
[email protected]b9163e02011-04-20 16:03:375559 }
5560 return content_restrictions;
5561}
[email protected]09b29342011-06-24 19:18:485562
5563void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
5564 BookmarkBar::State state;
[email protected]227393e2011-06-29 21:28:395565 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
[email protected]3710d0002011-10-11 00:35:005566 if (browser_defaults::bookmarks_enabled &&
5567 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
[email protected]227393e2011-06-29 21:28:395568 (!window_ || !window_->IsFullscreen())) {
[email protected]09b29342011-06-24 19:18:485569 state = BookmarkBar::SHOW;
5570 } else {
5571 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
5572 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
5573 state = BookmarkBar::DETACHED;
5574 else
5575 state = BookmarkBar::HIDDEN;
5576 }
5577 if (state == bookmark_bar_state_)
5578 return;
5579
5580 bookmark_bar_state_ = state;
5581
5582 if (!window_)
5583 return; // This is called from the constructor when window_ is NULL.
5584
5585 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
5586 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
5587 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
5588 // end up querying state once they process the tab switch.
5589 return;
5590 }
5591
5592 BookmarkBar::AnimateChangeType animate_type =
5593 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
5594 BookmarkBar::ANIMATE_STATE_CHANGE :
5595 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
5596 window_->BookmarkBarStateChanged(animate_type);
5597}
[email protected]2e2cacc2011-07-12 21:54:265598
5599void Browser::ShowSyncSetup() {
[email protected]e0dc2cb2011-08-04 03:22:575600 ProfileSyncService* service =
[email protected]5e61afb92012-01-27 20:09:135601 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
5602 profile()->GetOriginalProfile());
[email protected]65549182012-02-25 00:45:405603 LoginUIService* login_service =
5604 LoginUIServiceFactory::GetForProfile(profile()->GetOriginalProfile());
[email protected]aff3de22012-02-13 22:58:065605 if (service->HasSyncSetupCompleted()) {
[email protected]a981fd62011-10-08 03:09:045606 ShowOptionsTab(chrome::kPersonalOptionsSubPage);
[email protected]65549182012-02-25 00:45:405607 } else if (SyncPromoUI::ShouldShowSyncPromo(profile()) &&
5608 login_service->current_login_ui() == NULL) {
5609 // There is no currently active login UI, so display a new promo page.
[email protected]aff3de22012-02-13 22:58:065610 GURL url(SyncPromoUI::GetSyncPromoURL(GURL(), false, std::string()));
5611 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
5612 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
5613 ShowSingletonTabOverwritingNTP(params);
5614 } else {
[email protected]65549182012-02-25 00:45:405615 LoginUIServiceFactory::GetForProfile(
5616 profile()->GetOriginalProfile())->ShowLoginUI();
[email protected]aff3de22012-02-13 22:58:065617 }
[email protected]2e2cacc2011-07-12 21:54:265618}
[email protected]afcb43562011-09-02 23:33:385619
5620void Browser::ToggleSpeechInput() {
[email protected]41f022e2012-01-31 05:56:405621 GetSelectedWebContents()->GetRenderViewHost()->ToggleSpeechInput();
[email protected]afcb43562011-09-02 23:33:385622}