blob: d4ee67f0084151da38e71cacfca9580626a641cf [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]7fb4bbb2012-05-27 18:06:2244#include "chrome/browser/download/download_crx_util.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]a1bc3b82012-04-19 19:32:2048#include "chrome/browser/download/download_shelf.h"
[email protected]59560e0b2009-06-04 03:30:2249#include "chrome/browser/download/download_started_animation.h"
[email protected]a53209b2012-01-20 16:48:1650#include "chrome/browser/download/download_util.h"
[email protected]9c1662b2012-03-06 15:44:3351#include "chrome/browser/extensions/browser_extension_window_controller.h"
[email protected]bb461532010-11-26 21:50:2352#include "chrome/browser/extensions/crx_installer.h"
[email protected]49098f702011-10-13 03:47:1853#include "chrome/browser/extensions/default_apps_trial.h"
[email protected]10abd192010-09-30 02:03:4954#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0055#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0856#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5957#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0458#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]3a29a6e2011-08-24 18:26:2159#include "chrome/browser/file_select_helper.h"
[email protected]820735792010-07-29 23:40:0160#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4961#include "chrome/browser/google/google_url_tracker.h"
[email protected]7e204122011-09-01 18:56:2162#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]6b723f82010-10-05 20:14:2763#include "chrome/browser/instant/instant_controller.h"
[email protected]5aab5e22010-12-08 22:13:2964#include "chrome/browser/instant/instant_unload_handler.h"
[email protected]7d189022011-08-25 22:54:2065#include "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
[email protected]8f0bbd62012-02-22 03:37:1866#include "chrome/browser/intents/web_intents_util.h"
[email protected]2e6389f2012-05-18 19:41:2567#include "chrome/browser/lifetime/application_lifetime.h"
[email protected]a239c3f2009-02-17 22:13:1968#include "chrome/browser/net/url_fixer_upper.h"
[email protected]2c4fb7b2011-04-02 06:33:2969#include "chrome/browser/notifications/notification_ui_manager.h"
[email protected]14a000d2010-04-29 21:44:2470#include "chrome/browser/platform_util.h"
[email protected]4e94ab32011-08-05 05:28:2771#include "chrome/browser/prefs/incognito_mode_prefs.h"
[email protected]37858e52010-08-26 00:22:0272#include "chrome/browser/prefs/pref_service.h"
[email protected]4fdf6742012-01-10 20:14:3673#include "chrome/browser/prerender/prerender_manager.h"
74#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]d952a052011-09-06 18:42:4575#include "chrome/browser/prerender/prerender_tab_helper.h"
[email protected]02337592010-09-27 18:38:2576#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]0996e9b2011-08-26 17:59:0177#include "chrome/browser/printing/print_preview_tab_controller.h"
[email protected]68761472011-08-31 18:55:1478#include "chrome/browser/printing/print_view_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3379#include "chrome/browser/profiles/profile.h"
[email protected]5e919242012-02-13 23:59:3580#include "chrome/browser/profiles/profile_destroyer.h"
[email protected]5a17d492011-10-24 19:37:0381#include "chrome/browser/profiles/profile_manager.h"
[email protected]a7be6982011-12-12 21:53:5782#include "chrome/browser/profiles/profile_metrics.h"
[email protected]67baffc82011-12-19 18:03:0783#include "chrome/browser/repost_form_warning_controller.h"
[email protected]81898992011-06-14 22:15:0084#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4485#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1586#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1887#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0688#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1589#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1390#include "chrome/browser/sync/profile_sync_service.h"
[email protected]5e61afb92012-01-27 20:09:1391#include "chrome/browser/sync/profile_sync_service_factory.h"
[email protected]40f047972009-11-25 03:54:4092#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0493#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2994#include "chrome/browser/tab_contents/background_contents.h"
[email protected]4fdf6742012-01-10 20:14:3695#include "chrome/browser/tab_contents/retargeting_details.h"
[email protected]7cceebac2011-03-03 00:32:2196#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]1ab4ddf2011-07-21 04:48:0497#include "chrome/browser/tab_contents/tab_util.h"
[email protected]ffa6f592011-06-24 22:03:5798#include "chrome/browser/themes/theme_service.h"
99#include "chrome/browser/themes/theme_service_factory.h"
[email protected]82194b5fb2012-05-22 23:53:07100#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h"
[email protected]e7cfdbd2011-04-22 14:41:37101#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:14102#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]ef557022012-03-16 10:05:33103#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
[email protected]55452902011-06-01 21:57:47104#include "chrome/browser/ui/browser_dialogs.h"
[email protected]d8748142012-05-16 21:13:43105#include "chrome/browser/ui/browser_finder.h"
[email protected]6768ac02011-04-06 17:41:04106#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:37107#include "chrome/browser/ui/browser_navigator.h"
[email protected]fb7da4132011-03-15 15:51:00108#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]ef557022012-03-16 10:05:33109#include "chrome/browser/ui/browser_toolbar_model_delegate.h"
[email protected]00070c732011-04-09 15:31:33110#include "chrome/browser/ui/browser_window.h"
[email protected]31145092011-09-30 01:49:44111#include "chrome/browser/ui/constrained_window_tab_helper.h"
[email protected]a44657202012-01-09 05:48:31112#include "chrome/browser/ui/extensions/shell_window.h"
[email protected]45300ad42010-12-02 15:51:14113#include "chrome/browser/ui/find_bar/find_bar.h"
114#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:38115#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]bf8708692011-12-20 21:24:28116#include "chrome/browser/ui/fullscreen_controller.h"
[email protected]2f516c792011-09-19 22:22:09117#include "chrome/browser/ui/global_error.h"
118#include "chrome/browser/ui/global_error_service.h"
119#include "chrome/browser/ui/global_error_service_factory.h"
[email protected]8be45842012-04-13 19:49:29120#include "chrome/browser/ui/hung_plugin_tab_helper.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]3d61dd02012-06-07 00:05:53129#include "chrome/browser/ui/tab_contents/tab_contents.h"
[email protected]9a800652010-12-02 17:08:44130#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]b56e2e32012-05-11 21:18:04131#include "chrome/browser/ui/tabs/tab_finder.h"
[email protected]6a3ec2312010-12-02 19:30:19132#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]b56e2e32012-05-11 21:18:04133#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]f847e6082011-03-24 00:08:26134#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]daa9e382012-01-06 00:30:34135#include "chrome/browser/ui/webui/feedback_ui.h"
[email protected]a9acdff2012-03-08 04:04:52136#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
[email protected]6a1622a2011-09-20 22:37:45137#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
[email protected]a048ad22012-03-23 04:26:56138#include "chrome/browser/ui/webui/options2/content_settings_handler2.h"
[email protected]65549182012-02-25 00:45:40139#include "chrome/browser/ui/webui/signin/login_ui_service.h"
140#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
[email protected]9a800652010-12-02 17:08:44141#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54142#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50143#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33144#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:27145#include "chrome/common/chrome_notification_types.h"
[email protected]d938aed92009-01-22 19:49:33146#include "chrome/common/chrome_switches.h"
[email protected]7d189022011-08-25 22:54:20147#include "chrome/common/custom_handlers/protocol_handler.h"
[email protected]5b1a0e22009-05-26 19:00:58148#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33149#include "chrome/common/extensions/extension_constants.h"
[email protected]06305962012-05-09 22:34:36150#include "chrome/common/net/url_util.h"
[email protected]8a53ee042009-01-21 16:41:33151#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25152#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34153#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23154#include "chrome/common/web_apps.h"
[email protected]da8543762012-03-20 08:52:20155#include "content/public/browser/color_chooser.h"
[email protected]0e12d7d2011-12-01 16:21:44156#include "content/public/browser/devtools_manager.h"
[email protected]e582fdd2011-12-20 16:48:17157#include "content/public/browser/download_item.h"
158#include "content/public/browser/download_manager.h"
[email protected]cadaec52012-02-08 21:53:13159#include "content/public/browser/interstitial_page.h"
[email protected]d9083482012-01-06 00:38:46160#include "content/public/browser/invalidate_type.h"
[email protected]cdcb1dee2012-01-04 00:46:20161#include "content/public/browser/navigation_controller.h"
[email protected]022af742011-12-28 18:37:25162#include "content/public/browser/navigation_entry.h"
[email protected]7f6f44c2011-12-14 13:23:38163#include "content/public/browser/notification_details.h"
164#include "content/public/browser/notification_service.h"
[email protected]3a5180ae2011-12-21 02:39:38165#include "content/public/browser/plugin_service.h"
[email protected]9c1662b2012-03-06 15:44:33166#include "content/public/browser/render_process_host.h"
167#include "content/public/browser/render_view_host.h"
[email protected]b6583592012-01-25 19:52:33168#include "content/public/browser/site_instance.h"
[email protected]7f6f44c2011-12-14 13:23:38169#include "content/public/browser/user_metrics.h"
[email protected]d9083482012-01-06 00:38:46170#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:10171#include "content/public/browser/web_contents_view.h"
[email protected]0d9989d2011-12-21 20:26:00172#include "content/public/browser/web_intents_dispatcher.h"
[email protected]4573fbd2011-10-31 20:25:18173#include "content/public/common/content_restriction.h"
[email protected]c08950d22011-10-13 22:20:29174#include "content/public/common/content_switches.h"
[email protected]0f083402011-11-22 02:59:01175#include "content/public/common/page_zoom.h"
[email protected]cadaec52012-02-08 21:53:13176#include "content/public/common/renderer_preferences.h"
[email protected]a3e18c42009-03-04 23:36:05177#include "grit/chromium_strings.h"
178#include "grit/generated_resources.h"
179#include "grit/locale_settings.h"
[email protected]d952a052011-09-06 18:42:45180#include "grit/theme_resources_standard.h"
[email protected]8a53ee042009-01-21 16:41:33181#include "net/base/net_util.h"
182#include "net/base/registry_controlled_domain.h"
[email protected]4d7c4ef2012-03-16 01:47:12183#include "net/cookies/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33184#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39185#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17186#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38187#include "ui/gfx/point.h"
[email protected]ce9751942011-09-21 01:57:24188#include "webkit/glue/web_intent_data.h"
[email protected]3a3b75a2012-06-01 08:38:36189#include "webkit/glue/web_intent_service_data.h"
[email protected]4a19be92011-09-22 14:25:02190#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33191#include "webkit/glue/window_open_disposition.h"
[email protected]3a5180ae2011-12-21 02:39:38192#include "webkit/plugins/webplugininfo.h"
[email protected]8a53ee042009-01-21 16:41:33193
194#if defined(OS_WIN)
[email protected]36d5e5592010-11-15 20:45:59195#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15196#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59197#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12198#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19199#include "chrome/browser/ui/view_ids.h"
[email protected]dcd57762011-06-25 12:18:51200#include "ui/base/win/shell.h"
[email protected]8a53ee042009-01-21 16:41:33201#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33202
[email protected]6a4f5af22009-09-23 22:43:00203#if defined(OS_MACOSX)
[email protected]feb72832012-03-08 00:38:24204#include "ui/base/cocoa/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00205#endif
206
[email protected]b7969202010-05-14 21:29:26207#if defined(OS_CHROMEOS)
[email protected]b7813a22012-04-04 18:41:02208#include "chrome/browser/chromeos/gdata/gdata_util.h"
[email protected]eab8c0f2011-11-18 22:33:50209#endif
210
[email protected]dc04be7c2012-03-15 23:57:49211#if defined(USE_ASH)
[email protected]bafda132012-02-16 19:32:51212#include "ash/ash_switches.h"
[email protected]c2f0a892012-01-24 22:19:21213#endif
214
[email protected]8a53ee042009-01-21 16:41:33215using base::TimeDelta;
[email protected]b87ee522012-05-18 15:16:54216using content::NativeWebKeyboardEvent;
[email protected]c5eed492012-01-04 17:07:50217using content::NavigationController;
[email protected]10f417c52011-12-28 21:04:23218using content::NavigationEntry;
[email protected]e5d549d2011-12-28 01:29:20219using content::OpenURLParams;
[email protected]3a5180ae2011-12-21 02:39:38220using content::PluginService;
[email protected]e5d549d2011-12-28 01:29:20221using content::Referrer;
[email protected]b6583592012-01-25 19:52:33222using content::SiteInstance;
[email protected]d583e3f22011-12-27 21:38:17223using content::SSLStatus;
[email protected]7f6f44c2011-12-14 13:23:38224using content::UserMetricsAction;
[email protected]ea049a02011-12-25 21:37:09225using content::WebContents;
[email protected]1c321ee52012-05-21 03:02:34226using extensions::Extension;
[email protected]20c07f8e2012-05-31 08:43:14227using ui::WebDialogDelegate;
initial.commit09911bf2008-07-26 23:55:29228
[email protected]36b6dcb2008-11-12 01:19:57229///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29230
[email protected]505323e22009-01-24 02:47:58231namespace {
232
[email protected]91a79232010-11-10 18:15:08233// The URL to be loaded to display the "Report a broken page" form.
234const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20235 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08236 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
237
238// The URL for the privacy dashboard.
239const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
240
241// How long we wait before updating the browser chrome while loading a page.
242const int kUIUpdateCoalescingTimeMS = 200;
243
244const char kHashMark[] = "#";
245
[email protected]50dc3deb2011-07-07 01:07:19246// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
[email protected]10f417c52011-12-28 21:04:23247bool HasInternalURL(const NavigationEntry* entry) {
[email protected]50dc3deb2011-07-07 01:07:19248 if (!entry)
249 return false;
250
251 // Check the |virtual_url()| first. This catches regular chrome:// URLs
252 // including URLs that were rewritten (such as chrome://bookmarks).
[email protected]36fc0392011-12-25 03:59:51253 if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme))
[email protected]50dc3deb2011-07-07 01:07:19254 return true;
255
256 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
257 // view-source: of a chrome:// URL.
[email protected]36fc0392011-12-25 03:59:51258 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme))
259 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme);
[email protected]50dc3deb2011-07-07 01:07:19260
261 return false;
262}
263
[email protected]113baf92012-02-14 02:21:06264// Parse two comma-separated integers from str. Return true on success.
265bool ParseCommaSeparatedIntegers(const std::string& str,
266 int* ret_num1,
267 int* ret_num2) {
268 size_t num1_size = str.find_first_of(',');
269 if (num1_size == std::string::npos)
270 return false;
271
272 size_t num2_pos = num1_size + 1;
273 size_t num2_size = str.size() - num2_pos;
274 int num1, num2;
275 if (!base::StringToInt(str.substr(0, num1_size), &num1) ||
276 !base::StringToInt(str.substr(num2_pos, num2_size), &num2))
277 return false;
278
279 *ret_num1 = num1;
280 *ret_num2 = num2;
281 return true;
282}
283
[email protected]0da58292012-03-22 20:37:21284bool AllowPanels(const std::string& app_name) {
[email protected]cae97652012-04-20 03:12:12285 return PanelManager::ShouldUsePanels(
286 web_app::GetExtensionIdFromApplicationName(app_name));
[email protected]0da58292012-03-22 20:37:21287}
288
[email protected]92655362012-04-20 21:33:17289bool DisplayOldDownloadsUI() {
290 return !CommandLine::ForCurrentProcess()->HasSwitch(
291 switches::kDownloadsNewUI);
292}
293
[email protected]505323e22009-01-24 02:47:58294} // namespace
295
[email protected]b35b26b32011-05-05 20:35:14296////////////////////////////////////////////////////////////////////////////////
297// Browser, CreateParams:
298
[email protected]da22aa62012-04-04 18:54:35299Browser::CreateParams::CreateParams()
300 : type(TYPE_TABBED),
301 profile(NULL),
302 initial_show_state(ui::SHOW_STATE_DEFAULT),
303 is_session_restore(false) {
304}
305
[email protected]b35b26b32011-05-05 20:35:14306Browser::CreateParams::CreateParams(Type type, Profile* profile)
307 : type(type),
[email protected]a636d8e52012-02-28 15:40:41308 profile(profile),
[email protected]0da58292012-03-22 20:37:21309 app_type(APP_TYPE_HOST),
[email protected]a636d8e52012-02-28 15:40:41310 initial_show_state(ui::SHOW_STATE_DEFAULT),
311 is_session_restore(false) {
[email protected]b35b26b32011-05-05 20:35:14312}
313
[email protected]da22aa62012-04-04 18:54:35314// static
315Browser::CreateParams Browser::CreateParams::CreateForApp(
316 Type type,
317 const std::string& app_name,
318 const gfx::Rect& window_bounds,
319 Profile* profile) {
320 DCHECK(type != TYPE_TABBED);
321 DCHECK(!app_name.empty());
322
323 if (type == TYPE_PANEL && !AllowPanels(app_name))
324 type = TYPE_POPUP;
325
326 CreateParams params(type, profile);
327 params.app_name = app_name;
328 params.app_type = APP_TYPE_CHILD;
329 params.initial_bounds = window_bounds;
330
331 return params;
332}
333
334// static
335Browser::CreateParams Browser::CreateParams::CreateForDevTools(
336 Profile* profile) {
337 CreateParams params(TYPE_POPUP, profile);
338 params.app_name = DevToolsWindow::kDevToolsApp;
339 return params;
340}
341
[email protected]36b6dcb2008-11-12 01:19:57342///////////////////////////////////////////////////////////////////////////////
343// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29344
[email protected]299dabd2008-11-19 02:27:16345Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05346 : type_(type),
347 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39348 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40349 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]2fc15ae2012-05-06 00:01:37350 tab_strip_model_(new TabStripModel(this, profile))),
[email protected]1fc025202009-01-20 23:03:14351 command_updater_(this),
[email protected]0da58292012-03-22 20:37:21352 app_type_(APP_TYPE_HOST),
[email protected]15952e462008-11-14 00:29:05353 chrome_updater_factory_(this),
354 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06355 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]400eaf82011-08-22 15:47:39356 show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]8bc061f2011-08-31 22:46:23357 is_session_restore_(false),
[email protected]24f1477532011-11-22 22:55:36358 weak_factory_(this),
[email protected]867125a02009-12-10 06:01:48359 block_command_execution_(false),
360 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51361 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00362 pending_web_app_action_(NONE),
363 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]ef557022012-03-16 10:05:33364 content_setting_bubble_model_delegate_(
365 new BrowserContentSettingBubbleModelDelegate(this))),
366 ALLOW_THIS_IN_INITIALIZER_LIST(
367 toolbar_model_delegate_(
368 new BrowserToolbarModelDelegate(this))),
369 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]fb7da4132011-03-15 15:51:00370 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48371 new BrowserTabRestoreServiceDelegate(this))),
[email protected]afefa74e2011-07-26 05:04:23372 ALLOW_THIS_IN_INITIALIZER_LIST(
373 synced_window_delegate_(
374 new BrowserSyncedWindowDelegate(this))),
[email protected]8a5e0ca2011-08-25 06:30:47375 bookmark_bar_state_(BookmarkBar::HIDDEN),
[email protected]2f516c792011-09-19 22:22:09376 window_has_shown_(false) {
[email protected]2fc15ae2012-05-06 00:01:37377 tab_strip_model_->AddObserver(this);
378
[email protected]ef557022012-03-16 10:05:33379 toolbar_model_.reset(new ToolbarModel(toolbar_model_delegate_.get()));
380
[email protected]432115822011-07-10 15:52:27381 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
[email protected]ad50def52011-10-19 23:17:07382 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27383 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]a93089b12011-11-22 20:47:38384 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27385 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]a93089b12011-11-22 20:47:38386 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27387 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
[email protected]a93089b12011-11-22 20:47:38388 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27389 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
[email protected]ad50def52011-10-19 23:17:07390 content::NotificationService::AllSources());
[email protected]6b40bb582012-03-15 20:50:38391#if defined(ENABLE_THEMES)
[email protected]ffa6f592011-06-24 22:03:57392 registrar_.Add(
[email protected]432115822011-07-10 15:52:27393 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
[email protected]6c2381d2011-10-19 02:52:53394 content::Source<ThemeService>(
395 ThemeServiceFactory::GetForProfile(profile_)));
[email protected]6b40bb582012-03-15 20:50:38396#endif
[email protected]ea049a02011-12-25 21:37:09397 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
[email protected]ad50def52011-10-19 23:17:07398 content::NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29399
[email protected]9e823662010-10-13 23:36:00400 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04401 if (local_state) {
402 local_pref_registrar_.Init(local_state);
403 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
404 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
[email protected]623294c42012-04-27 18:27:14405 local_pref_registrar_.Add(prefs::kInManagedMode, this);
[email protected]97b46382011-05-02 13:23:04406 }
407
408 profile_pref_registrar_.Init(profile_->GetPrefs());
409 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
410 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
[email protected]3710d0002011-10-11 00:35:00411 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this);
[email protected]6c6b02d2011-09-02 03:36:47412 profile_pref_registrar_.Add(prefs::kHomePage, this);
[email protected]97b46382011-05-02 13:23:04413 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]4e94ab32011-08-05 05:28:27414 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
[email protected]9e823662010-10-13 23:36:00415
initial.commit09911bf2008-07-26 23:55:29416 InitCommandState();
417 BrowserList::AddBrowser(this);
418
[email protected]97b46382011-05-02 13:23:04419 // NOTE: These prefs all need to be explicitly destroyed in the destructor
420 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29421 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
422 profile_->GetPrefs(), NULL);
[email protected]281918912010-05-27 22:05:13423
[email protected]92371eb2011-04-28 11:50:15424 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13425 if (tab_restore_service_) {
426 tab_restore_service_->AddObserver(this);
427 TabRestoreServiceChanged(tab_restore_service_);
428 }
[email protected]d3b98c82010-07-14 07:45:59429
[email protected]5e61afb92012-01-27 20:09:13430 ProfileSyncService* service =
431 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
432 if (service)
433 service->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30434
[email protected]2031cf9d2010-10-12 05:05:37435 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26436
437 // Make sure TabFinder has been created. This does nothing if TabFinder is
438 // not enabled.
439 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48440
441 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
[email protected]a7be6982011-12-12 21:53:57442
443 FilePath profile_path = profile->GetPath();
444 ProfileMetrics::LogProfileLaunch(profile_path);
initial.commit09911bf2008-07-26 23:55:29445}
446
447Browser::~Browser() {
[email protected]5e61afb92012-01-27 20:09:13448 ProfileSyncService* service =
449 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
450 if (service)
451 service->RemoveObserver(this);
[email protected]d3b98c82010-07-14 07:45:59452
[email protected]2fc15ae2012-05-06 00:01:37453 // The tab strip should not have any tabs at this point.
454 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers())
455 DCHECK(tab_strip_model_->empty());
456 tab_strip_model_->RemoveObserver(this);
457
initial.commit09911bf2008-07-26 23:55:29458 BrowserList::RemoveBrowser(this);
459
[email protected]bdc6ccd12012-03-20 22:06:13460 SessionService* session_service =
461 SessionServiceFactory::GetForProfile(profile_);
462 if (session_service)
463 session_service->WindowClosed(session_id_);
464
465 TabRestoreService* tab_restore_service =
466 TabRestoreServiceFactory::GetForProfile(profile());
467 if (tab_restore_service)
468 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
469
[email protected]7be64502011-05-03 17:51:47470#if !defined(OS_MACOSX)
[email protected]d8748142012-05-16 21:13:43471 if (!browser::GetBrowserCount(profile_)) {
initial.commit09911bf2008-07-26 23:55:29472 // We're the last browser window with this profile. We need to nuke the
473 // TabRestoreService, which will start the shutdown of the
474 // NavigationControllers and allow for proper shutdown. If we don't do this
475 // chrome won't shutdown cleanly, and may end up crashing when some
476 // thread tries to use the IO thread (or another thread) that is no longer
477 // valid.
[email protected]fbc947b2009-06-19 13:28:24478 // This isn't a valid assumption for Mac OS, as it stays running after
479 // the last browser has closed. The Mac equivalent is in its app
480 // controller.
[email protected]92371eb2011-04-28 11:50:15481 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29482 }
[email protected]fbc947b2009-06-19 13:28:24483#endif
initial.commit09911bf2008-07-26 23:55:29484
[email protected]97b46382011-05-02 13:23:04485 profile_pref_registrar_.RemoveAll();
486 local_pref_registrar_.RemoveAll();
487
[email protected]9a8c4022011-01-25 14:25:33488 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33489
initial.commit09911bf2008-07-26 23:55:29490 if (profile_->IsOffTheRecord() &&
[email protected]474e5db2011-08-12 13:02:23491 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
[email protected]5e919242012-02-13 23:59:35492 // An incognito profile is no longer needed, this indirectly frees
493 // its cache and cookies once it gets destroyed at the appropriate time.
[email protected]4dffabe2012-05-19 14:37:06494 ProfileDestroyer::DestroyProfileWhenAppropriate(profile_);
initial.commit09911bf2008-07-26 23:55:29495 }
496
497 // There may be pending file dialogs, we need to tell them that we've gone
498 // away so they don't try and call back to us.
499 if (select_file_dialog_.get())
500 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13501
502 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29503}
504
[email protected]15952e462008-11-14 00:29:05505// static
506Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14507 Browser* browser = new Browser(TYPE_TABBED, profile);
508 browser->InitBrowserWindow();
509 return browser;
510}
511
512// static
513Browser* Browser::CreateWithParams(const CreateParams& params) {
[email protected]a636d8e52012-02-28 15:40:41514 if (!params.app_name.empty())
515 RegisterAppPrefs(params.app_name, params.profile);
516
[email protected]b35b26b32011-05-05 20:35:14517 Browser* browser = new Browser(params.type, params.profile);
518 browser->app_name_ = params.app_name;
[email protected]0da58292012-03-22 20:37:21519 browser->app_type_ = params.app_type;
[email protected]81b2b0ac2011-11-23 01:54:48520 browser->set_override_bounds(params.initial_bounds);
[email protected]a636d8e52012-02-28 15:40:41521 browser->set_show_state(params.initial_show_state);
522 browser->set_is_session_restore(params.is_session_restore);
523
[email protected]9800de5e2011-03-11 18:19:49524 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05525 return browser;
526}
[email protected]6104acf2008-11-11 22:27:34527
[email protected]9800de5e2011-03-11 18:19:49528void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05529 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43530
[email protected]9800de5e2011-03-11 18:19:49531 window_ = CreateBrowserWindow();
[email protected]01a5a762011-11-21 05:40:55532 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
[email protected]15952e462008-11-14 00:29:05533
[email protected]5e37c452011-09-06 19:31:39534#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]6a34951a2012-01-17 18:10:40535 // Set the app user model id for this application to that of the application
536 // name. See http://crbug.com/7028.
537 ui::win::SetAppIdForWindow(
538 is_app() && !is_type_panel() ?
539 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
540 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
[email protected]90556dd2012-06-07 20:26:18541 window()->GetNativeWindow());
[email protected]45446a52010-11-04 17:41:00542
[email protected]6a34951a2012-01-17 18:10:40543 if (is_type_panel()) {
544 ui::win::SetAppIconForWindow(ShellIntegration::GetChromiumIconPath(),
[email protected]90556dd2012-06-07 20:26:18545 window()->GetNativeWindow());
[email protected]45446a52010-11-04 17:41:00546 }
[email protected]80cf3562009-11-17 08:17:24547#endif
548
[email protected]41d9faf2012-02-28 23:46:02549 // Create the extension window controller before sending notifications.
550 extension_window_controller_.reset(
551 new BrowserExtensionWindowController(this));
552
[email protected]ad50def52011-10-19 23:17:07553 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27554 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
[email protected]6c2381d2011-10-19 02:52:53555 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:07556 content::NotificationService::NoDetails());
[email protected]14d8c66e2009-09-22 00:32:52557
[email protected]15952e462008-11-14 00:29:05558 PrefService* local_state = g_browser_process->local_state();
[email protected]2f516c792011-09-19 22:22:09559 if (local_state && local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01560 prefs::kAutofillPersonalDataManagerFirstRun) &&
561 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46562 // Notify PDM that this is a first run.
563#if defined(OS_WIN)
[email protected]ea9edcb02011-09-23 22:05:04564 ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_));
[email protected]f69c8852010-10-12 02:36:46565#endif // defined(OS_WIN)
566 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01567 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46568 }
[email protected]6a1622a2011-09-20 22:37:45569
570 // Permanently dismiss ntp4 bubble for new users.
[email protected]dfa08b042011-12-28 23:07:21571 if (first_run::IsChromeFirstRun())
[email protected]27e96a972011-10-20 20:06:55572 NewTabPageHandler::DismissIntroMessage(local_state);
initial.commit09911bf2008-07-26 23:55:29573}
574
[email protected]bf8708692011-12-20 21:24:28575void Browser::SetWindowForTesting(BrowserWindow* window) {
576 DCHECK(!window_);
577 window_ = window;
578 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
579}
580
[email protected]36b6dcb2008-11-12 01:19:57581///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07582// Getters & Setters
583
[email protected]b77cb302009-10-29 04:09:17584FindBarController* Browser::GetFindBarController() {
585 if (!find_bar_controller_.get()) {
[email protected]632983f2011-08-08 22:51:24586 FindBar* find_bar = window_->CreateFindBar();
[email protected]b77cb302009-10-29 04:09:17587 find_bar_controller_.reset(new FindBarController(find_bar));
588 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]3d61dd02012-06-07 00:05:53589 find_bar_controller_->ChangeTabContents(GetActiveTabContents());
[email protected]b77cb302009-10-29 04:09:17590 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
591 }
592 return find_bar_controller_.get();
593}
594
[email protected]24db8a072009-10-29 20:35:37595bool Browser::HasFindBarController() const {
596 return find_bar_controller_.get() != NULL;
597}
598
[email protected]b35b26b32011-05-05 20:35:14599bool Browser::is_app() const {
600 return !app_name_.empty();
601}
602
603bool Browser::is_devtools() const {
604 return app_name_ == DevToolsWindow::kDevToolsApp;
605}
606
[email protected]5c238752009-06-13 10:29:07607///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57608// Browser, Creation Helpers:
609
610// static
[email protected]4aa3f7722012-03-23 19:09:16611void Browser::NewEmptyWindow(Profile* profile) {
[email protected]eddcf7502012-02-09 22:43:48612 bool incognito = profile->IsOffTheRecord();
613 PrefService* prefs = profile->GetPrefs();
614 if (incognito) {
615 if (IncognitoModePrefs::GetAvailability(prefs) ==
616 IncognitoModePrefs::DISABLED) {
617 incognito = false;
618 }
619 } else {
620 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
621 IncognitoModePrefs::ShouldLaunchIncognito(
622 *CommandLine::ForCurrentProcess(), prefs)) {
623 incognito = true;
624 }
625 }
626
627 if (incognito) {
628 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]4aa3f7722012-03-23 19:09:16629 OpenEmptyWindow(profile->GetOffTheRecordProfile());
[email protected]eddcf7502012-02-09 22:43:48630 } else {
631 content::RecordAction(UserMetricsAction("NewWindow"));
632 SessionService* session_service =
633 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
634 if (!session_service ||
635 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
[email protected]4aa3f7722012-03-23 19:09:16636 OpenEmptyWindow(profile->GetOriginalProfile());
[email protected]eddcf7502012-02-09 22:43:48637 }
638 }
639}
640
641// static
[email protected]2e0f8e92012-03-14 21:31:35642Browser* Browser::OpenEmptyWindow(Profile* profile) {
[email protected]15952e462008-11-14 00:29:05643 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57644 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05645 browser->window()->Show();
[email protected]2e0f8e92012-03-14 21:31:35646 return browser;
initial.commit09911bf2008-07-26 23:55:29647}
648
[email protected]36b6dcb2008-11-12 01:19:57649// static
[email protected]fbc947b2009-06-19 13:28:24650void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15651 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24652 if (service)
653 service->RestoreMostRecentEntry(NULL);
654}
655
656// static
[email protected]36b6dcb2008-11-12 01:19:57657void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]d8748142012-05-16 21:13:43658 Browser* browser = browser::FindOrCreateTabbedBrowser(
[email protected]cecc93a2010-10-05 15:58:55659 profile->GetOffTheRecordProfile());
[email protected]2905f742011-10-13 03:51:58660 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK);
[email protected]15952e462008-11-14 00:29:05661 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17662}
663
[email protected]36b6dcb2008-11-12 01:19:57664// static
[email protected]90a8bf252010-03-12 00:09:47665void Browser::OpenBookmarkManagerWindow(Profile* profile) {
666 Browser* browser = Browser::Create(profile);
[email protected]0af8f132011-07-16 01:37:02667 browser->OpenBookmarkManager();
[email protected]90a8bf252010-03-12 00:09:47668 browser->window()->Show();
669}
670
[email protected]057d959a2010-03-12 02:56:20671#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47672// static
[email protected]a9fbb0962012-03-21 23:25:13673void Browser::OpenAboutWindow(Profile* profile) {
674 Browser* browser = Browser::Create(profile);
675 browser->OpenAboutChromeDialog();
676 browser->window()->Show();
677}
678
679// static
[email protected]91a5b3e2009-10-30 19:32:22680void Browser::OpenHistoryWindow(Profile* profile) {
681 Browser* browser = Browser::Create(profile);
682 browser->ShowHistoryTab();
683 browser->window()->Show();
684}
685
686// static
687void Browser::OpenDownloadsWindow(Profile* profile) {
688 Browser* browser = Browser::Create(profile);
689 browser->ShowDownloadsTab();
690 browser->window()->Show();
691}
692
693// static
[email protected]1fdff702009-10-22 00:36:18694void Browser::OpenHelpWindow(Profile* profile) {
695 Browser* browser = Browser::Create(profile);
[email protected]202802e42011-07-06 11:40:46696 browser->ShowHelpTab();
[email protected]1fdff702009-10-22 00:36:18697 browser->window()->Show();
698}
[email protected]4a42d272010-06-18 01:29:42699
[email protected]eca258132010-11-15 23:33:08700// static
[email protected]4a42d272010-06-18 01:29:42701void Browser::OpenOptionsWindow(Profile* profile) {
702 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49703 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42704 browser->window()->Show();
705}
[email protected]c8de64a2011-01-25 17:10:23706
707// static
[email protected]713d01b2012-03-24 05:58:20708void Browser::OpenSyncSetupWindow(Profile* profile,
709 SyncPromoUI::Source source) {
[email protected]65549182012-02-25 00:45:40710 Browser* browser = Browser::Create(profile);
[email protected]713d01b2012-03-24 05:58:20711 browser->ShowSyncSetup(source);
[email protected]65549182012-02-25 00:45:40712 browser->window()->Show();
713}
714
715// static
[email protected]ddddfda2011-07-14 23:19:39716void Browser::OpenClearBrowsingDataDialogWindow(Profile* profile) {
[email protected]c8de64a2011-01-25 17:10:23717 Browser* browser = Browser::Create(profile);
718 browser->OpenClearBrowsingDataDialog();
719 browser->window()->Show();
720}
721
722// static
723void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
724 Browser* browser = Browser::Create(profile);
725 browser->OpenImportSettingsDialog();
726 browser->window()->Show();
727}
[email protected]b99081b2011-03-10 17:43:47728
729// static
730void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
731 Browser* browser = Browser::Create(profile);
732 browser->OpenInstantConfirmDialog();
733 browser->window()->Show();
734}
[email protected]1fdff702009-10-22 00:36:18735#endif
736
[email protected]ccb55cf52010-03-06 22:02:04737// static
738void Browser::OpenExtensionsWindow(Profile* profile) {
739 Browser* browser = Browser::Create(profile);
740 browser->ShowExtensionsTab();
741 browser->window()->Show();
742}
743
[email protected]36b6dcb2008-11-12 01:19:57744///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57745// Browser, State Storage and Retrieval for UI:
746
[email protected]57ecc4b2010-08-11 03:02:51747std::string Browser::GetWindowPlacementKey() const {
748 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57749 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51750 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57751 name.append(app_name_);
752 }
[email protected]bc9a5152008-11-15 00:32:04753 return name;
754}
[email protected]36b6dcb2008-11-12 01:19:57755
[email protected]bc9a5152008-11-15 00:32:04756bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14757 switch (type_) {
758 case TYPE_TABBED:
759 return true;
760 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:51761 // Only save the window placement of popups if they are restored,
762 // or the window belongs to DevTools.
[email protected]a636d8e52012-02-28 15:40:41763#if defined USE_AURA
764 if (is_app())
765 return true;
766#endif
[email protected]bd6cdf22011-06-21 08:11:51767 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:14768 case TYPE_PANEL:
769 // Do not save the window placement of panels.
770 return false;
771 default:
772 return false;
773 }
[email protected]bc9a5152008-11-15 00:32:04774}
[email protected]36b6dcb2008-11-12 01:19:57775
[email protected]400eaf82011-08-22 15:47:39776void Browser::SaveWindowPlacement(const gfx::Rect& bounds,
777 ui::WindowShowState show_state) {
[email protected]bc9a5152008-11-15 00:32:04778 // Save to the session storage service, used when reloading a past session.
779 // Note that we don't want to be the ones who cause lazy initialization of
780 // the session service. This function gets called during initial window
781 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:15782 SessionService* session_service =
783 SessionServiceFactory::GetForProfileIfExisting(profile());
784 if (session_service)
[email protected]400eaf82011-08-22 15:47:39785 session_service->SetWindowBounds(session_id_, bounds, show_state);
[email protected]36b6dcb2008-11-12 01:19:57786}
787
[email protected]15952e462008-11-14 00:29:05788gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]113baf92012-02-14 02:21:06789 gfx::Rect restored_bounds = override_bounds_;
790 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
791 &restored_bounds);
792
[email protected]bb975362009-01-21 01:00:22793 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05794 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
795 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
796 if (record_mode || playback_mode) {
797 // In playback/record mode we always fix the size of the browser and
798 // move it to (0,0). The reason for this is two reasons: First we want
799 // resize/moves in the playback to still work, and Second we want
800 // playbacks to work (as much as possible) on machines w/ different
801 // screen sizes.
[email protected]113baf92012-02-14 02:21:06802 restored_bounds = gfx::Rect(0, 0, 800, 600);
[email protected]15952e462008-11-14 00:29:05803 }
804
[email protected]113baf92012-02-14 02:21:06805 // The following options override playback/record.
806 if (parsed_command_line.HasSwitch(switches::kWindowSize)) {
807 std::string str =
808 parsed_command_line.GetSwitchValueASCII(switches::kWindowSize);
809 int width, height;
810 if (ParseCommaSeparatedIntegers(str, &width, &height))
811 restored_bounds.set_size(gfx::Size(width, height));
812 }
813 if (parsed_command_line.HasSwitch(switches::kWindowPosition)) {
814 std::string str =
815 parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition);
816 int x, y;
817 if (ParseCommaSeparatedIntegers(str, &x, &y))
818 restored_bounds.set_origin(gfx::Point(x, y));
819 }
820
[email protected]15952e462008-11-14 00:29:05821 return restored_bounds;
822}
823
[email protected]400eaf82011-08-22 15:47:39824ui::WindowShowState Browser::GetSavedWindowShowState() const {
[email protected]76d8a4f2012-02-27 19:25:10825 // Only tabbed browsers use the command line or preference state, with the
826 // exception of devtools.
[email protected]f523da82012-03-30 11:54:34827 bool show_state = !is_type_tabbed() && !is_devtools();
[email protected]a636d8e52012-02-28 15:40:41828
829#if defined(USE_AURA)
830 // Apps save state on aura.
831 show_state &= !is_app();
832#endif
833
834 if (show_state)
[email protected]3c627ff2012-01-27 17:04:07835 return show_state_;
[email protected]dfca0c32012-01-18 22:32:25836
[email protected]bb975362009-01-21 01:00:22837 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]400eaf82011-08-22 15:47:39838 return ui::SHOW_STATE_MAXIMIZED;
[email protected]15952e462008-11-14 00:29:05839
[email protected]400eaf82011-08-22 15:47:39840 if (show_state_ != ui::SHOW_STATE_DEFAULT)
841 return show_state_;
[email protected]2e716622009-03-09 21:11:01842
[email protected]96f20102011-11-16 17:20:32843 const DictionaryValue* window_pref =
844 profile()->GetPrefs()->GetDictionary(GetWindowPlacementKey().c_str());
[email protected]2e716622009-03-09 21:11:01845 bool maximized = false;
[email protected]96f20102011-11-16 17:20:32846 window_pref->GetBoolean("maximized", &maximized);
847
[email protected]3c627ff2012-01-27 17:04:07848 return maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_DEFAULT;
[email protected]36b6dcb2008-11-12 01:19:57849}
850
851SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]3d61dd02012-06-07 00:05:53852 TabContents* contents = GetActiveTabContents();
[email protected]ce5348a82008-12-18 18:36:23853 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
854 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:04855 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57856}
857
[email protected]731f8a42009-07-20 22:07:32858string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3d61dd02012-06-07 00:05:53859 WebContents* contents = GetActiveWebContents();
[email protected]dda5dfa32009-07-10 00:33:29860 string16 title;
[email protected]c7c42332008-11-15 01:10:54861
[email protected]731f8a42009-07-20 22:07:32862 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
863 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57864 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29865 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57866 FormatTitleForDisplay(&title);
867 }
868 if (title.empty())
[email protected]51d83bdf2011-12-09 16:09:29869 title = CoreTabHelper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57870
[email protected]cae97652012-04-20 03:12:12871#if defined(OS_MACOSX) || defined(USE_ASH)
872 // On Mac or Ash, we don't want to suffix the page title with
[email protected]22a3daa2009-11-09 22:03:33873 // the application name.
[email protected]d904bc82009-07-07 00:41:04874 return title;
[email protected]7be64502011-05-03 17:51:47875#else
[email protected]edb5e6a2009-04-08 23:46:17876 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55877 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:14878 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:17879 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29880 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50881#endif
[email protected]36b6dcb2008-11-12 01:19:57882}
883
884// static
[email protected]dda5dfa32009-07-10 00:33:29885void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57886 size_t current_index = 0;
887 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:51888 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:15889 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:57890 current_index = match_index;
891 }
892}
893
894///////////////////////////////////////////////////////////////////////////////
895// Browser, OnBeforeUnload handling:
896
897bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:06898 if (!CanCloseWithInProgressDownloads())
899 return false;
900
901 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:04902 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:06903
[email protected]36b6dcb2008-11-12 01:19:57904 is_attempting_to_close_browser_ = true;
905
[email protected]460a2942010-12-15 19:43:15906 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:04907 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:57908
909 ProcessPendingTabs();
910 return false;
911}
912
913void Browser::OnWindowClosing() {
914 if (!ShouldCloseWindow())
915 return;
916
[email protected]911f8152010-03-18 16:46:40917 bool exiting = false;
918
[email protected]c984d9f2010-07-20 20:52:20919 // Application should shutdown on last window close if the user is explicitly
920 // trying to quit, or if there is nothing keeping the browser alive (such as
921 // AppController on the Mac, or BackgroundContentsService for background
922 // pages).
923 bool should_quit_if_last_browser =
[email protected]2e6389f2012-05-18 19:41:25924 browser_shutdown::IsTryingToQuit() || !browser::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:50925
926 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:57927 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:40928 exiting = true;
929 }
[email protected]36b6dcb2008-11-12 01:19:57930
[email protected]92371eb2011-04-28 11:50:15931 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:57932 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:15933 SessionService* session_service =
934 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:57935 if (session_service)
936 session_service->WindowClosing(session_id());
937
[email protected]92371eb2011-04-28 11:50:15938 TabRestoreService* tab_restore_service =
939 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]a636d8e52012-02-28 15:40:41940
941#if defined(USE_AURA)
942 if (tab_restore_service && is_app())
943 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
944#endif
945
[email protected]b35b26b32011-05-05 20:35:14946 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:00947 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39948
[email protected]911f8152010-03-18 16:46:40949 // TODO(sky): convert session/tab restore to use notification.
[email protected]ad50def52011-10-19 23:17:07950 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27951 chrome::NOTIFICATION_BROWSER_CLOSING,
[email protected]6c2381d2011-10-19 02:52:53952 content::Source<Browser>(this),
953 content::Details<bool>(&exiting));
[email protected]911f8152010-03-18 16:46:40954
[email protected]36b6dcb2008-11-12 01:19:57955 CloseAllTabs();
956}
957
[email protected]28788c7d2011-05-20 23:03:45958void Browser::OnWindowActivated() {
959 // On some platforms we want to automatically reload tabs that are
960 // killed when the user selects them.
[email protected]3d61dd02012-06-07 00:05:53961 WebContents* contents = GetActiveWebContents();
[email protected]be1f56ab2011-12-22 06:55:31962 if (contents && contents->GetCrashedStatus() ==
[email protected]28788c7d2011-05-20 23:03:45963 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
964 if (CommandLine::ForCurrentProcess()->HasSwitch(
965 switches::kReloadKilledTabs)) {
966 Reload(CURRENT_TAB);
967 }
968 }
969}
970
[email protected]69444cc2009-04-09 20:40:06971////////////////////////////////////////////////////////////////////////////////
972// In-progress download termination handling:
973
974void Browser::InProgressDownloadResponse(bool cancel_downloads) {
975 if (cancel_downloads) {
976 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
977 CloseWindow();
978 return;
979 }
980
981 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
982 // close again we'll show the warning again.
983 cancel_download_confirmation_state_ = NOT_PROMPTED;
984
985 // Show the download page so the user can figure-out what downloads are still
986 // in-progress.
987 ShowDownloadsTab();
988}
989
[email protected]5a17d492011-10-24 19:37:03990Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
991 int* num_downloads_blocking) const {
992 DCHECK(num_downloads_blocking);
993 *num_downloads_blocking = 0;
994
995 if (is_attempting_to_close_browser_)
996 return DOWNLOAD_CLOSE_OK;
997
998 // If we're not running a full browser process with a profile manager
999 // (testing), it's ok to close the browser.
1000 if (!g_browser_process->profile_manager())
1001 return DOWNLOAD_CLOSE_OK;
1002
1003 int total_download_count = DownloadService::DownloadCountAllProfiles();
1004 if (total_download_count == 0)
1005 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
1006
1007 // Figure out how many windows are open total, and associated with this
1008 // profile, that are relevant for the ok-to-close decision.
1009 int profile_window_count = 0;
1010 int total_window_count = 0;
1011 for (BrowserList::const_iterator iter = BrowserList::begin();
1012 iter != BrowserList::end(); ++iter) {
1013 // Don't count this browser window or any other in the process of closing.
1014 Browser* const browser = *iter;
1015 // Check is_attempting_to_close_browser_ as window closing may be
1016 // delayed, and windows that are in the process of closing don't
1017 // count against our totals.
1018 if (browser == this || browser->is_attempting_to_close_browser_)
1019 continue;
1020
1021 if ((*iter)->profile() == profile())
1022 profile_window_count++;
1023 total_window_count++;
1024 }
1025
1026 // If there aren't any other windows, we're at browser shutdown,
1027 // which would cancel all current downloads.
1028 if (total_window_count == 0) {
1029 *num_downloads_blocking = total_download_count;
1030 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
1031 }
1032
1033 // If there aren't any other windows on our profile, and we're an incognito
1034 // profile, and there are downloads associated with that profile,
1035 // those downloads would be cancelled by our window (-> profile) close.
1036 DownloadService* download_service =
1037 DownloadServiceFactory::GetForProfile(profile());
1038 if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
1039 profile()->IsOffTheRecord()) {
1040 *num_downloads_blocking = download_service->DownloadCount();
1041 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
1042 }
1043
1044 // Those are the only conditions under which we will block shutdown.
1045 return DOWNLOAD_CLOSE_OK;
1046}
1047
[email protected]69444cc2009-04-09 20:40:061048////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451049// Browser, TabStripModel pass-thrus:
1050
1051int Browser::tab_count() const {
[email protected]2fc15ae2012-05-06 00:01:371052 return tab_strip_model_->count();
[email protected]c848d3d92010-09-16 21:57:451053}
1054
[email protected]1ea49d52011-04-12 17:44:441055int Browser::active_index() const {
[email protected]2fc15ae2012-05-06 00:01:371056 return tab_strip_model_->active_index();
[email protected]c848d3d92010-09-16 21:57:451057}
1058
1059int Browser::GetIndexOfController(
[email protected]c5eed492012-01-04 17:07:501060 const NavigationController* controller) const {
[email protected]2fc15ae2012-05-06 00:01:371061 return tab_strip_model_->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451062}
1063
[email protected]3d61dd02012-06-07 00:05:531064// DEPRECATED
1065TabContents* Browser::GetSelectedTabContentsWrapper() const {
1066 return GetActiveTabContents();
1067}
1068
1069TabContents* Browser::GetActiveTabContents() const {
[email protected]2fc15ae2012-05-06 00:01:371070 return tab_strip_model_->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491071}
[email protected]b375c5d2011-05-03 21:15:041072
[email protected]3d61dd02012-06-07 00:05:531073// DEPRECATED
[email protected]4ca15302012-01-03 05:53:201074WebContents* Browser::GetSelectedWebContents() const {
[email protected]3d61dd02012-06-07 00:05:531075 return GetActiveWebContents();
[email protected]4ca15302012-01-03 05:53:201076}
1077
[email protected]3d61dd02012-06-07 00:05:531078WebContents* Browser::GetActiveWebContents() const {
1079 TabContents* tab_contents = GetActiveTabContents();
1080 return tab_contents ? tab_contents->web_contents() : NULL;
1081}
1082
1083// DEPRECATED
1084TabContents* Browser::GetTabContentsWrapperAt(int index) const {
1085 return GetTabContentsAt(index);
1086}
1087
1088TabContents* Browser::GetTabContentsAt(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371089 return tab_strip_model_->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451090}
1091
[email protected]6acde6352012-01-04 16:52:201092WebContents* Browser::GetWebContentsAt(int index) const {
[email protected]3d61dd02012-06-07 00:05:531093 TabContents* tab_contents = GetTabContentsAt(index);
1094 if (tab_contents)
1095 return tab_contents->web_contents();
[email protected]3c9e1872010-11-18 16:17:491096 return NULL;
[email protected]c848d3d92010-09-16 21:57:451097}
1098
[email protected]eaca0ad12011-04-18 15:53:411099void Browser::ActivateTabAt(int index, bool user_gesture) {
[email protected]2fc15ae2012-05-06 00:01:371100 tab_strip_model_->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451101}
1102
[email protected]fb7da4132011-03-15 15:51:001103bool Browser::IsTabPinned(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371104 return tab_strip_model_->IsTabPinned(index);
[email protected]fb7da4132011-03-15 15:51:001105}
1106
[email protected]002efb042011-10-07 17:30:241107bool Browser::IsTabDiscarded(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371108 return tab_strip_model_->IsTabDiscarded(index);
[email protected]002efb042011-10-07 17:30:241109}
1110
[email protected]c848d3d92010-09-16 21:57:451111void Browser::CloseAllTabs() {
[email protected]2fc15ae2012-05-06 00:01:371112 tab_strip_model_->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451113}
1114
1115////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571116// Browser, Tab adding/showing functions:
1117
[email protected]95bf8a5b2010-12-22 16:04:071118bool Browser::IsTabStripEditable() const {
1119 return window()->IsTabStripEditable();
1120}
1121
[email protected]b3344872010-05-03 15:52:291122int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]2fc15ae2012-05-06 00:01:371123 return (tab_strip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ?
1124 tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291125}
1126
[email protected]3d61dd02012-06-07 00:05:531127TabContents* Browser::AddSelectedTabWithURL(
[email protected]dad09ce42011-08-25 23:11:301128 const GURL& url,
[email protected]2905f742011-10-13 03:51:581129 content::PageTransition transition) {
[email protected]616381f02010-11-02 15:15:331130 browser::NavigateParams params(this, url, transition);
1131 params.disposition = NEW_FOREGROUND_TAB;
1132 browser::Navigate(&params);
1133 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571134}
1135
[email protected]3d61dd02012-06-07 00:05:531136WebContents* Browser::AddTab(TabContents* tab_contents,
[email protected]2905f742011-10-13 03:51:581137 content::PageTransition type) {
[email protected]2fc15ae2012-05-06 00:01:371138 tab_strip_model_->AddTabContents(tab_contents, -1, type,
1139 TabStripModel::ADD_ACTIVE);
[email protected]d9083482012-01-06 00:38:461140 return tab_contents->web_contents();
[email protected]36b6dcb2008-11-12 01:19:571141}
1142
[email protected]6acde6352012-01-04 16:52:201143WebContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571144 const std::vector<TabNavigation>& navigations,
1145 int tab_index,
1146 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081147 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091148 bool select,
[email protected]5e369672009-11-03 23:48:301149 bool pin,
[email protected]6ee12c42010-09-14 09:36:071150 bool from_last_session,
[email protected]adbfb8df2012-02-24 01:19:431151 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041152 GURL restore_url = navigations.at(selected_navigation).virtual_url();
[email protected]3d61dd02012-06-07 00:05:531153 TabContents* tab_contents = TabContentsFactory(
[email protected]1ab4ddf2011-07-21 04:48:041154 profile(),
[email protected]3123d2092012-04-27 19:35:481155 tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
[email protected]3c9e1872010-11-18 16:17:491156 MSG_ROUTING_NONE,
[email protected]3d61dd02012-06-07 00:05:531157 GetActiveWebContents(),
[email protected]ecc523f62010-09-28 22:45:401158 session_storage_namespace);
[email protected]3d61dd02012-06-07 00:05:531159 WebContents* new_tab = tab_contents->web_contents();
1160 tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]10f417c52011-12-28 21:04:231161 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141162 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1163 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561164 new_tab->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141165 selected_navigation, from_last_session, &entries);
1166 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571167
[email protected]eaca0ad12011-04-18 15:53:411168 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211169 TabStripModel::ADD_NONE;
1170 if (pin) {
[email protected]2fc15ae2012-05-06 00:01:371171 int first_mini_tab_idx = tab_strip_model_->IndexOfFirstNonMiniTab();
[email protected]41f022e2012-01-31 05:56:401172 tab_index = std::min(tab_index, first_mini_tab_idx);
[email protected]981b992e2011-03-28 21:05:211173 add_types |= TabStripModel::ADD_PINNED;
1174 }
[email protected]3d61dd02012-06-07 00:05:531175 tab_strip_model_->InsertTabContentsAt(tab_index, tab_contents, add_types);
[email protected]c93a9dd2010-04-22 20:25:181176 if (select) {
[email protected]77bc6732009-04-20 22:01:031177 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181178 } else {
1179 // We set the size of the view here, before WebKit does its initial
1180 // layout. If we don't, the initial layout of background tabs will be
1181 // performed with a view width of 0, which may cause script outputs and
1182 // anchor link location calculations to be incorrect even after a new
1183 // layout with proper view dimensions. TabStripModel::AddTabContents()
1184 // contains similar logic.
[email protected]d487beefe2011-12-21 05:41:211185 new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size());
[email protected]c93a9dd2010-04-22 20:25:181186 new_tab->HideContents();
1187 }
[email protected]92371eb2011-04-28 11:50:151188 SessionService* session_service =
1189 SessionServiceFactory::GetForProfileIfExisting(profile_);
1190 if (session_service)
[email protected]3d61dd02012-06-07 00:05:531191 session_service->TabRestored(tab_contents, pin);
[email protected]ce3fa3c2009-04-20 19:55:571192 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571193}
1194
[email protected]92655362012-04-20 21:33:171195void Browser::AddWebContents(WebContents* new_contents,
1196 WindowOpenDisposition disposition,
1197 const gfx::Rect& initial_pos,
1198 bool user_gesture) {
1199 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1200}
1201
1202void Browser::CloseTabContents(WebContents* contents) {
1203 CloseContents(contents);
1204}
1205
[email protected]5835871a2012-04-25 21:56:551206gfx::NativeWindow Browser::BrowserShowWebDialog(
1207 WebDialogDelegate* delegate,
[email protected]60fd60e2012-04-26 17:58:331208 gfx::NativeWindow parent_window) {
[email protected]92655362012-04-20 21:33:171209 if (!parent_window)
[email protected]90556dd2012-06-07 20:26:181210 parent_window = window_->GetNativeWindow();
[email protected]92655362012-04-20 21:33:171211
[email protected]00b5a5f2012-06-05 09:08:211212 return browser::ShowWebDialog(parent_window, profile_, this, delegate);
[email protected]92655362012-04-20 21:33:171213}
1214
1215void Browser::BrowserRenderWidgetShowing() {
1216 RenderWidgetShowing();
1217}
1218
1219void Browser::BookmarkBarSizeChanged(bool is_animating) {
1220 window_->ToolbarSizeChanged(is_animating);
1221}
1222
[email protected]36b6dcb2008-11-12 01:19:571223void Browser::ReplaceRestoredTab(
1224 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301225 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101226 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071227 const std::string& extension_app_id,
[email protected]adbfb8df2012-02-24 01:19:431228 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041229 GURL restore_url = navigations.at(selected_navigation).virtual_url();
[email protected]3d61dd02012-06-07 00:05:531230 TabContents* tab_contents = TabContentsFactory(
[email protected]1ab4ddf2011-07-21 04:48:041231 profile(),
[email protected]3123d2092012-04-27 19:35:481232 tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
[email protected]ecc523f62010-09-28 22:45:401233 MSG_ROUTING_NONE,
[email protected]3d61dd02012-06-07 00:05:531234 GetActiveWebContents(),
[email protected]6ee12c42010-09-14 09:36:071235 session_storage_namespace);
[email protected]3d61dd02012-06-07 00:05:531236 tab_contents->extension_tab_helper()->SetExtensionAppById(extension_app_id);
1237 WebContents* replacement = tab_contents->web_contents();
[email protected]10f417c52011-12-28 21:04:231238 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141239 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1240 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561241 replacement->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141242 selected_navigation, from_last_session, &entries);
1243 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571244
[email protected]3d61dd02012-06-07 00:05:531245 tab_strip_model_->ReplaceNavigationControllerAt(active_index(), tab_contents);
[email protected]36b6dcb2008-11-12 01:19:571246}
1247
[email protected]3698f172010-03-17 20:50:291248bool Browser::NavigateToIndexWithDisposition(int index,
1249 WindowOpenDisposition disp) {
[email protected]c5eed492012-01-04 17:07:501250 NavigationController& controller =
[email protected]f5fa20e2011-12-21 22:35:561251 GetOrCloneTabForDisposition(disp)->GetController();
[email protected]a26023822011-12-29 00:23:551252 if (index < 0 || index >= controller.GetEntryCount())
[email protected]3698f172010-03-17 20:50:291253 return false;
[email protected]cb84d642010-06-10 00:56:281254 controller.GoToIndex(index);
1255 return true;
[email protected]3698f172010-03-17 20:50:291256}
1257
[email protected]fee320542011-03-02 01:30:491258void Browser::ShowSingletonTab(const GURL& url) {
1259 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331260 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571261}
[email protected]d938aed92009-01-22 19:49:331262
[email protected]578c6962011-08-24 22:06:401263void Browser::ShowSingletonTabRespectRef(const GURL& url) {
1264 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1265 params.ref_behavior = browser::NavigateParams::RESPECT_REF;
1266 browser::Navigate(&params);
1267}
1268
[email protected]ddddfda2011-07-14 23:19:391269void Browser::ShowSingletonTabOverwritingNTP(
1270 const browser::NavigateParams& params) {
1271 browser::NavigateParams local_params(params);
[email protected]3d61dd02012-06-07 00:05:531272 WebContents* contents = GetActiveWebContents();
[email protected]842a648c2011-07-20 23:23:161273 if (contents) {
1274 const GURL& contents_url = contents->GetURL();
1275 if ((contents_url == GURL(chrome::kChromeUINewTabURL) ||
1276 contents_url == GURL(chrome::kAboutBlankURL)) &&
1277 browser::GetIndexOfSingletonTab(&local_params) < 0) {
1278 local_params.disposition = CURRENT_TAB;
1279 }
[email protected]ddddfda2011-07-14 23:19:391280 }
1281
1282 browser::Navigate(&local_params);
1283}
1284
[email protected]92655362012-04-20 21:33:171285browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1286 const GURL& url) {
1287 browser::NavigateParams params(
1288 this, url, content::PAGE_TRANSITION_AUTO_BOOKMARK);
1289 params.disposition = SINGLETON_TAB;
1290 params.window_action = browser::NavigateParams::SHOW_WINDOW;
1291 params.user_gesture = true;
1292 return params;
1293}
1294
[email protected]227393e2011-06-29 21:28:391295void Browser::WindowFullscreenStateChanged() {
[email protected]01a5a762011-11-21 05:40:551296 fullscreen_controller_->WindowFullscreenStateChanged();
[email protected]9adb8b12011-12-09 06:49:131297 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1298 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
[email protected]ae2622c2009-07-30 23:47:581299}
1300
[email protected]36b6dcb2008-11-12 01:19:571301///////////////////////////////////////////////////////////////////////////////
1302// Browser, Assorted browser commands:
1303
[email protected]43c9dc722011-08-20 02:05:091304bool Browser::CanGoBack() const {
[email protected]3d61dd02012-06-07 00:05:531305 return GetActiveWebContents()->GetController().CanGoBack();
[email protected]43c9dc722011-08-20 02:05:091306}
1307
[email protected]485fba42009-03-24 23:27:291308void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381309 content::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271310
[email protected]3d61dd02012-06-07 00:05:531311 TabContents* current_tab = GetActiveTabContents();
[email protected]43c9dc722011-08-20 02:05:091312 if (CanGoBack()) {
[email protected]d9083482012-01-06 00:38:461313 WebContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061314 // If we are on an interstitial page and clone the tab, it won't be copied
1315 // to the new tab, so we don't need to go back.
[email protected]d9083482012-01-06 00:38:461316 if (current_tab->web_contents()->ShowingInterstitialPage() &&
1317 (new_tab != current_tab->web_contents()))
[email protected]d497b0782010-03-29 19:19:061318 return;
[email protected]f5fa20e2011-12-21 22:35:561319 new_tab->GetController().GoBack();
[email protected]485fba42009-03-24 23:27:291320 }
[email protected]36b6dcb2008-11-12 01:19:571321}
1322
[email protected]43c9dc722011-08-20 02:05:091323bool Browser::CanGoForward() const {
[email protected]3d61dd02012-06-07 00:05:531324 return GetActiveWebContents()->GetController().CanGoForward();
[email protected]43c9dc722011-08-20 02:05:091325}
1326
[email protected]3698f172010-03-17 20:50:291327void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381328 content::RecordAction(UserMetricsAction("Forward"));
[email protected]43c9dc722011-08-20 02:05:091329 if (CanGoForward())
[email protected]f5fa20e2011-12-21 22:35:561330 GetOrCloneTabForDisposition(disposition)->GetController().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571331}
1332
[email protected]cb84d642010-06-10 00:56:281333void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381334 content::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281335 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161336}
[email protected]fbd77592008-11-12 20:50:271337
[email protected]cb84d642010-06-10 00:56:281338void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381339 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281340 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161341}
1342
[email protected]485fba42009-03-24 23:27:291343void Browser::Home(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381344 content::RecordAction(UserMetricsAction("Home"));
[email protected]e5d549d2011-12-28 01:29:201345 OpenURL(OpenURLParams(
1346 profile_->GetHomePage(), Referrer(), disposition,
[email protected]2905f742011-10-13 03:51:581347 content::PageTransitionFromInt(
1348 content::PAGE_TRANSITION_AUTO_BOOKMARK |
[email protected]e5d549d2011-12-28 01:29:201349 content::PAGE_TRANSITION_HOME_PAGE),
1350 false));
[email protected]36b6dcb2008-11-12 01:19:571351}
1352
[email protected]fbd77592008-11-12 20:50:271353void Browser::OpenCurrentURL() {
[email protected]7f6f44c2011-12-14 13:23:381354 content::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351355 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491356 if (!location_bar)
1357 return;
1358
[email protected]9d0306ea2009-09-02 19:38:391359 WindowOpenDisposition open_disposition =
1360 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271361 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301362 return;
[email protected]03bb953d2010-09-14 21:38:301363
[email protected]537de682011-08-08 18:10:141364 GURL url(location_bar->GetInputString());
[email protected]07d490bc2011-03-07 17:05:261365
1366 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1367 Browser* existing_browser = NULL;
[email protected]4ca15302012-01-03 05:53:201368 WebContents* existing_tab = TabFinder::GetInstance()->FindTab(
[email protected]07d490bc2011-03-07 17:05:261369 this, url, &existing_browser);
1370 if (existing_tab) {
1371 existing_browser->ActivateContents(existing_tab);
1372 return;
1373 }
1374 }
1375
[email protected]616381f02010-11-02 15:15:331376 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1377 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251378 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1379 // inherit the opener. In some cases the tabstrip will determine the group
1380 // should be inherited, in which case the group is inherited instead of the
1381 // opener.
[email protected]616381f02010-11-02 15:15:331382 params.tabstrip_add_types =
1383 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1384 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331385
[email protected]6e37fe32011-03-02 09:06:521386 DCHECK(profile_->GetExtensionService());
1387 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]a9acdff2012-03-08 04:04:521388 AppLauncherHandler::RecordAppLaunchType(
1389 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION);
[email protected]46fd1ea42011-02-16 15:59:331390 }
[email protected]fbd77592008-11-12 20:50:271391}
1392
[email protected]84214982008-12-10 18:49:101393void Browser::Stop() {
[email protected]7f6f44c2011-12-14 13:23:381394 content::RecordAction(UserMetricsAction("Stop"));
[email protected]3d61dd02012-06-07 00:05:531395 GetActiveWebContents()->Stop();
[email protected]84214982008-12-10 18:49:101396}
1397
[email protected]8daec682012-05-31 18:13:201398#if !defined(OS_WIN)
[email protected]84214982008-12-10 18:49:101399void Browser::NewWindow() {
[email protected]eddcf7502012-02-09 22:43:481400 NewEmptyWindow(profile_->GetOriginalProfile());
[email protected]84214982008-12-10 18:49:101401}
1402
1403void Browser::NewIncognitoWindow() {
[email protected]eddcf7502012-02-09 22:43:481404 NewEmptyWindow(profile_->GetOffTheRecordProfile());
[email protected]84214982008-12-10 18:49:101405}
[email protected]8daec682012-05-31 18:13:201406#endif // OS_WIN
[email protected]84214982008-12-10 18:49:101407
[email protected]84214982008-12-10 18:49:101408void Browser::CloseWindow() {
[email protected]7f6f44c2011-12-14 13:23:381409 content::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101410 window_->Close();
1411}
1412
[email protected]fbd77592008-11-12 20:50:271413void Browser::NewTab() {
[email protected]7f6f44c2011-12-14 13:23:381414 content::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261415
[email protected]b35b26b32011-05-05 20:35:141416 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271417 AddBlankTab(true);
[email protected]3d61dd02012-06-07 00:05:531418 GetActiveWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271419 } else {
[email protected]d8748142012-05-16 21:13:431420 Browser* b = browser::FindOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271421 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051422 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111423 // The call to AddBlankTab above did not set the focus to the tab as its
1424 // window was not active, so we have to do it explicitly.
1425 // See http://crbug.com/6380.
[email protected]3d61dd02012-06-07 00:05:531426 b->GetActiveWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271427 }
1428}
1429
1430void Browser::CloseTab() {
[email protected]7f6f44c2011-12-14 13:23:381431 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211432 if (CanCloseTab())
[email protected]2fc15ae2012-05-06 00:01:371433 tab_strip_model_->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271434}
1435
[email protected]fbd77592008-11-12 20:50:271436void Browser::SelectNextTab() {
[email protected]7f6f44c2011-12-14 13:23:381437 content::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]2fc15ae2012-05-06 00:01:371438 tab_strip_model_->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271439}
1440
1441void Browser::SelectPreviousTab() {
[email protected]7f6f44c2011-12-14 13:23:381442 content::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]2fc15ae2012-05-06 00:01:371443 tab_strip_model_->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271444}
1445
[email protected]91ac9202010-07-30 18:32:351446void Browser::OpenTabpose() {
1447#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031448 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1449 switches::kEnableExposeForTabs)) {
1450 return;
1451 }
1452
[email protected]7f6f44c2011-12-14 13:23:381453 content::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351454 window()->OpenTabpose();
1455#else
1456 NOTREACHED();
1457#endif
1458}
1459
[email protected]9ac7fcb2009-09-14 18:22:521460void Browser::MoveTabNext() {
[email protected]7f6f44c2011-12-14 13:23:381461 content::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]2fc15ae2012-05-06 00:01:371462 tab_strip_model_->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521463}
1464
1465void Browser::MoveTabPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381466 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]2fc15ae2012-05-06 00:01:371467 tab_strip_model_->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521468}
1469
[email protected]fbd77592008-11-12 20:50:271470void Browser::SelectNumberedTab(int index) {
1471 if (index < tab_count()) {
[email protected]7f6f44c2011-12-14 13:23:381472 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]41f022e2012-01-31 05:56:401473 ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271474 }
1475}
1476
1477void Browser::SelectLastTab() {
[email protected]7f6f44c2011-12-14 13:23:381478 content::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]2fc15ae2012-05-06 00:01:371479 tab_strip_model_->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271480}
1481
1482void Browser::DuplicateTab() {
[email protected]7f6f44c2011-12-14 13:23:381483 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441484 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271485}
1486
[email protected]0c4c3882009-10-01 21:42:141487void Browser::WriteCurrentURLToClipboard() {
1488 // TODO(ericu): There isn't currently a metric for this. Should there be?
1489 // We don't appear to track the action when it comes from the
1490 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141491
[email protected]3d61dd02012-06-07 00:05:531492 WebContents* contents = GetActiveWebContents();
[email protected]ef557022012-03-16 10:05:331493 if (!toolbar_model_->ShouldDisplayURL())
[email protected]0c4c3882009-10-01 21:42:141494 return;
1495
[email protected]06305962012-05-09 22:34:361496 chrome_common_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141497 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171498 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141499 g_browser_process->clipboard());
1500}
1501
[email protected]fbd77592008-11-12 20:50:271502void Browser::ConvertPopupToTabbedBrowser() {
[email protected]7f6f44c2011-12-14 13:23:381503 content::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]3d61dd02012-06-07 00:05:531504 TabContents* contents = tab_strip_model_->DetachTabContentsAt(active_index());
[email protected]15952e462008-11-14 00:29:051505 Browser* browser = Browser::Create(profile_);
[email protected]c0849252012-05-12 13:51:271506 browser->tab_strip_model()->AppendTabContents(contents, true);
[email protected]15952e462008-11-14 00:29:051507 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271508}
1509
[email protected]184717d52012-02-22 04:46:161510void Browser::ToggleFullscreenMode() {
1511 fullscreen_controller_->ToggleFullscreenMode();
1512}
1513
[email protected]41d9faf2012-02-28 23:46:021514void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
1515 fullscreen_controller_->ToggleFullscreenModeWithExtension(extension_url);
[email protected]9282cea2009-02-18 18:49:001516}
1517
[email protected]d3766932011-08-04 22:18:231518#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:161519void Browser::TogglePresentationMode() {
1520 fullscreen_controller_->TogglePresentationMode();
[email protected]d3766932011-08-04 22:18:231521}
1522#endif
1523
[email protected]92655362012-04-20 21:33:171524void Browser::Exit() {
1525 content::RecordAction(UserMetricsAction("Exit"));
[email protected]2e6389f2012-05-18 19:41:251526 browser::AttemptUserExit();
[email protected]92655362012-04-20 21:33:171527}
1528
[email protected]36b6dcb2008-11-12 01:19:571529void Browser::BookmarkCurrentPage() {
[email protected]7f6f44c2011-12-14 13:23:381530 content::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271531
[email protected]76624fde2009-10-09 18:13:231532 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571533 if (!model || !model->IsLoaded())
1534 return; // Ignore requests until bookmarks are loaded.
1535
[email protected]76624fde2009-10-09 18:13:231536 GURL url;
[email protected]261cd762010-08-20 05:45:371537 string16 title;
[email protected]3d61dd02012-06-07 00:05:531538 TabContents* tab = GetActiveTabContents();
[email protected]d9083482012-01-06 00:38:461539 bookmark_utils::GetURLAndTitleToBookmark(tab->web_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441540 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211541 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321542 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211543 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041544 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211545 }
[email protected]4394f2b2011-09-03 03:07:561546 bookmark_utils::AddIfNotBookmarked(model, url, title);
[email protected]11dbbd22009-11-06 18:55:041547 // Make sure the model actually added a bookmark before showing the star. A
1548 // bookmark isn't created if the url is invalid.
1549 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271550 // Only show the bubble if the window is active, otherwise we may get into
[email protected]b106ca52012-03-13 06:08:461551 // weird situations where the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441552 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271553 }
[email protected]36b6dcb2008-11-12 01:19:571554}
1555
[email protected]6ec11922012-06-07 03:55:121556#if !defined(OS_WIN)
1557void Browser::PinCurrentPageToStartScreen() {
1558}
1559#endif
1560
[email protected]40bdb6d92009-02-25 00:22:271561void Browser::SavePage() {
[email protected]7f6f44c2011-12-14 13:23:381562 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]3d61dd02012-06-07 00:05:531563 WebContents* current_tab = GetActiveWebContents();
[email protected]0bfbf882011-12-22 18:19:271564 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
[email protected]7f6f44c2011-12-14 13:23:381565 content::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]3d61dd02012-06-07 00:05:531566 GetActiveWebContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271567}
1568
[email protected]77d8d622010-12-15 10:30:121569void Browser::ViewSelectedSource() {
[email protected]3d61dd02012-06-07 00:05:531570 ViewSource(GetActiveTabContents());
[email protected]36b6dcb2008-11-12 01:19:571571}
initial.commit09911bf2008-07-26 23:55:291572
[email protected]4801ecc2009-04-05 04:52:581573void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171574 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581575}
1576
[email protected]92655362012-04-20 21:33:171577void Browser::ShowPageInfo(content::WebContents* web_contents,
1578 const GURL& url,
1579 const SSLStatus& ssl,
1580 bool show_history) {
1581 Profile* profile = Profile::FromBrowserContext(
1582 web_contents->GetBrowserContext());
[email protected]3d61dd02012-06-07 00:05:531583 TabContents* tab_contents =
1584 TabContents::GetOwningTabContentsForWebContents(web_contents);
[email protected]92655362012-04-20 21:33:171585
1586 if (CommandLine::ForCurrentProcess()->HasSwitch(
1587 switches::kEnableWebsiteSettings)) {
[email protected]3d61dd02012-06-07 00:05:531588 window()->ShowWebsiteSettings(
1589 profile, tab_contents, url, ssl, show_history);
[email protected]92655362012-04-20 21:33:171590 } else {
1591 window()->ShowPageInfo(profile, url, ssl, show_history);
1592 }
1593}
1594
1595void Browser::ShowChromeToMobileBubble() {
1596 // Only show the bubble if the window is active, otherwise we may get into
1597 // weird situations where the bubble is deleted as soon as it is shown.
1598 if (window_->IsActive())
1599 window_->ShowChromeToMobileBubble();
1600}
1601
[email protected]a3e18c42009-03-04 23:36:051602bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221603 return SupportsWindowFeatureImpl(feature, true);
1604}
[email protected]f5bf8ccf2010-02-05 18:19:251605
[email protected]018cf362010-05-05 22:43:221606bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1607 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051608}
1609
[email protected]fbd77592008-11-12 20:50:271610void Browser::Print() {
[email protected]47c7ec82012-01-18 03:29:211611 if (g_browser_process->local_state()->GetBoolean(
1612 prefs::kPrintPreviewDisabled)) {
[email protected]3d61dd02012-06-07 00:05:531613 GetActiveTabContents()->print_view_manager()->PrintNow();
[email protected]47c7ec82012-01-18 03:29:211614 } else {
[email protected]3d61dd02012-06-07 00:05:531615 GetActiveTabContents()->print_view_manager()->PrintPreviewNow();
[email protected]47c7ec82012-01-18 03:29:211616 }
[email protected]fbd77592008-11-12 20:50:271617}
1618
[email protected]0996e9b2011-08-26 17:59:011619void Browser::AdvancedPrint() {
[email protected]3d61dd02012-06-07 00:05:531620 GetActiveTabContents()->print_view_manager()->AdvancedPrintNow();
[email protected]0996e9b2011-08-26 17:59:011621}
1622
[email protected]92655362012-04-20 21:33:171623void Browser::EmailPageLocation() {
1624 content::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]3d61dd02012-06-07 00:05:531625 WebContents* wc = GetActiveWebContents();
[email protected]92655362012-04-20 21:33:171626 DCHECK(wc);
1627
1628 std::string title = net::EscapeQueryParamValue(
1629 UTF16ToUTF8(wc->GetTitle()), false);
1630 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
1631 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1632 title + "&body=%0A%0A" + page_url;
1633 platform_util::OpenExternal(GURL(mailto));
1634}
1635
[email protected]fbd77592008-11-12 20:50:271636void Browser::ToggleEncodingAutoDetect() {
[email protected]7f6f44c2011-12-14 13:23:381637 content::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271638 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181639 // If "auto detect" is turned on, then any current override encoding
1640 // is cleared. This also implicitly performs a reload.
1641 // OTOH, if "auto detect" is turned off, we don't change the currently
1642 // active encoding.
1643 if (encoding_auto_detect_.GetValue()) {
[email protected]3d61dd02012-06-07 00:05:531644 WebContents* contents = GetActiveWebContents();
[email protected]a697f4c2009-09-14 22:30:181645 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081646 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181647 }
[email protected]fbd77592008-11-12 20:50:271648}
1649
1650void Browser::OverrideEncoding(int encoding_id) {
[email protected]7f6f44c2011-12-14 13:23:381651 content::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401652 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271653 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]3d61dd02012-06-07 00:05:531654 WebContents* contents = GetActiveWebContents();
[email protected]57c6a652009-05-04 07:58:341655 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081656 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271657 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401658 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191659 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1660 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401661 encoding_id,
1662 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271663 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191664 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271665 }
[email protected]36b6dcb2008-11-12 01:19:571666}
1667
[email protected]84214982008-12-10 18:49:101668void Browser::Cut() {
[email protected]7f6f44c2011-12-14 13:23:381669 content::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231670 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571671}
1672
[email protected]84214982008-12-10 18:49:101673void Browser::Copy() {
[email protected]7f6f44c2011-12-14 13:23:381674 content::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231675 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571676}
1677
[email protected]84214982008-12-10 18:49:101678void Browser::Paste() {
[email protected]7f6f44c2011-12-14 13:23:381679 content::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231680 window()->Paste();
[email protected]84214982008-12-10 18:49:101681}
1682
1683void Browser::Find() {
[email protected]7f6f44c2011-12-14 13:23:381684 content::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291685 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101686}
1687
1688void Browser::FindNext() {
[email protected]7f6f44c2011-12-14 13:23:381689 content::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291690 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101691}
1692
1693void Browser::FindPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381694 content::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291695 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101696}
1697
[email protected]54087fe2011-10-28 22:02:481698void Browser::Zoom(content::PageZoom zoom) {
[email protected]0bffaa322011-07-18 17:37:541699 if (is_devtools())
1700 return;
1701
[email protected]3d61dd02012-06-07 00:05:531702 content::RenderViewHost* host = GetActiveWebContents()->GetRenderViewHost();
[email protected]0f083402011-11-22 02:59:011703 if (zoom == content::PAGE_ZOOM_RESET) {
1704 host->SetZoomLevel(0);
[email protected]7f6f44c2011-12-14 13:23:381705 content::RecordAction(UserMetricsAction("ZoomNormal"));
[email protected]0f083402011-11-22 02:59:011706 return;
1707 }
[email protected]896220042010-03-23 18:14:281708
[email protected]3d61dd02012-06-07 00:05:531709 double current_zoom_level = GetActiveWebContents()->GetZoomLevel();
[email protected]0f083402011-11-22 02:59:011710 double default_zoom_level =
1711 profile_->GetPrefs()->GetDouble(prefs::kDefaultZoomLevel);
1712
1713 // Generate a vector of zoom levels from an array of known presets along with
1714 // the default level added if necessary.
1715 std::vector<double> zoom_levels =
1716 chrome_page_zoom::PresetZoomLevels(default_zoom_level);
1717
1718 if (zoom == content::PAGE_ZOOM_OUT) {
1719 // Iterate through the zoom levels in reverse order to find the next
1720 // lower level based on the current zoom level for this page.
1721 for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin();
1722 i != zoom_levels.rend(); ++i) {
1723 double zoom_level = *i;
1724 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
1725 continue;
1726 if (zoom_level < current_zoom_level) {
1727 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:381728 content::RecordAction(UserMetricsAction("ZoomMinus"));
[email protected]0f083402011-11-22 02:59:011729 return;
1730 }
[email protected]7f6f44c2011-12-14 13:23:381731 content::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum"));
[email protected]0f083402011-11-22 02:59:011732 }
1733 } else {
1734 // Iterate through the zoom levels in normal order to find the next
1735 // higher level based on the current zoom level for this page.
1736 for (std::vector<double>::const_iterator i = zoom_levels.begin();
1737 i != zoom_levels.end(); ++i) {
1738 double zoom_level = *i;
1739 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
1740 continue;
1741 if (zoom_level > current_zoom_level) {
1742 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:381743 content::RecordAction(UserMetricsAction("ZoomPlus"));
[email protected]0f083402011-11-22 02:59:011744 return;
1745 }
1746 }
[email protected]7f6f44c2011-12-14 13:23:381747 content::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum"));
[email protected]0f083402011-11-22 02:59:011748 }
[email protected]84214982008-12-10 18:49:101749}
1750
1751void Browser::FocusToolbar() {
[email protected]7f6f44c2011-12-14 13:23:381752 content::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:101753 window_->FocusToolbar();
1754}
1755
1756void Browser::FocusLocationBar() {
[email protected]7f6f44c2011-12-14 13:23:381757 content::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:581758 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:101759}
1760
[email protected]92655362012-04-20 21:33:171761void Browser::FocusSearch() {
1762 // TODO(beng): replace this with FocusLocationBar
1763 content::RecordAction(UserMetricsAction("FocusSearch"));
1764 window_->GetLocationBar()->FocusSearch();
1765}
1766
1767void Browser::FocusAppMenu() {
1768 content::RecordAction(UserMetricsAction("FocusAppMenu"));
1769 window_->FocusAppMenu();
1770}
1771
[email protected]83548a42010-06-18 13:53:371772void Browser::FocusBookmarksToolbar() {
[email protected]7f6f44c2011-12-14 13:23:381773 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:371774 window_->FocusBookmarksToolbar();
1775}
1776
[email protected]83548a42010-06-18 13:53:371777void Browser::FocusNextPane() {
[email protected]7f6f44c2011-12-14 13:23:381778 content::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:371779 window_->RotatePaneFocus(true);
1780}
1781
1782void Browser::FocusPreviousPane() {
[email protected]7f6f44c2011-12-14 13:23:381783 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:371784 window_->RotatePaneFocus(false);
1785}
1786
[email protected]84214982008-12-10 18:49:101787void Browser::OpenFile() {
[email protected]7f6f44c2011-12-14 13:23:381788 content::RecordAction(UserMetricsAction("OpenFile"));
[email protected]84214982008-12-10 18:49:101789 if (!select_file_dialog_.get())
1790 select_file_dialog_ = SelectFileDialog::Create(this);
1791
[email protected]35896a32010-06-09 08:42:511792 const FilePath directory = profile_->last_selected_directory();
1793
[email protected]84214982008-12-10 18:49:101794 // TODO(beng): figure out how to juggle this.
[email protected]90556dd2012-06-07 20:26:181795 gfx::NativeWindow parent_window = window_->GetNativeWindow();
[email protected]84214982008-12-10 18:49:101796 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:511797 string16(), directory,
[email protected]b949f1112009-04-12 20:03:081798 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]3d61dd02012-06-07 00:05:531799 GetActiveWebContents(),
[email protected]d56bcd22009-03-16 19:51:561800 parent_window, NULL);
[email protected]84214982008-12-10 18:49:101801}
1802
1803void Browser::OpenCreateShortcutsDialog() {
[email protected]7f6f44c2011-12-14 13:23:381804 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:471805#if !defined(OS_MACOSX)
[email protected]3d61dd02012-06-07 00:05:531806 TabContents* current_tab = GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491807 DCHECK(current_tab &&
[email protected]d9083482012-01-06 00:38:461808 web_app::IsValidUrl(current_tab->web_contents()->GetURL())) <<
[email protected]3c9e1872010-11-18 16:17:491809 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:511810
[email protected]10f417c52011-12-28 21:04:231811 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:461812 current_tab->web_contents()->GetController().GetLastCommittedEntry();
[email protected]ed5431872009-11-17 08:39:511813 if (!entry)
1814 return;
1815
[email protected]eabfdae92009-12-11 06:13:511816 // RVH's GetApplicationInfo should not be called before it returns.
1817 DCHECK(pending_web_app_action_ == NONE);
1818 pending_web_app_action_ = CREATE_SHORTCUT;
1819
[email protected]a2cf65eb2010-01-18 08:20:381820 // Start fetching web app info for CreateApplicationShortcut dialog and show
1821 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]36fc0392011-12-25 03:59:511822 current_tab->extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]98f6e022009-06-05 22:49:531823#else
1824 NOTIMPLEMENTED();
1825#endif
[email protected]36b6dcb2008-11-12 01:19:571826}
1827
[email protected]2a8a98122010-07-16 11:58:481828void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
[email protected]e3791ce92011-08-09 01:03:321829 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
[email protected]7f6f44c2011-12-14 13:23:381830 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
[email protected]e3791ce92011-08-09 01:03:321831 else
[email protected]7f6f44c2011-12-14 13:23:381832 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]e3791ce92011-08-09 01:03:321833
[email protected]aebdd072011-07-07 12:36:591834 DevToolsWindow::ToggleDevToolsWindow(
[email protected]3d61dd02012-06-07 00:05:531835 GetActiveWebContents()->GetRenderViewHost(),
[email protected]4a63e242011-12-12 15:23:081836 action);
[email protected]fbd77592008-11-12 20:50:271837}
1838
[email protected]adb6a84d2011-02-07 16:58:401839void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]7f6f44c2011-12-14 13:23:381840 content::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:401841 if (highlight_background_resources)
1842 window_->ShowBackgroundPages();
1843 else
1844 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:101845}
1846
[email protected]daa9e382012-01-06 00:30:341847void Browser::OpenFeedbackDialog() {
1848 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]5835871a2012-04-25 21:56:551849 browser::ShowWebFeedbackView(this, std::string(), std::string());
[email protected]84214982008-12-10 18:49:101850}
[email protected]44b2c8852009-03-18 00:57:491851
[email protected]84214982008-12-10 18:49:101852void Browser::ToggleBookmarkBar() {
[email protected]7f6f44c2011-12-14 13:23:381853 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:101854 window_->ToggleBookmarkBar();
1855}
1856
[email protected]84214982008-12-10 18:49:101857void Browser::OpenBookmarkManager() {
[email protected]7f6f44c2011-12-14 13:23:381858 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
1859 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]0af8f132011-07-16 01:37:021860 ShowSingletonTabOverwritingNTP(
[email protected]a179fac72011-08-29 22:22:421861 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIBookmarksURL)));
[email protected]0af8f132011-07-16 01:37:021862}
1863
[email protected]4c9ee222011-08-17 19:51:351864void Browser::OpenBookmarkManagerForNode(int64 node_id) {
1865 OpenBookmarkManagerWithHash("", node_id);
1866}
1867
1868void Browser::OpenBookmarkManagerEditNode(int64 node_id) {
1869 OpenBookmarkManagerWithHash("e=", node_id);
1870}
1871
[email protected]fdb98512009-08-26 01:37:101872void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:121873 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:101874 window_->ShowAppMenu();
1875}
1876
[email protected]7d2d08152011-10-25 22:58:471877void Browser::ShowAvatarMenu() {
1878 window_->ShowAvatarBubbleFromAvatarButton();
1879}
1880
[email protected]8bf80e922009-03-09 20:56:361881void Browser::ShowHistoryTab() {
[email protected]7f6f44c2011-12-14 13:23:381882 content::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]56e613862012-03-29 19:51:521883 browser::NavigateParams params(
1884 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIHistoryURL)));
[email protected]a048ad22012-03-23 04:26:561885 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1886 ShowSingletonTabOverwritingNTP(params);
[email protected]8bf80e922009-03-09 20:56:361887}
[email protected]84214982008-12-10 18:49:101888
1889void Browser::ShowDownloadsTab() {
[email protected]7f6f44c2011-12-14 13:23:381890 content::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]3d037ce72011-04-04 17:43:451891 if (window()) {
1892 DownloadShelf* shelf = window()->GetDownloadShelf();
1893 if (shelf->IsShowing())
1894 shelf->Close();
1895 }
[email protected]ddddfda2011-07-14 23:19:391896 ShowSingletonTabOverwritingNTP(
1897 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIDownloadsURL)));
[email protected]84214982008-12-10 18:49:101898}
1899
[email protected]34085a32009-11-06 22:49:481900void Browser::ShowExtensionsTab() {
[email protected]7f6f44c2011-12-14 13:23:381901 content::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]55a66012012-03-31 00:56:021902 browser::NavigateParams params(
1903 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIExtensionsURL)));
[email protected]a048ad22012-03-23 04:26:561904 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1905 ShowSingletonTabOverwritingNTP(params);
[email protected]34085a32009-11-06 22:49:481906}
1907
[email protected]c1bbaa82010-11-08 11:17:051908void Browser::ShowAboutConflictsTab() {
[email protected]7f6f44c2011-12-14 13:23:381909 content::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:491910 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:051911}
1912
[email protected]d9083482012-01-06 00:38:461913void Browser::ShowBrokenPageTab(WebContents* contents) {
[email protected]daa9e382012-01-06 00:30:341914 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]10e457c2010-04-29 03:35:231915 string16 page_title = contents->GetTitle();
[email protected]10f417c52011-12-28 21:04:231916 NavigationEntry* entry = contents->GetController().GetActiveEntry();
[email protected]10e457c2010-04-29 03:35:231917 if (!entry)
1918 return;
[email protected]36fc0392011-12-25 03:59:511919 std::string page_url = entry->GetURL().spec();
[email protected]10e457c2010-04-29 03:35:231920 std::vector<std::string> subst;
1921 subst.push_back(UTF16ToASCII(page_title));
1922 subst.push_back(page_url);
1923 std::string report_page_url =
1924 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:491925 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:231926}
1927
[email protected]12e816bde2010-09-14 19:59:291928void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]55a66012012-03-31 00:56:021929 std::string url = std::string(chrome::kChromeUISettingsURL) + sub_page;
[email protected]f563e9132012-03-07 02:04:301930#if defined(OS_CHROMEOS)
[email protected]55a66012012-03-31 00:56:021931 if (sub_page.find(chrome::kInternetOptionsSubPage, 0) != std::string::npos) {
[email protected]a048ad22012-03-23 04:26:561932 std::string::size_type loc = sub_page.find("?", 0);
1933 std::string network_page = loc != std::string::npos ?
1934 sub_page.substr(loc) : std::string();
[email protected]55a66012012-03-31 00:56:021935 url = std::string(chrome::kChromeUISettingsURL) + network_page;
[email protected]f5ec7242012-01-27 07:15:151936 }
[email protected]55a66012012-03-31 00:56:021937#endif
[email protected]a048ad22012-03-23 04:26:561938 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
1939 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1940 ShowSingletonTabOverwritingNTP(params);
[email protected]4a42d272010-06-18 01:29:421941}
1942
[email protected]92655362012-04-20 21:33:171943void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
1944 ShowOptionsTab(
1945 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
1946 options2::ContentSettingsHandler::ContentSettingsTypeToGroupName(
1947 content_type));
1948}
1949
[email protected]84214982008-12-10 18:49:101950void Browser::OpenClearBrowsingDataDialog() {
[email protected]7f6f44c2011-12-14 13:23:381951 content::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:051952 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:101953}
1954
[email protected]84214982008-12-10 18:49:101955void Browser::OpenOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:381956 content::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]089562d2012-03-26 20:41:511957 ShowOptionsTab(std::string());
[email protected]fbd77592008-11-12 20:50:271958}
1959
1960void Browser::OpenPasswordManager() {
[email protected]7f6f44c2011-12-14 13:23:381961 content::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:041962 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:271963}
1964
[email protected]1bdf29e2009-05-11 23:45:251965void Browser::OpenImportSettingsDialog() {
[email protected]7f6f44c2011-12-14 13:23:381966 content::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:051967 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:251968}
[email protected]1bdf29e2009-05-11 23:45:251969
[email protected]b99081b2011-03-10 17:43:471970void Browser::OpenInstantConfirmDialog() {
1971 ShowOptionsTab(chrome::kInstantConfirmPage);
1972}
1973
[email protected]fbd77592008-11-12 20:50:271974void Browser::OpenAboutChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:381975 content::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]a9fbb0962012-03-21 23:25:131976#if !defined(OS_WIN)
[email protected]55a66012012-03-31 00:56:021977 browser::NavigateParams params(
1978 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIUberURL)));
[email protected]a8928f82012-03-27 05:48:121979 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1980 ShowSingletonTabOverwritingNTP(params);
[email protected]4ea87862012-02-21 19:45:101981#else
[email protected]a048ad22012-03-23 04:26:561982 // crbug.com/115123.
1983 window_->ShowAboutChromeDialog();
[email protected]4ea87862012-02-21 19:45:101984#endif
[email protected]fbd77592008-11-12 20:50:271985}
1986
[email protected]b1b73942010-05-26 20:11:541987void Browser::OpenUpdateChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:381988 content::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:541989 window_->ShowUpdateChromeDialog();
1990}
1991
[email protected]202802e42011-07-06 11:40:461992void Browser::ShowHelpTab() {
[email protected]7f6f44c2011-12-14 13:23:381993 content::RecordAction(UserMetricsAction("ShowHelpTab"));
[email protected]adc8e852012-01-29 08:58:221994 ShowSingletonTab(GURL(chrome::kChromeHelpURL));
[email protected]fbd77592008-11-12 20:50:271995}
1996
[email protected]31cc1c022010-10-15 20:03:471997void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:201998 OpenURL(OpenURLParams(
1999 GURL(kPrivacyDashboardUrl), Referrer(),
2000 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false));
[email protected]31cc1c022010-10-15 20:03:472001 window_->Activate();
2002}
2003
[email protected]024617a2010-08-20 05:08:052004void Browser::OpenSearchEngineOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382005 content::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052006 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052007}
2008
[email protected]a003d8e2010-10-02 21:03:352009void Browser::OpenPluginsTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202010 OpenURL(OpenURLParams(
2011 GURL(chrome::kChromeUIPluginsURL), Referrer(), NEW_FOREGROUND_TAB,
2012 content::PAGE_TRANSITION_LINK, false));
[email protected]a003d8e2010-10-02 21:03:352013 window_->Activate();
2014}
2015
[email protected]92655362012-04-20 21:33:172016void Browser::ShowSyncSetup(SyncPromoUI::Source source) {
2017 ProfileSyncService* service =
2018 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
2019 profile()->GetOriginalProfile());
2020 LoginUIService* login_service =
2021 LoginUIServiceFactory::GetForProfile(profile()->GetOriginalProfile());
2022 if (service->HasSyncSetupCompleted()) {
2023 ShowOptionsTab(std::string());
2024 } else if (SyncPromoUI::ShouldShowSyncPromo(profile()) &&
2025 login_service->current_login_ui() == NULL) {
2026 // There is no currently active login UI, so display a new promo page.
2027 GURL url(SyncPromoUI::GetSyncPromoURL(GURL(), source));
2028 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
2029 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2030 ShowSingletonTabOverwritingNTP(params);
2031 } else {
2032 LoginUIServiceFactory::GetForProfile(
[email protected]bdb27902012-05-01 23:33:392033 profile()->GetOriginalProfile())->ShowLoginUI();
[email protected]92655362012-04-20 21:33:172034 }
2035}
2036
2037void Browser::ToggleSpeechInput() {
[email protected]3d61dd02012-06-07 00:05:532038 GetActiveWebContents()->GetRenderViewHost()->ToggleSpeechInput();
[email protected]92655362012-04-20 21:33:172039}
2040
2041void Browser::UpdateDownloadShelfVisibility(bool visible) {
2042 if (GetStatusBubble())
2043 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
2044}
2045
[email protected]36b6dcb2008-11-12 01:19:572046///////////////////////////////////////////////////////////////////////////////
2047
2048// static
[email protected]79117172009-08-28 16:11:442049void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542050 const PrefService::Preference* home_page_pref =
2051 prefs->FindPreference(prefs::kHomePage);
2052 if (home_page_pref &&
2053 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192054 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]1d8e794e42012-04-06 02:41:452055 prefs->SetString(prefs::kHomePage, std::string());
[email protected]ddd231e2010-06-29 20:35:192056 }
[email protected]8fe6e1c2010-05-27 08:21:542057 const PrefService::Preference* home_page_is_new_tab_page_pref =
2058 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2059 if (home_page_is_new_tab_page_pref &&
2060 !home_page_is_new_tab_page_pref->IsManaged() &&
2061 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332062 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442063}
2064
2065// static
[email protected]36b6dcb2008-11-12 01:19:572066void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572067 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]d9898912011-04-15 21:10:002068 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]4e72ebb2011-10-18 05:02:182069 prefs->RegisterBooleanPref(prefs::kShouldShowFirstRunBubble, false);
[email protected]47c7ec82012-01-18 03:29:212070 prefs->RegisterBooleanPref(prefs::kPrintPreviewDisabled,
2071#if defined(GOOGLE_CHROME_BUILD)
2072 false
2073#else
2074 true
2075#endif
2076 );
[email protected]36b6dcb2008-11-12 01:19:572077}
2078
2079// static
2080void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182081 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]1d8e794e42012-04-06 02:41:452082 std::string(),
[email protected]d36f941b2011-05-09 06:19:162083 PrefService::SYNCABLE_PREF);
[email protected]6c6b02d2011-09-02 03:36:472084 prefs->RegisterBooleanPref(prefs::kHomePageChanged,
2085 false,
2086 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162087 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2088 true,
2089 PrefService::SYNCABLE_PREF);
2090 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2091 false,
2092 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092093#if defined(OS_MACOSX)
2094 // This really belongs in platform code, but there's no good place to
2095 // initialize it between the time when the AppController is created
2096 // (where there's no profile) and the time the controller gets another
[email protected]fe7c4872012-05-10 20:06:032097 // crack at the start of the main event loop. By that time,
2098 // StartupBrowserCreator has already created the browser window, and it's too
2099 // late: we need the pref to be already initialized. Doing it here also saves
2100 // us from having to hard-code pref registration in the several unit tests
2101 // that use this preference.
[email protected]d36f941b2011-05-09 06:19:162102 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2103 true,
2104 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092105#endif
[email protected]d36f941b2011-05-09 06:19:162106 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2107 true,
2108 PrefService::SYNCABLE_PREF);
2109 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2110 true,
2111 PrefService::SYNCABLE_PREF);
2112 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2113 true,
2114 PrefService::SYNCABLE_PREF);
2115 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2116 true,
2117 PrefService::SYNCABLE_PREF);
2118 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2119 false,
2120 PrefService::SYNCABLE_PREF);
2121 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2122 false,
2123 PrefService::SYNCABLE_PREF);
2124 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2125 0,
2126 PrefService::SYNCABLE_PREF);
2127 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2128 true,
2129 PrefService::UNSYNCABLE_PREF);
2130 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2131 true,
2132 PrefService::UNSYNCABLE_PREF);
2133 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2134 true,
2135 PrefService::UNSYNCABLE_PREF);
2136 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2137 true,
2138 PrefService::UNSYNCABLE_PREF);
2139 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2140 true,
2141 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162142 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2143 true,
2144 PrefService::SYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162145 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2146 std::string(),
2147 PrefService::UNSYNCABLE_PREF);
2148 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2149 true,
2150 PrefService::UNSYNCABLE_PREF);
[email protected]1af419c2011-10-31 23:45:412151 prefs->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled,
2152 true,
2153 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162154 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2155 false,
2156 PrefService::UNSYNCABLE_PREF);
[email protected]945ec5c2012-03-06 18:00:212157 prefs->RegisterIntegerPref(prefs::kDevToolsHSplitLocation,
2158 -1,
2159 PrefService::UNSYNCABLE_PREF);
2160 prefs->RegisterIntegerPref(prefs::kDevToolsVSplitLocation,
[email protected]d36f941b2011-05-09 06:19:162161 -1,
2162 PrefService::UNSYNCABLE_PREF);
2163 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2164 PrefService::UNSYNCABLE_PREF);
2165 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2166 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122167 prefs->RegisterBooleanPref(prefs::kImportBookmarks,
2168 true,
2169 PrefService::UNSYNCABLE_PREF);
2170 prefs->RegisterBooleanPref(prefs::kImportHistory,
2171 true,
2172 PrefService::UNSYNCABLE_PREF);
2173 prefs->RegisterBooleanPref(prefs::kImportHomepage,
2174 true,
2175 PrefService::UNSYNCABLE_PREF);
2176 prefs->RegisterBooleanPref(prefs::kImportSearchEngine,
2177 true,
2178 PrefService::UNSYNCABLE_PREF);
2179 prefs->RegisterBooleanPref(prefs::kImportSavedPasswords,
2180 true,
2181 PrefService::UNSYNCABLE_PREF);
[email protected]f6e680912011-09-21 20:26:192182 // The map of timestamps of the last used file browser handlers.
2183 prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers,
2184 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122185
[email protected]2bf2bd92011-03-31 07:12:442186 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162187 // them even though they're only typically controlled via policy.
2188 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2189 false,
2190 PrefService::UNSYNCABLE_PREF);
2191 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2192 false,
2193 PrefService::UNSYNCABLE_PREF);
2194 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2195 false,
2196 PrefService::UNSYNCABLE_PREF);
2197 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2198 true,
2199 PrefService::UNSYNCABLE_PREF);
2200 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2201 true,
2202 PrefService::UNSYNCABLE_PREF);
[email protected]781be952011-08-31 20:22:142203 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled,
2204 true,
2205 PrefService::UNSYNCABLE_PREF);
[email protected]80b07612011-12-12 16:04:302206 prefs->RegisterBooleanPref(prefs::kEnableMemoryInfo,
2207 false,
2208 PrefService::UNSYNCABLE_PREF);
[email protected]f2df3112011-11-18 10:21:482209
2210 // Initialize the disk cache prefs.
2211 prefs->RegisterFilePathPref(prefs::kDiskCacheDir,
2212 FilePath(),
2213 PrefService::UNSYNCABLE_PREF);
2214 prefs->RegisterIntegerPref(prefs::kDiskCacheSize,
2215 0,
2216 PrefService::UNSYNCABLE_PREF);
2217 prefs->RegisterIntegerPref(prefs::kMediaCacheSize,
2218 0,
2219 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572220}
2221
2222// static
[email protected]d9083482012-01-06 00:38:462223bool Browser::RunUnloadEventsHelper(WebContents* contents) {
[email protected]075969d2012-04-17 20:05:552224 // If the WebContents is not connected yet, then there's no unload
2225 // handler we can fire even if the WebContents has an unload listener.
[email protected]ecc523f62010-09-28 22:45:402226 // One case where we hit this is in a tab that has an infinite loop
2227 // before load.
[email protected]5aab5e22010-12-08 22:13:292228 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402229 // If the page has unload listeners, then we tell the renderer to fire
2230 // them. Once they have fired, we'll get a message back saying whether
2231 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292232 // with the NeedToFireBeforeUnload bit cleared.
[email protected]151a63d2011-12-20 22:32:522233 contents->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]ecc523f62010-09-28 22:45:402234 return true;
2235 }
2236 return false;
2237}
2238
2239// static
[email protected]2a6bc3e2011-12-28 23:51:332240void Browser::JSOutOfMemoryHelper(WebContents* tab) {
[email protected]3d61dd02012-06-07 00:05:532241 TabContents* tab_contents = TabContents::GetOwningTabContentsForWebContents(
[email protected]7d189022011-08-25 22:54:202242 tab);
[email protected]3d61dd02012-06-07 00:05:532243 if (!tab_contents)
[email protected]2a6bc3e2011-12-28 23:51:332244 return;
2245
[email protected]3d61dd02012-06-07 00:05:532246 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
[email protected]2a6bc3e2011-12-28 23:51:332247 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
2248 infobar_helper,
2249 NULL,
2250 l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT),
2251 true));
[email protected]7d189022011-08-25 22:54:202252}
2253
2254// static
[email protected]2a6bc3e2011-12-28 23:51:332255void Browser::RegisterProtocolHandlerHelper(WebContents* tab,
[email protected]7d189022011-08-25 22:54:202256 const std::string& protocol,
2257 const GURL& url,
[email protected]3a3b75a2012-06-01 08:38:362258 const string16& title,
2259 bool user_gesture) {
[email protected]3d61dd02012-06-07 00:05:532260 TabContents* tab_contents = TabContents::GetOwningTabContentsForWebContents(
[email protected]7d189022011-08-25 22:54:202261 tab);
[email protected]3d61dd02012-06-07 00:05:532262 if (!tab_contents || tab_contents->profile()->IsOffTheRecord())
[email protected]7d189022011-08-25 22:54:202263 return;
2264
[email protected]7d189022011-08-25 22:54:202265 ProtocolHandler handler =
2266 ProtocolHandler::CreateProtocolHandler(protocol, url, title);
2267
2268 ProtocolHandlerRegistry* registry =
[email protected]3d61dd02012-06-07 00:05:532269 tab_contents->profile()->GetProtocolHandlerRegistry();
[email protected]7d189022011-08-25 22:54:202270
[email protected]a50af292011-10-25 03:07:402271 if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) {
[email protected]7f6f44c2011-12-14 13:23:382272 content::RecordAction(
[email protected]7d189022011-08-25 22:54:202273 UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown"));
[email protected]3d61dd02012-06-07 00:05:532274 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
[email protected]d3ddb6d2012-01-06 02:51:172275
2276 RegisterProtocolHandlerInfoBarDelegate* rph_delegate =
[email protected]95a33ed62011-09-30 15:07:082277 new RegisterProtocolHandlerInfoBarDelegate(infobar_helper,
2278 registry,
[email protected]d3ddb6d2012-01-06 02:51:172279 handler);
2280
2281 for (size_t i = 0; i < infobar_helper->infobar_count(); i++) {
2282 InfoBarDelegate* delegate = infobar_helper->GetInfoBarDelegateAt(i);
2283 RegisterProtocolHandlerInfoBarDelegate* cast_delegate =
2284 delegate->AsRegisterProtocolHandlerInfoBarDelegate();
2285 if (cast_delegate != NULL && cast_delegate->IsReplacedBy(rph_delegate)) {
2286 infobar_helper->ReplaceInfoBar(cast_delegate, rph_delegate);
2287 rph_delegate = NULL;
2288 break;
2289 }
2290 }
2291
2292 if (rph_delegate != NULL)
2293 infobar_helper->AddInfoBar(rph_delegate);
[email protected]7d189022011-08-25 22:54:202294 }
2295}
2296
2297// static
[email protected]2a6bc3e2011-12-28 23:51:332298void Browser::FindReplyHelper(WebContents* tab,
[email protected]b888919c2011-09-02 00:32:162299 int request_id,
2300 int number_of_matches,
2301 const gfx::Rect& selection_rect,
2302 int active_match_ordinal,
2303 bool final_update) {
[email protected]3d61dd02012-06-07 00:05:532304 TabContents* tab_contents = TabContents::GetOwningTabContentsForWebContents(
[email protected]b888919c2011-09-02 00:32:162305 tab);
[email protected]3d61dd02012-06-07 00:05:532306 if (!tab_contents || !tab_contents->find_tab_helper())
[email protected]b888919c2011-09-02 00:32:162307 return;
2308
[email protected]3d61dd02012-06-07 00:05:532309 tab_contents->find_tab_helper()->HandleFindReply(request_id,
2310 number_of_matches,
2311 selection_rect,
2312 active_match_ordinal,
2313 final_update);
[email protected]b888919c2011-09-02 00:32:162314}
2315
[email protected]ef557022012-03-16 10:05:332316void Browser::ExecuteCommand(int id) {
2317 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2318}
2319
2320void Browser::ExecuteCommand(int id, int event_flags) {
2321 ExecuteCommandWithDisposition(
2322 id, browser::DispositionFromEventFlags(event_flags));
2323}
2324
2325bool Browser::ExecuteCommandIfEnabled(int id) {
2326 if (command_updater_.SupportsCommand(id) &&
2327 command_updater_.IsCommandEnabled(id)) {
2328 ExecuteCommand(id);
2329 return true;
2330 }
2331 return false;
2332}
2333
2334bool Browser::IsReservedCommandOrKey(int command_id,
2335 const NativeWebKeyboardEvent& event) {
[email protected]e7293fa2012-05-17 04:42:332336 // In Apps mode, no keys are reserved.
2337 if (is_app())
2338 return false;
2339
[email protected]ef557022012-03-16 10:05:332340#if defined(OS_CHROMEOS)
2341 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
[email protected]e7293fa2012-05-17 04:42:332342 // aren't able to block Chrome from performing the standard actions for F1-F4.
2343 // We should not handle F5-10 here since they are processed by Ash. See also:
2344 // crbug.com/127333#c8
[email protected]ef557022012-03-16 10:05:332345 ui::KeyboardCode key_code =
2346 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]f7a5ebc82012-05-30 07:39:022347 if ((key_code == ui::VKEY_F1 ||
2348 key_code == ui::VKEY_F2 ||
2349 key_code == ui::VKEY_F3 ||
2350 key_code == ui::VKEY_F4) &&
2351 // Make sure it's a browser shortcut (i.e. not an Ash one like Alt+F4).
2352 command_id != -1) {
[email protected]ef557022012-03-16 10:05:332353 return true;
2354 }
2355#endif
2356
2357 if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN)
2358 return true;
2359 return command_id == IDC_CLOSE_TAB ||
2360 command_id == IDC_CLOSE_WINDOW ||
2361 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2362 command_id == IDC_NEW_TAB ||
2363 command_id == IDC_NEW_WINDOW ||
2364 command_id == IDC_RESTORE_TAB ||
2365 command_id == IDC_SELECT_NEXT_TAB ||
2366 command_id == IDC_SELECT_PREVIOUS_TAB ||
2367 command_id == IDC_TABPOSE ||
2368 command_id == IDC_EXIT ||
2369 command_id == IDC_SEARCH;
2370}
2371
2372void Browser::SetBlockCommandExecution(bool block) {
2373 block_command_execution_ = block;
2374 if (block) {
2375 last_blocked_command_id_ = -1;
2376 last_blocked_command_disposition_ = CURRENT_TAB;
2377 }
2378}
2379
2380int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2381 if (disposition)
2382 *disposition = last_blocked_command_disposition_;
2383 return last_blocked_command_id_;
2384}
2385
[email protected]3d61dd02012-06-07 00:05:532386void Browser::UpdateUIForNavigationInTab(TabContents* contents,
[email protected]ef557022012-03-16 10:05:332387 content::PageTransition transition,
2388 bool user_initiated) {
[email protected]2fc15ae2012-05-06 00:01:372389 tab_strip_model_->TabNavigating(contents, transition);
[email protected]ef557022012-03-16 10:05:332390
[email protected]3d61dd02012-06-07 00:05:532391 bool contents_is_selected = contents == GetActiveTabContents();
[email protected]ef557022012-03-16 10:05:332392 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2393 // Forcibly reset the location bar if the url is going to change in the
2394 // current tab, since otherwise it won't discard any ongoing user edits,
2395 // since it doesn't realize this is a user-initiated action.
2396 window()->GetLocationBar()->Revert();
2397 }
2398
2399 if (GetStatusBubble())
2400 GetStatusBubble()->Hide();
2401
2402 // Update the location bar. This is synchronous. We specifically don't
2403 // update the load state since the load hasn't started yet and updating it
2404 // will put it out of sync with the actual state like whether we're
2405 // displaying a favicon, which controls the throbber. If we updated it here,
2406 // the throbber will show the default favicon for a split second when
2407 // navigating away from the new tab page.
2408 ScheduleUIUpdate(contents->web_contents(), content::INVALIDATE_TYPE_URL);
2409
[email protected]e1f288d2012-05-23 19:36:102410 if (contents_is_selected)
[email protected]ef557022012-03-16 10:05:332411 contents->web_contents()->Focus();
2412}
2413
[email protected]3d61dd02012-06-07 00:05:532414void Browser::ShowCollectedCookiesDialog(TabContents* tab_contents) {
[email protected]90556dd2012-06-07 20:26:182415 browser::ShowCollectedCookiesDialog(window()->GetNativeWindow(),
[email protected]3d61dd02012-06-07 00:05:532416 tab_contents);
[email protected]92655362012-04-20 21:33:172417}
2418
[email protected]ef557022012-03-16 10:05:332419///////////////////////////////////////////////////////////////////////////////
2420// Browser, PageNavigator implementation:
2421
2422WebContents* Browser::OpenURL(const OpenURLParams& params) {
2423 return OpenURLFromTab(NULL, params);
2424}
2425
2426///////////////////////////////////////////////////////////////////////////////
2427// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2428
[email protected]485fba42009-03-24 23:27:292429void Browser::ExecuteCommandWithDisposition(
2430 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142431 // No commands are enabled if there is not yet any selected tab.
2432 // TODO(pkasting): It seems like we should not need this, because either
2433 // most/all commands should not have been enabled yet anyway or the ones that
2434 // are enabled should be global, or safe themselves against having no selected
2435 // tab. However, Ben says he tried removing this before and got lots of
2436 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2437 // window construction. This probably could use closer examination someday.
[email protected]3d61dd02012-06-07 00:05:532438 if (!GetActiveTabContents())
[email protected]1fc025202009-01-20 23:03:142439 return;
2440
[email protected]59c9f002010-11-19 00:38:052441 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2442 << id;
[email protected]36b6dcb2008-11-12 01:19:572443
[email protected]867125a02009-12-10 06:01:482444 // If command execution is blocked then just record the command and return.
2445 if (block_command_execution_) {
2446 // We actually only allow no more than one blocked command, otherwise some
2447 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062448 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482449 last_blocked_command_id_ = id;
2450 last_blocked_command_disposition_ = disposition;
2451 return;
2452 }
2453
[email protected]fbd77592008-11-12 20:50:272454 // The order of commands in this switch statement must match the function
2455 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572456 switch (id) {
[email protected]84214982008-12-10 18:49:102457 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282458 case IDC_BACK: GoBack(disposition); break;
2459 case IDC_FORWARD: GoForward(disposition); break;
2460 case IDC_RELOAD: Reload(disposition); break;
2461 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2462 case IDC_HOME: Home(disposition); break;
2463 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282464 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572465
[email protected]84214982008-12-10 18:49:102466 // Window management commands
[email protected]cb84d642010-06-10 00:56:282467 case IDC_NEW_WINDOW: NewWindow(); break;
2468 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282469 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2470 case IDC_NEW_TAB: NewTab(); break;
2471 case IDC_CLOSE_TAB: CloseTab(); break;
2472 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2473 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352474 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282475 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2476 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572477 case IDC_SELECT_TAB_0:
2478 case IDC_SELECT_TAB_1:
2479 case IDC_SELECT_TAB_2:
2480 case IDC_SELECT_TAB_3:
2481 case IDC_SELECT_TAB_4:
2482 case IDC_SELECT_TAB_5:
2483 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542484 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282485 break;
2486 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2487 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2488 case IDC_RESTORE_TAB: RestoreTab(); break;
2489 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2490 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
[email protected]184717d52012-02-22 04:46:162491 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
[email protected]d3766932011-08-04 22:18:232492#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:162493 case IDC_PRESENTATION_MODE: TogglePresentationMode(); break;
[email protected]d3766932011-08-04 22:18:232494#endif
[email protected]cb84d642010-06-10 00:56:282495 case IDC_EXIT: Exit(); break;
[email protected]36b6dcb2008-11-12 01:19:572496
[email protected]84214982008-12-10 18:49:102497 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282498 case IDC_SAVE_PAGE: SavePage(); break;
2499 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
[email protected]6ec11922012-06-07 03:55:122500 case IDC_PIN_TO_START_SCREEN: PinCurrentPageToStartScreen(); break;
[email protected]cb84d642010-06-10 00:56:282501 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122502 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282503 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2504 case IDC_PRINT: Print(); break;
[email protected]0996e9b2011-08-26 17:59:012505 case IDC_ADVANCED_PRINT: AdvancedPrint(); break;
[email protected]b106ca52012-03-13 06:08:462506 case IDC_CHROME_TO_MOBILE_PAGE: ShowChromeToMobileBubble(); break;
[email protected]cb84d642010-06-10 00:56:282507 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572508 case IDC_ENCODING_UTF8:
2509 case IDC_ENCODING_UTF16LE:
2510 case IDC_ENCODING_ISO88591:
2511 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492512 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572513 case IDC_ENCODING_GB18030:
2514 case IDC_ENCODING_BIG5HKSCS:
2515 case IDC_ENCODING_BIG5:
2516 case IDC_ENCODING_KOREAN:
2517 case IDC_ENCODING_SHIFTJIS:
2518 case IDC_ENCODING_ISO2022JP:
2519 case IDC_ENCODING_EUCJP:
2520 case IDC_ENCODING_THAI:
2521 case IDC_ENCODING_ISO885915:
2522 case IDC_ENCODING_MACINTOSH:
2523 case IDC_ENCODING_ISO88592:
2524 case IDC_ENCODING_WINDOWS1250:
2525 case IDC_ENCODING_ISO88595:
2526 case IDC_ENCODING_WINDOWS1251:
2527 case IDC_ENCODING_KOI8R:
2528 case IDC_ENCODING_KOI8U:
2529 case IDC_ENCODING_ISO88597:
2530 case IDC_ENCODING_WINDOWS1253:
2531 case IDC_ENCODING_ISO88594:
2532 case IDC_ENCODING_ISO885913:
2533 case IDC_ENCODING_WINDOWS1257:
2534 case IDC_ENCODING_ISO88593:
2535 case IDC_ENCODING_ISO885910:
2536 case IDC_ENCODING_ISO885914:
2537 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572538 case IDC_ENCODING_WINDOWS1254:
2539 case IDC_ENCODING_ISO88596:
2540 case IDC_ENCODING_WINDOWS1256:
2541 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002542 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572543 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282544 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572545
[email protected]84214982008-12-10 18:49:102546 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282547 case IDC_CUT: Cut(); break;
2548 case IDC_COPY: Copy(); break;
2549 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102550
2551 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282552 case IDC_FIND: Find(); break;
2553 case IDC_FIND_NEXT: FindNext(); break;
2554 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102555
2556 // Zoom
[email protected]54087fe2011-10-28 22:02:482557 case IDC_ZOOM_PLUS: Zoom(content::PAGE_ZOOM_IN); break;
2558 case IDC_ZOOM_NORMAL: Zoom(content::PAGE_ZOOM_RESET); break;
2559 case IDC_ZOOM_MINUS: Zoom(content::PAGE_ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102560
2561 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282562 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2563 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2564 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522565 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372566 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
[email protected]83548a42010-06-18 13:53:372567 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2568 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102569
2570 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282571 case IDC_OPEN_FILE: OpenFile(); break;
2572 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482573 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2574 DEVTOOLS_TOGGLE_ACTION_NONE);
2575 break;
2576 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2577 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2578 break;
2579 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2580 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2581 break;
[email protected]adb6a84d2011-02-07 16:58:402582 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2583 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]daa9e382012-01-06 00:30:342584 case IDC_FEEDBACK: OpenFeedbackDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492585
[email protected]cb84d642010-06-10 00:56:282586 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252587 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492588
[email protected]cb84d642010-06-10 00:56:282589 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2590 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]7d2d08152011-10-25 22:58:472591 case IDC_SHOW_AVATAR_MENU: ShowAvatarMenu(); break;
[email protected]cb84d642010-06-10 00:56:282592 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2593 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2594 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
[email protected]cb84d642010-06-10 00:56:282595 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052596 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282597 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2598 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2599 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412600 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2601 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052602 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]202802e42011-07-06 11:40:462603 case IDC_HELP_PAGE: ShowHelpTab(); break;
[email protected]713d01b2012-03-24 05:58:202604 case IDC_SHOW_SYNC_SETUP: ShowSyncSetup(SyncPromoUI::SOURCE_MENU);
2605 break;
[email protected]afcb43562011-09-02 23:33:382606 case IDC_TOGGLE_SPEECH_INPUT: ToggleSpeechInput(); break;
[email protected]d938aed92009-01-22 19:49:332607
[email protected]36b6dcb2008-11-12 01:19:572608 default:
[email protected]84214982008-12-10 18:49:102609 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272610 break;
[email protected]36b6dcb2008-11-12 01:19:572611 }
2612}
2613
[email protected]92655362012-04-20 21:33:172614////////////////////////////////////////////////////////////////////////////////
2615// Browser, TabRestoreServiceObserver:
2616
2617void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
2618 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
2619 !service->entries().empty());
2620}
2621
2622void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
2623 if (!tab_restore_service_)
2624 return;
2625
2626 DCHECK_EQ(tab_restore_service_, service);
2627 tab_restore_service_->RemoveObserver(this);
2628 tab_restore_service_ = NULL;
2629}
2630
[email protected]3d61dd02012-06-07 00:05:532631// Centralized method for creating a TabContents, configuring and
[email protected]92655362012-04-20 21:33:172632// installing all its supporting objects and observers.
[email protected]3d61dd02012-06-07 00:05:532633TabContents* Browser::TabContentsFactory(
[email protected]92655362012-04-20 21:33:172634 Profile* profile,
2635 SiteInstance* site_instance,
2636 int routing_id,
2637 const WebContents* base_web_contents,
2638 content::SessionStorageNamespace* session_storage_namespace) {
2639 WebContents* new_contents = WebContents::Create(
2640 profile, site_instance, routing_id, base_web_contents,
2641 session_storage_namespace);
[email protected]3d61dd02012-06-07 00:05:532642 TabContents* tab_contents = new TabContents(new_contents);
2643 return tab_contents;
[email protected]92655362012-04-20 21:33:172644}
2645
[email protected]485fba42009-03-24 23:27:292646///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572647// Browser, TabStripModelDelegate implementation:
2648
[email protected]3d61dd02012-06-07 00:05:532649TabContents* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582650 return AddBlankTabAt(-1, foreground);
2651}
2652
[email protected]3d61dd02012-06-07 00:05:532653TabContents* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052654 // Time new tab page creation time. We keep track of the timing data in
[email protected]075969d2012-04-17 20:05:552655 // WebContents, but we want to include the time it takes to create the
2656 // WebContents object too.
[email protected]3f8eb7f2009-10-02 23:58:052657 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332658 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
[email protected]2905f742011-10-13 03:51:582659 content::PAGE_TRANSITION_TYPED);
[email protected]616381f02010-11-02 15:15:332660 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2661 params.tabstrip_index = index;
2662 browser::Navigate(&params);
[email protected]d9083482012-01-06 00:38:462663 params.target_contents->web_contents()->SetNewTabStartTime(
[email protected]3c9e1872010-11-18 16:17:492664 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332665 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052666}
2667
[email protected]3c9e1872010-11-18 16:17:492668Browser* Browser::CreateNewStripWithContents(
[email protected]3d61dd02012-06-07 00:05:532669 TabContents* detached_contents,
[email protected]3c9e1872010-11-18 16:17:492670 const gfx::Rect& window_bounds,
2671 const DockInfo& dock_info,
2672 bool maximize) {
[email protected]018cf362010-05-05 22:43:222673 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:062674
[email protected]5e495462008-11-20 23:07:412675 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:412676 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2677 dock_info.AdjustOtherWindowBounds();
2678
[email protected]36b6dcb2008-11-12 01:19:572679 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:142680 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:412681 browser->set_override_bounds(new_window_bounds);
[email protected]400eaf82011-08-22 15:47:392682 browser->set_show_state(
2683 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
[email protected]9800de5e2011-03-11 18:19:492684 browser->InitBrowserWindow();
[email protected]c0849252012-05-12 13:51:272685 browser->tab_strip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:272686 // Make sure the loading state is updated correctly, otherwise the throbber
2687 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:332688 browser->LoadingStateChanged(detached_contents->web_contents());
[email protected]3d1104f2009-03-26 15:30:282689 return browser;
[email protected]36b6dcb2008-11-12 01:19:572690}
2691
2692int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:402693 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
2694 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:572695}
2696
[email protected]3d61dd02012-06-07 00:05:532697TabContents* Browser::CreateTabContentsForURL(
[email protected]3ebe558b2011-12-06 08:05:082698 const GURL& url, const content::Referrer& referrer, Profile* profile,
[email protected]2905f742011-10-13 03:51:582699 content::PageTransition transition, bool defer_load,
[email protected]36b6dcb2008-11-12 01:19:572700 SiteInstance* instance) const {
[email protected]3d61dd02012-06-07 00:05:532701 TabContents* contents = TabContentsFactory(profile, instance,
2702 MSG_ROUTING_NONE, GetActiveWebContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:572703 if (!defer_load) {
2704 // Load the initial URL before adding the new tab contents to the tab strip
2705 // so that the tab contents has navigation state.
[email protected]d9083482012-01-06 00:38:462706 contents->web_contents()->GetController().LoadURL(
[email protected]4a63e242011-12-12 15:23:082707 url, referrer, transition, std::string());
[email protected]36b6dcb2008-11-12 01:19:572708 }
2709
2710 return contents;
2711}
2712
2713bool Browser::CanDuplicateContentsAt(int index) {
[email protected]c5eed492012-01-04 17:07:502714 NavigationController& nc = GetWebContentsAt(index)->GetController();
[email protected]fbc5e5f92012-01-02 06:08:322715 return nc.GetWebContents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:572716}
2717
2718void Browser::DuplicateContentsAt(int index) {
[email protected]3d61dd02012-06-07 00:05:532719 TabContents* contents = GetTabContentsAt(index);
[email protected]94ce7252010-12-20 21:46:332720 CHECK(contents);
[email protected]3d61dd02012-06-07 00:05:532721 TabContents* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:562722
2723 bool pinned = false;
2724 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2725 // If this is a tabbed browser, just create a duplicate tab inside the same
2726 // window next to the tab being duplicated.
[email protected]2fc15ae2012-05-06 00:01:372727 int index = tab_strip_model_->GetIndexOfTabContents(contents);
[email protected]41f022e2012-01-31 05:56:402728 pinned = IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:412729 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:562730 TabStripModel::ADD_INHERIT_GROUP |
2731 (pinned ? TabStripModel::ADD_PINNED : 0);
[email protected]2fc15ae2012-05-06 00:01:372732 tab_strip_model_->InsertTabContentsAt(index + 1, contents_dupe, add_types);
[email protected]47b309f2010-12-28 17:35:562733 } else {
2734 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:142735 if (is_app()) {
2736 CHECK(!is_type_popup());
2737 CHECK(!is_type_panel());
[email protected]da22aa62012-04-04 18:54:352738 browser = Browser::CreateWithParams(
2739 Browser::CreateParams::CreateForApp(
2740 TYPE_POPUP, app_name_, gfx::Rect(),profile_));
[email protected]b35b26b32011-05-05 20:35:142741 } else if (is_type_popup()) {
[email protected]da22aa62012-04-04 18:54:352742 browser = Browser::CreateWithParams(
2743 Browser::CreateParams(TYPE_POPUP, profile_));
[email protected]47b309f2010-12-28 17:35:562744 }
2745
2746 // Preserve the size of the original window. The new window has already
2747 // been given an offset by the OS, so we shouldn't copy the old bounds.
2748 BrowserWindow* new_window = browser->window();
2749 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
2750 window()->GetRestoredBounds().size()));
2751
[email protected]4e595682011-02-09 17:07:022752 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]075969d2012-04-17 20:05:552753 // WebContents is invisible and won't size it.
[email protected]47b309f2010-12-28 17:35:562754 browser->window()->Show();
2755
2756 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:582757 browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK);
[email protected]47b309f2010-12-28 17:35:562758 }
2759
[email protected]92371eb2011-04-28 11:50:152760 SessionService* session_service =
2761 SessionServiceFactory::GetForProfileIfExisting(profile_);
2762 if (session_service)
[email protected]81898992011-06-14 22:15:002763 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:572764}
2765
[email protected]36b6dcb2008-11-12 01:19:572766void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:472767#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:572768 // This is scheduled to run after we return to the message loop because
2769 // otherwise the frame will think the drag session is still active and ignore
2770 // the request.
[email protected]d6a3c772009-01-27 19:41:202771 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:372772 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:362773 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]d6a3c772009-01-27 19:41:202774#endif
initial.commit09911bf2008-07-26 23:55:292775}
2776
[email protected]3d61dd02012-06-07 00:05:532777void Browser::CreateHistoricalTab(TabContents* contents) {
[email protected]505323e22009-01-24 02:47:582778 // We don't create historical tabs for incognito windows or windows without
2779 // profiles.
[email protected]92371eb2011-04-28 11:50:152780 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:582781 return;
[email protected]92371eb2011-04-28 11:50:152782
[email protected]0d4ef7f2011-05-12 22:38:572783 // We don't create historical tabs for print preview tabs.
[email protected]d9083482012-01-06 00:38:462784 if (contents->web_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
[email protected]0d4ef7f2011-05-12 22:38:572785 return;
2786
[email protected]92371eb2011-04-28 11:50:152787 TabRestoreService* service =
2788 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:582789
[email protected]fb5ff422010-05-03 20:46:102790 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:152791 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]d9083482012-01-06 00:38:462792 service->CreateHistoricalTab(&contents->web_contents()->GetController(),
[email protected]2fc15ae2012-05-06 00:01:372793 tab_strip_model_->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:582794 }
2795}
2796
[email protected]3d61dd02012-06-07 00:05:532797bool Browser::RunUnloadListenerBeforeClosing(TabContents* contents) {
[email protected]d9083482012-01-06 00:38:462798 return Browser::RunUnloadEventsHelper(contents->web_contents());
[email protected]505323e22009-01-24 02:47:582799}
2800
[email protected]2db5a2042011-04-26 17:13:472801bool Browser::CanCloseContents(std::vector<int>* indices) {
2802 DCHECK(!indices->empty());
2803 TabCloseableStateWatcher* watcher =
2804 g_browser_process->tab_closeable_state_watcher();
2805 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
2806 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:042807 return false;
[email protected]2db5a2042011-04-26 17:13:472808 // Now, handle cases where at least one tab can be closed.
2809 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:102810 // in-progress downloads.
2811 // Note that the next call when it returns false will ask the user for
2812 // confirmation before closing the browser if the user decides so.
[email protected]41f022e2012-01-31 05:56:402813 if (tab_count() == static_cast<int>(indices->size()) &&
[email protected]2db5a2042011-04-26 17:13:472814 !CanCloseWithInProgressDownloads()) {
2815 indices->clear();
2816 can_close_all = false;
2817 }
2818 return can_close_all;
[email protected]940ccb22009-04-30 17:11:102819}
[email protected]d6a3c772009-01-27 19:41:202820
[email protected]a206b442009-10-08 23:20:202821bool Browser::CanBookmarkAllTabs() const {
2822 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:582823 return (model && model->IsLoaded()) &&
2824 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:042825 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:202826}
2827
[email protected]b3ac5c82009-10-08 20:56:542828void Browser::BookmarkAllTabs() {
[email protected]9d603392011-11-18 05:45:282829 BookmarkEditor::ShowBookmarkAllTabsDialog(this);
[email protected]b3ac5c82009-10-08 20:56:542830}
2831
[email protected]0b4d3382010-07-14 16:13:042832bool Browser::CanCloseTab() const {
2833 TabCloseableStateWatcher* watcher =
2834 g_browser_process->tab_closeable_state_watcher();
2835 return !watcher || watcher->CanCloseTab(this);
2836}
2837
[email protected]92655362012-04-20 21:33:172838bool Browser::CanRestoreTab() {
2839 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
2840}
2841
2842void Browser::RestoreTab() {
2843 content::RecordAction(UserMetricsAction("RestoreTab"));
2844 TabRestoreService* service =
2845 TabRestoreServiceFactory::GetForProfile(profile_);
2846 if (!service)
2847 return;
2848
2849 service->RestoreMostRecentEntry(tab_restore_service_delegate());
2850}
2851
[email protected]b283a7532010-08-12 21:24:592852bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:442853 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
2854 // for those windows, we already have a big icon in the top-left outside any
2855 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:332856 return true;
[email protected]b283a7532010-08-12 21:24:592857}
2858
[email protected]2d46c842008-11-14 19:24:312859///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572860// Browser, TabStripModelObserver implementation:
2861
[email protected]3d61dd02012-06-07 00:05:532862void Browser::TabInsertedAt(TabContents* contents,
[email protected]36b6dcb2008-11-12 01:19:572863 int index,
2864 bool foreground) {
[email protected]9219d262011-02-15 21:05:122865 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:002866 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:582867
[email protected]c37e3b62010-01-22 00:15:172868 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:572869
[email protected]159f7762008-12-19 14:58:272870 // Make sure the loading state is updated correctly, otherwise the throbber
2871 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:332872 LoadingStateChanged(contents->web_contents());
[email protected]159f7762008-12-19 14:58:272873
[email protected]36b6dcb2008-11-12 01:19:572874 // If the tab crashes in the beforeunload or unload handler, it won't be
2875 // able to ack. But we know we can close it.
[email protected]fbc5e5f92012-01-02 06:08:322876 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
2877 content::Source<WebContents>(contents->web_contents()));
[email protected]93f230e02011-06-01 14:40:002878
[email protected]432115822011-07-10 15:52:272879 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:322880 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:502881
2882 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]fbc5e5f92012-01-02 06:08:322883 content::Source<WebContents>(contents->web_contents()));
[email protected]36b6dcb2008-11-12 01:19:572884}
2885
[email protected]f2cc7382010-10-15 18:03:052886void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3d61dd02012-06-07 00:05:532887 TabContents* contents,
[email protected]f2cc7382010-10-15 18:03:052888 int index) {
[email protected]d9083482012-01-06 00:38:462889 fullscreen_controller_->OnTabClosing(contents->web_contents());
[email protected]ad50def52011-10-19 23:17:072890 content::NotificationService::current()->Notify(
[email protected]884033e2012-04-16 19:38:422891 chrome::NOTIFICATION_TAB_CLOSING,
[email protected]c5eed492012-01-04 17:07:502892 content::Source<NavigationController>(
[email protected]cca0f1e2012-01-03 18:27:462893 &contents->web_contents()->GetController()),
[email protected]ad50def52011-10-19 23:17:072894 content::NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:572895
[email protected]075969d2012-04-17 20:05:552896 // Sever the WebContents' connection back to us.
[email protected]9219d262011-02-15 21:05:122897 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:572898}
2899
[email protected]3d61dd02012-06-07 00:05:532900void Browser::TabDetachedAt(TabContents* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:172901 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:572902}
2903
[email protected]3d61dd02012-06-07 00:05:532904void Browser::TabDeactivated(TabContents* contents) {
[email protected]01a5a762011-11-21 05:40:552905 fullscreen_controller_->OnTabDeactivated(contents);
[email protected]6b723f82010-10-05 20:14:272906 if (instant())
[email protected]3e481282011-10-15 15:39:502907 instant()->Hide();
[email protected]03bb953d2010-09-14 21:38:302908
[email protected]85ff2c42009-05-29 21:22:032909 // Save what the user's currently typing, so it can be restored when we
2910 // switch back to this tab.
[email protected]83a2610a2012-01-05 01:00:272911 window_->GetLocationBar()->SaveStateToContents(contents->web_contents());
[email protected]85ff2c42009-05-29 21:22:032912}
2913
[email protected]3d61dd02012-06-07 00:05:532914void Browser::ActiveTabChanged(TabContents* old_contents,
2915 TabContents* new_contents,
[email protected]3aca95d42011-05-24 22:06:542916 int index,
2917 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:162918 // On some platforms we want to automatically reload tabs that are
2919 // killed when the user selects them.
[email protected]9d7518f2012-04-17 02:15:202920 bool did_reload = false;
[email protected]d9083482012-01-06 00:38:462921 if (user_gesture && new_contents->web_contents()->GetCrashedStatus() ==
[email protected]a8f024392011-01-13 21:50:162922 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
2923 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:562924 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]734d26692012-03-26 18:00:252925 LOG(WARNING) << "Reloading killed tab at " << index;
[email protected]d6d4dae2012-04-18 17:47:322926 static int reload_count = 0;
[email protected]24c463a2012-04-20 22:33:502927 UMA_HISTOGRAM_CUSTOM_COUNTS(
2928 "Tabs.SadTab.ReloadCount", ++reload_count, 1, 1000, 50);
[email protected]a8f024392011-01-13 21:50:162929 Reload(CURRENT_TAB);
[email protected]9d7518f2012-04-17 02:15:202930 did_reload = true;
[email protected]f8a35772011-02-02 23:17:562931 }
[email protected]a8f024392011-01-13 21:50:162932 }
2933
[email protected]002efb042011-10-07 17:30:242934 // Discarded tabs always get reloaded.
[email protected]9d7518f2012-04-17 02:15:202935 if (!did_reload && IsTabDiscarded(index)) {
[email protected]d6d4dae2012-04-18 17:47:322936 LOG(WARNING) << "Reloading discarded tab at " << index;
2937 static int reload_count = 0;
[email protected]24c463a2012-04-20 22:33:502938 UMA_HISTOGRAM_CUSTOM_COUNTS(
2939 "Tabs.Discard.ReloadCount", ++reload_count, 1, 1000, 50);
[email protected]002efb042011-10-07 17:30:242940 Reload(CURRENT_TAB);
[email protected]002efb042011-10-07 17:30:242941 }
2942
[email protected]36b6dcb2008-11-12 01:19:572943 // If we have any update pending, do it now.
[email protected]24f1477532011-11-22 22:55:362944 if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
[email protected]36b6dcb2008-11-12 01:19:572945 ProcessPendingUIUpdates();
2946
[email protected]36b6dcb2008-11-12 01:19:572947 // Propagate the profile to the location bar.
2948 UpdateToolbar(true);
2949
[email protected]943d8122010-06-11 02:13:452950 // Update reload/stop state.
[email protected]d9083482012-01-06 00:38:462951 UpdateReloadStopState(new_contents->web_contents()->IsLoading(), true);
[email protected]36b6dcb2008-11-12 01:19:572952
[email protected]84214982008-12-10 18:49:102953 // Update commands to reflect current state.
2954 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:572955
2956 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:102957 StatusBubble* status_bubble = GetStatusBubble();
2958 if (status_bubble) {
2959 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:572960
[email protected]be3877f2009-01-14 15:51:102961 // Show the loading state (if any).
[email protected]51d83bdf2011-12-09 16:09:292962 status_bubble->SetStatus(
[email protected]3d61dd02012-06-07 00:05:532963 GetActiveTabContents()->core_tab_helper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:102964 }
[email protected]36b6dcb2008-11-12 01:19:572965
[email protected]24db8a072009-10-29 20:35:372966 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:242967 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:172968 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:582969 }
2970
[email protected]36b6dcb2008-11-12 01:19:572971 // Update sessions. Don't force creation of sessions. If sessions doesn't
2972 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:152973 SessionService* session_service =
2974 SessionServiceFactory::GetForProfileIfExisting(profile_);
[email protected]2fc15ae2012-05-06 00:01:372975 if (session_service && !tab_strip_model_->closing_all()) {
[email protected]41f022e2012-01-31 05:56:402976 session_service->SetSelectedTabInWindow(session_id(), active_index());
[email protected]36b6dcb2008-11-12 01:19:572977 }
[email protected]09b29342011-06-24 19:18:482978
2979 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:572980}
2981
[email protected]3d61dd02012-06-07 00:05:532982void Browser::TabMoved(TabContents* contents,
[email protected]36b6dcb2008-11-12 01:19:572983 int from_index,
[email protected]1a242c32010-02-02 21:20:542984 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:572985 DCHECK(from_index >= 0 && to_index >= 0);
2986 // Notify the history service.
2987 SyncHistoryWithTabs(std::min(from_index, to_index));
2988}
2989
[email protected]da25dd52011-01-11 19:06:302990void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
[email protected]3d61dd02012-06-07 00:05:532991 TabContents* old_contents,
2992 TabContents* new_contents,
[email protected]8a34e6602010-10-02 17:29:432993 int index) {
[email protected]c37e3b62010-01-22 00:15:172994 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
[email protected]41f022e2012-01-31 05:56:402995 TabInsertedAt(new_contents, index, (index == active_index()));
[email protected]c37e3b62010-01-22 00:15:172996
[email protected]a26023822011-12-29 00:23:552997 int entry_count =
[email protected]d9083482012-01-06 00:38:462998 new_contents->web_contents()->GetController().GetEntryCount();
[email protected]c37e3b62010-01-22 00:15:172999 if (entry_count > 0) {
3000 // Send out notification so that observers are updated appropriately.
[email protected]d9083482012-01-06 00:38:463001 new_contents->web_contents()->GetController().NotifyEntryChanged(
3002 new_contents->web_contents()->GetController().GetEntryAtIndex(
[email protected]4a63e242011-12-12 15:23:083003 entry_count - 1),
[email protected]c37e3b62010-01-22 00:15:173004 entry_count - 1);
3005 }
[email protected]47e020a2010-10-15 14:43:373006
[email protected]92371eb2011-04-28 11:50:153007 SessionService* session_service =
3008 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:373009 if (session_service) {
3010 // The new_contents may end up with a different navigation stack. Force
3011 // the session service to update itself.
[email protected]41f022e2012-01-31 05:56:403012 session_service->TabRestored(new_contents, IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373013 }
[email protected]2914600d2011-01-31 23:25:143014
[email protected]a0262432012-04-13 15:48:093015 content::DevToolsManager::GetInstance()->ContentsReplaced(
[email protected]d9083482012-01-06 00:38:463016 old_contents->web_contents(), new_contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:173017}
3018
[email protected]3d61dd02012-06-07 00:05:533019void Browser::TabPinnedStateChanged(TabContents* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153020 SessionService* session_service =
3021 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093022 if (session_service) {
3023 session_service->SetPinnedState(
3024 session_id(),
[email protected]3d61dd02012-06-07 00:05:533025 GetTabContentsAt(index)->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:403026 IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093027 }
3028}
3029
[email protected]36b6dcb2008-11-12 01:19:573030void Browser::TabStripEmpty() {
3031 // Close the frame after we return to the message loop (not immediately,
3032 // otherwise it will destroy this object before the stack has a chance to
3033 // cleanly unwind.)
3034 // Note: This will be called several times if TabStripEmpty is called several
3035 // times. This is because it does not close the window if tabs are
3036 // still present.
[email protected]0586b0e2010-02-12 21:38:373037 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363038 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]49d864f2012-04-09 21:14:393039 // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not
3040 // attempt to add tabs to the browser before it closes.
3041 is_attempting_to_close_browser_ = true;
[email protected]36b6dcb2008-11-12 01:19:573042}
3043
[email protected]92655362012-04-20 21:33:173044void Browser::OnAcceptFullscreenPermission(
3045 const GURL& url,
3046 FullscreenExitBubbleType bubble_type) {
3047 fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type);
3048}
3049
3050void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) {
3051 fullscreen_controller_->OnDenyFullscreenPermission(bubble_type);
3052}
3053
3054bool Browser::TabsNeedBeforeUnloadFired() {
3055 if (tabs_needing_before_unload_fired_.empty()) {
3056 for (int i = 0; i < tab_count(); ++i) {
[email protected]3d61dd02012-06-07 00:05:533057 WebContents* contents = GetTabContentsAt(i)->web_contents();
[email protected]92655362012-04-20 21:33:173058 if (contents->NeedToFireBeforeUnload())
3059 tabs_needing_before_unload_fired_.insert(contents);
3060 }
3061 }
3062 return !tabs_needing_before_unload_fired_.empty();
3063}
3064
3065bool Browser::IsFullscreenForTabOrPending() const {
3066 return fullscreen_controller_->IsFullscreenForTabOrPending();
3067}
3068
[email protected]d013f142012-04-27 17:31:143069bool Browser::IsMouseLocked() const {
3070 return fullscreen_controller_->IsMouseLocked();
[email protected]92655362012-04-20 21:33:173071}
3072
3073void Browser::OnWindowDidShow() {
3074 if (window_has_shown_)
3075 return;
3076 window_has_shown_ = true;
3077
3078 // Nothing to do for non-tabbed windows.
3079 if (!is_type_tabbed())
3080 return;
3081
3082 // Show any pending global error bubble.
3083 GlobalErrorService* service =
3084 GlobalErrorServiceFactory::GetForProfile(profile());
3085 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
3086 if (error)
3087 error->ShowBubbleView(this);
3088}
3089
3090void Browser::ShowFirstRunBubble() {
3091 window()->GetLocationBar()->ShowFirstRunBubble();
3092}
3093
3094///////////////////////////////////////////////////////////////////////////////
3095// Browser, protected:
3096
3097BrowserWindow* Browser::CreateBrowserWindow() {
3098 bool create_panel = false;
3099#if defined(USE_ASH)
3100 if (CommandLine::ForCurrentProcess()->HasSwitch(
3101 ash::switches::kAuraPanelManager))
3102 create_panel = is_type_panel();
3103#elif !defined(OS_CHROMEOS)
3104 create_panel = is_type_panel();
3105#endif
3106 if (create_panel)
[email protected]4d617832012-05-22 19:10:263107 return PanelManager::GetInstance()->CreatePanel(this)->browser_window();
[email protected]92655362012-04-20 21:33:173108
3109 return BrowserWindow::CreateBrowserWindow(this);
3110}
3111
[email protected]36b6dcb2008-11-12 01:19:573112///////////////////////////////////////////////////////////////////////////////
[email protected]674bc592011-12-20 23:00:423113// Browser, content::WebContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293114
[email protected]e5d549d2011-12-28 01:29:203115WebContents* Browser::OpenURLFromTab(WebContents* source,
[email protected]00c37fc2011-08-02 00:22:503116 const OpenURLParams& params) {
3117 browser::NavigateParams nav_params(this, params.url, params.transition);
[email protected]3d61dd02012-06-07 00:05:533118 nav_params.source_contents = GetTabContentsAt(
[email protected]2fc15ae2012-05-06 00:01:373119 tab_strip_model_->GetWrapperIndex(source));
[email protected]cb8fb01a2011-12-05 21:01:143120 nav_params.referrer = params.referrer;
[email protected]00c37fc2011-08-02 00:22:503121 nav_params.disposition = params.disposition;
3122 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
[email protected]e35ccd552012-05-23 16:22:473123 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]00c37fc2011-08-02 00:22:503124 nav_params.user_gesture = true;
3125 nav_params.override_encoding = params.override_encoding;
[email protected]e47ae9472011-10-13 19:48:343126 nav_params.is_renderer_initiated = params.is_renderer_initiated;
[email protected]4ad5d77d2011-12-03 02:00:483127 nav_params.transferred_global_request_id =
3128 params.transferred_global_request_id;
[email protected]00c37fc2011-08-02 00:22:503129 browser::Navigate(&nav_params);
3130
3131 return nav_params.target_contents ?
[email protected]d9083482012-01-06 00:38:463132 nav_params.target_contents->web_contents() : NULL;
initial.commit09911bf2008-07-26 23:55:293133}
3134
[email protected]2a6bc3e2011-12-28 23:51:333135void Browser::NavigationStateChanged(const WebContents* source,
initial.commit09911bf2008-07-26 23:55:293136 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293137 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403138 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293139 ScheduleUIUpdate(source, changed_flags);
3140
[email protected]83c2e232011-10-07 21:36:463141 // We can synchronously update commands since they will only change once per
3142 // navigation, so we don't have to worry about flickering. We do, however,
3143 // need to update the command state early on load to always present usable
3144 // actions in the face of slow-to-commit pages.
[email protected]d9083482012-01-06 00:38:463145 if (changed_flags & (content::INVALIDATE_TYPE_URL |
3146 content::INVALIDATE_TYPE_LOAD))
[email protected]84214982008-12-10 18:49:103147 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293148}
3149
[email protected]2a6bc3e2011-12-28 23:51:333150void Browser::AddNewContents(WebContents* source,
3151 WebContents* new_contents,
initial.commit09911bf2008-07-26 23:55:293152 WindowOpenDisposition disposition,
3153 const gfx::Rect& initial_pos,
3154 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373155 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333156 DCHECK(disposition != SAVE_TO_DISK);
3157 // Can't create a new contents for the current tab - invalid case.
3158 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293159
[email protected]3d61dd02012-06-07 00:05:533160 TabContents* source_tab_contents = NULL;
[email protected]e7cfdbd2011-04-22 14:41:373161 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]3d61dd02012-06-07 00:05:533162 TabContents* new_tab_contents =
3163 TabContents::GetOwningTabContentsForWebContents(new_contents);
3164 if (!new_tab_contents) {
3165 new_tab_contents = new TabContents(new_contents);
[email protected]2a6bc3e2011-12-28 23:51:333166 }
[email protected]e7cfdbd2011-04-22 14:41:373167 if (source) {
[email protected]3d61dd02012-06-07 00:05:533168 source_tab_contents =
3169 TabContents::GetOwningTabContentsForWebContents(source);
3170 source_blocked_content = source_tab_contents->blocked_content_tab_helper();
[email protected]e7cfdbd2011-04-22 14:41:373171 }
3172
[email protected]3d61dd02012-06-07 00:05:533173 if (source_tab_contents) {
[email protected]e7cfdbd2011-04-22 14:41:373174 // Handle blocking of all contents.
3175 if (source_blocked_content->all_contents_blocked()) {
[email protected]3d61dd02012-06-07 00:05:533176 source_blocked_content->AddTabContents(new_tab_contents,
[email protected]e7cfdbd2011-04-22 14:41:373177 disposition,
[email protected]9e4ae3d2012-03-27 01:05:463178 initial_pos,
[email protected]e7cfdbd2011-04-22 14:41:373179 user_gesture);
3180 return;
3181 }
3182
3183 // Handle blocking of popups.
3184 if ((disposition == NEW_POPUP) && !user_gesture &&
3185 !CommandLine::ForCurrentProcess()->HasSwitch(
3186 switches::kDisablePopupBlocking)) {
3187 // Unrequested popups from normal pages are constrained unless they're in
3188 // the whitelist. The popup owner will handle checking this.
[email protected]3d61dd02012-06-07 00:05:533189 GetConstrainingContentsWrapper(source_tab_contents)->
[email protected]393c0ed02011-04-22 14:55:363190 blocked_content_tab_helper()->
[email protected]3d61dd02012-06-07 00:05:533191 AddPopup(new_tab_contents, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373192 return;
3193 }
3194
[email protected]151a63d2011-12-20 22:32:523195 new_contents->GetRenderViewHost()->DisassociateFromPopupCount();
[email protected]e7cfdbd2011-04-22 14:41:373196 }
3197
[email protected]3d61dd02012-06-07 00:05:533198 browser::NavigateParams params(this, new_tab_contents);
[email protected]2fc15ae2012-05-06 00:01:373199 params.source_contents = source ?
[email protected]3d61dd02012-06-07 00:05:533200 GetTabContentsAt(tab_strip_model_->GetWrapperIndex(source)): NULL;
[email protected]3c9e1872010-11-18 16:17:493201 params.disposition = disposition;
[email protected]9e4ae3d2012-03-27 01:05:463202 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353203 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3204 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493205 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293206}
3207
[email protected]2a6bc3e2011-12-28 23:51:333208void Browser::ActivateContents(WebContents* contents) {
[email protected]2fc15ae2012-05-06 00:01:373209 ActivateTabAt(tab_strip_model_->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393210 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293211}
3212
[email protected]2a6bc3e2011-12-28 23:51:333213void Browser::DeactivateContents(WebContents* contents) {
[email protected]ea42e7782010-08-23 23:58:123214 window_->Deactivate();
3215}
3216
[email protected]2a6bc3e2011-12-28 23:51:333217void Browser::LoadingStateChanged(WebContents* source) {
[email protected]2fc15ae2012-05-06 00:01:373218 window_->UpdateLoadingAnimations(tab_strip_model_->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393219 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293220
[email protected]3d61dd02012-06-07 00:05:533221 WebContents* selected_contents = GetActiveWebContents();
[email protected]3c9e1872010-11-18 16:17:493222 if (source == selected_contents) {
[email protected]f5d978c2011-07-21 14:43:513223 bool is_loading = source->IsLoading();
3224 UpdateReloadStopState(is_loading, false);
[email protected]43d259d2010-09-03 21:37:463225 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443226 GetStatusBubble()->SetStatus(
[email protected]3d61dd02012-06-07 00:05:533227 GetActiveTabContents()->core_tab_helper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463228 }
[email protected]eabfdae92009-12-11 06:13:513229
[email protected]f5d978c2011-07-21 14:43:513230 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333231 // Schedule a shortcut update when web application info is available if
3232 // last committed entry is not NULL. Last committed entry could be NULL
3233 // when an interstitial page is injected (e.g. bad https certificate,
3234 // malware site etc). When this happens, we abort the shortcut update.
[email protected]10f417c52011-12-28 21:04:233235 NavigationEntry* entry = source->GetController().GetLastCommittedEntry();
[email protected]eabfdae92009-12-11 06:13:513236 if (entry) {
[email protected]3d61dd02012-06-07 00:05:533237 TabContents::GetOwningTabContentsForWebContents(source)->
[email protected]36fc0392011-12-25 03:59:513238 extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]eabfdae92009-12-11 06:13:513239 } else {
3240 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513241 }
3242 }
initial.commit09911bf2008-07-26 23:55:293243 }
3244}
3245
[email protected]a81343d232011-12-27 07:39:203246void Browser::CloseContents(WebContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473247 if (is_attempting_to_close_browser_) {
3248 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063249 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473250 // will go down the slow shutdown path instead of the fast path of killing
3251 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213252 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473253 return;
3254 }
3255
[email protected]2fc15ae2012-05-06 00:01:373256 int index = tab_strip_model_->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293257 if (index == TabStripModel::kNoTab) {
3258 NOTREACHED() << "CloseContents called for tab not in our strip";
3259 return;
3260 }
[email protected]2fc15ae2012-05-06 00:01:373261 tab_strip_model_->CloseTabContentsAt(index,
[email protected]0cce15f2010-05-21 16:58:393262 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293263}
3264
[email protected]2a6bc3e2011-12-28 23:51:333265void Browser::MoveContents(WebContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143266 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293267 NOTREACHED() << "moving invalid browser type";
3268 return;
3269 }
[email protected]e561e202010-03-24 17:57:123270 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293271}
3272
[email protected]2a6bc3e2011-12-28 23:51:333273void Browser::DetachContents(WebContents* source) {
[email protected]2fc15ae2012-05-06 00:01:373274 int index = tab_strip_model_->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313275 if (index >= 0)
[email protected]2fc15ae2012-05-06 00:01:373276 tab_strip_model_->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313277}
3278
[email protected]2a6bc3e2011-12-28 23:51:333279bool Browser::IsPopupOrPanel(const WebContents* source) const {
initial.commit09911bf2008-07-26 23:55:293280 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143281 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293282}
3283
[email protected]92655362012-04-20 21:33:173284bool Browser::CanReloadContents(WebContents* source) const {
3285 return !is_devtools();
[email protected]36b6dcb2008-11-12 01:19:573286}
3287
[email protected]2a6bc3e2011-12-28 23:51:333288void Browser::UpdateTargetURL(WebContents* source, int32 page_id,
[email protected]d952a052011-09-06 18:42:453289 const GURL& url) {
[email protected]be3877f2009-01-14 15:51:103290 if (!GetStatusBubble())
3291 return;
3292
[email protected]3d61dd02012-06-07 00:05:533293 if (source == GetActiveWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:573294 PrefService* prefs = profile_->GetPrefs();
[email protected]65233052011-08-22 19:02:483295 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
[email protected]36b6dcb2008-11-12 01:19:573296 }
3297}
3298
[email protected]92655362012-04-20 21:33:173299void Browser::ContentsMouseEvent(
3300 WebContents* source, const gfx::Point& location, bool motion) {
3301 if (!GetStatusBubble())
3302 return;
3303
[email protected]3d61dd02012-06-07 00:05:533304 if (source == GetActiveWebContents()) {
[email protected]92655362012-04-20 21:33:173305 GetStatusBubble()->MouseMoved(location, !motion);
3306 if (!motion)
3307 GetStatusBubble()->SetURL(GURL(), std::string());
3308 }
[email protected]3a6a3b62009-05-27 21:36:203309}
3310
[email protected]36b6dcb2008-11-12 01:19:573311void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253312 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573313}
3314
[email protected]2a6bc3e2011-12-28 23:51:333315void Browser::WebContentsFocused(WebContents* contents) {
3316 window_->WebContentsFocused(contents);
[email protected]7e383692009-06-12 19:14:543317}
3318
[email protected]130efb02009-09-18 18:54:353319bool Browser::TakeFocus(bool reverse) {
[email protected]ad50def52011-10-19 23:17:073320 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273321 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
[email protected]6c2381d2011-10-19 02:52:533322 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:073323 content::NotificationService::NoDetails());
[email protected]130efb02009-09-18 18:54:353324 return false;
3325}
3326
[email protected]36b6dcb2008-11-12 01:19:573327bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143328 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573329}
3330
[email protected]2a6bc3e2011-12-28 23:51:333331void Browser::ConvertContentsToApplication(WebContents* contents) {
[email protected]36fc0392011-12-25 03:59:513332 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
[email protected]57ecc4b2010-08-11 03:02:513333 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573334
[email protected]b6c874582009-05-08 19:38:313335 DetachContents(contents);
[email protected]da22aa62012-04-04 18:54:353336 Browser* app_browser = Browser::CreateWithParams(
3337 Browser::CreateParams::CreateForApp(
3338 TYPE_POPUP, app_name, gfx::Rect(), profile_));
[email protected]3d61dd02012-06-07 00:05:533339 TabContents* tab_contents =
3340 TabContents::GetOwningTabContentsForWebContents(contents);
3341 if (!tab_contents)
3342 tab_contents = new TabContents(contents);
3343 app_browser->tab_strip_model()->AppendTabContents(tab_contents, true);
[email protected]75aef122010-12-06 21:48:323344
3345 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:523346 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]75aef122010-12-06 21:48:323347 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573348}
3349
[email protected]b7a756d42012-01-23 18:08:173350gfx::Rect Browser::GetRootWindowResizerRect() const {
3351 return window_->GetRootWindowResizerRect();
3352}
3353
[email protected]2a6bc3e2011-12-28 23:51:333354void Browser::BeforeUnloadFired(WebContents* tab,
[email protected]36b6dcb2008-11-12 01:19:573355 bool proceed,
3356 bool* proceed_to_fire_unload) {
3357 if (!is_attempting_to_close_browser_) {
3358 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393359 if (!proceed)
[email protected]0bfbf882011-12-22 18:19:273360 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573361 return;
3362 }
3363
3364 if (!proceed) {
3365 CancelWindowClose();
3366 *proceed_to_fire_unload = false;
[email protected]0bfbf882011-12-22 18:19:273367 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573368 return;
3369 }
3370
[email protected]06b42f032008-12-03 18:43:053371 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313372 // Now that beforeunload has fired, put the tab on the queue to fire
3373 // unload.
[email protected]06b42f032008-12-03 18:43:053374 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573375 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063376 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573377 // fire all the beforeunload events before attempting to fire the unload
3378 // events should the user cancel closing the browser.
3379 *proceed_to_fire_unload = false;
3380 return;
3381 }
3382
3383 *proceed_to_fire_unload = true;
3384}
3385
[email protected]a26dc362010-04-23 01:48:583386void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133387 // Two differences between this and FocusLocationBar():
3388 // (1) This doesn't get recorded in user metrics, since it's called
3389 // internally.
3390 // (2) This checks whether the location bar can be focused, and if not, clears
3391 // the focus. FocusLocationBar() is only reached when the location bar is
3392 // focusable, but this may be reached at other times, e.g. while in
3393 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583394 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573395}
3396
[email protected]7d5925a2009-03-03 02:59:123397void Browser::RenderWidgetShowing() {
3398 window_->DisableInactiveFrame();
3399}
[email protected]a239c3f2009-02-17 22:13:193400
[email protected]0a2aeb82009-05-15 21:52:483401int Browser::GetExtraRenderViewHeight() const {
3402 return window_->GetExtraRenderViewHeight();
3403}
3404
[email protected]2a6bc3e2011-12-28 23:51:333405void Browser::OnStartDownload(WebContents* source,
[email protected]e582fdd2011-12-20 16:48:173406 content::DownloadItem* download) {
[email protected]3d61dd02012-06-07 00:05:533407 TabContents* tab_contents =
3408 TabContents::GetOwningTabContentsForWebContents(source);
3409 TabContents* constrained = GetConstrainingContentsWrapper(tab_contents);
3410 if (constrained != tab_contents) {
[email protected]686493142011-07-15 21:47:223411 // Download in a constrained popup is shown in the tab that opened it.
[email protected]d9083482012-01-06 00:38:463412 WebContents* constrained_tab = constrained->web_contents();
[email protected]6934a702011-12-20 00:04:513413 constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download);
[email protected]686493142011-07-15 21:47:223414 return;
3415 }
3416
3417 if (!window())
3418 return;
3419
[email protected]a0e4b072011-08-17 01:47:073420 if (DisplayOldDownloadsUI()) {
[email protected]a0e4b072011-08-17 01:47:073421 // GetDownloadShelf creates the download shelf if it was not yet created.
3422 DownloadShelf* shelf = window()->GetDownloadShelf();
3423 shelf->AddDownload(new DownloadItemModel(download));
3424 // Don't show the animation for "Save file" downloads.
3425 // For non-theme extensions, we don't show the download animation.
3426 // Show animation in same window as the download shelf. Download shelf
3427 // may not be in the same window that initiated the download, e.g.
3428 // Panels.
3429 // Don't show the animation if the selected tab is not visible (i.e. the
3430 // window is minimized, we're in a unit test, etc.).
[email protected]3d61dd02012-06-07 00:05:533431 WebContents* shelf_tab = shelf->browser()->GetActiveWebContents();
[email protected]c09a8fd2011-11-21 19:54:503432 if ((download->GetTotalBytes() > 0) &&
[email protected]7fb4bbb2012-05-27 18:06:223433 !download_crx_util::IsExtensionDownload(*download) &&
[email protected]a0e4b072011-08-17 01:47:073434 platform_util::IsVisible(shelf_tab->GetNativeView()) &&
3435 ui::Animation::ShouldRenderRichAnimation()) {
3436 DownloadStartedAnimation::Show(shelf_tab);
3437 }
[email protected]a0e4b072011-08-17 01:47:073438 }
[email protected]686493142011-07-15 21:47:223439
3440 // If the download occurs in a new tab, close it.
[email protected]f5fa20e2011-12-21 22:35:563441 if (source->GetController().IsInitialNavigation() && tab_count() > 1)
[email protected]686493142011-07-15 21:47:223442 CloseContents(source);
3443}
3444
[email protected]2a6bc3e2011-12-28 23:51:333445void Browser::ViewSourceForTab(WebContents* source, const GURL& page_url) {
[email protected]1788e772010-12-15 16:40:503446 DCHECK(source);
[email protected]3d61dd02012-06-07 00:05:533447 TabContents* tab_contents = GetTabContentsAt(
[email protected]2fc15ae2012-05-06 00:01:373448 tab_strip_model_->GetWrapperIndex(source));
[email protected]3d61dd02012-06-07 00:05:533449 ViewSource(tab_contents);
[email protected]77d8d622010-12-15 10:30:123450}
3451
[email protected]2a6bc3e2011-12-28 23:51:333452void Browser::ViewSourceForFrame(WebContents* source,
[email protected]932b7a12011-03-09 12:50:273453 const GURL& frame_url,
3454 const std::string& frame_content_state) {
3455 DCHECK(source);
[email protected]3d61dd02012-06-07 00:05:533456 TabContents* tab_contents = GetTabContentsAt(
[email protected]2fc15ae2012-05-06 00:01:373457 tab_strip_model_->GetWrapperIndex(source));
[email protected]3d61dd02012-06-07 00:05:533458 ViewSource(tab_contents, frame_url, frame_content_state);
[email protected]932b7a12011-03-09 12:50:273459}
3460
[email protected]867125a02009-12-10 06:01:483461bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3462 bool* is_keyboard_shortcut) {
[email protected]85804b52011-10-15 06:56:273463 // Escape exits tabbed fullscreen mode.
3464 // TODO(koz): Write a test for this http://crbug.com/100441.
[email protected]01a5a762011-11-21 05:40:553465 if (event.windowsKeyCode == 27 &&
3466 fullscreen_controller_->HandleUserPressedEscape()) {
[email protected]85804b52011-10-15 06:56:273467 return true;
3468 }
[email protected]867125a02009-12-10 06:01:483469 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3470}
[email protected]97df4b332009-10-02 01:25:413471
[email protected]867125a02009-12-10 06:01:483472void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3473 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413474}
3475
[email protected]4fdf6742012-01-10 20:14:363476void Browser::ShowRepostFormWarningDialog(WebContents* source) {
[email protected]67baffc82011-12-19 18:03:073477 browser::ShowTabModalConfirmDialog(
[email protected]2a6bc3e2011-12-28 23:51:333478 new RepostFormWarningController(source),
[email protected]3d61dd02012-06-07 00:05:533479 TabContents::GetOwningTabContentsForWebContents(source));
[email protected]14f3408a2009-08-31 20:53:533480}
3481
[email protected]ec0b6c42010-08-26 03:16:583482bool Browser::ShouldAddNavigationToHistory(
3483 const history::HistoryAddPageArgs& add_page_args,
[email protected]610cbb82011-10-18 16:35:083484 content::NavigationType navigation_type) {
[email protected]2e29d922009-10-22 22:13:353485 // Don't update history if running as app.
3486 return !IsApplication();
3487}
3488
[email protected]4fdf6742012-01-10 20:14:363489bool Browser::ShouldCreateWebContents(
3490 WebContents* web_contents,
3491 int route_id,
3492 WindowContainerType window_container_type,
[email protected]03b6d552012-03-29 04:03:013493 const string16& frame_name,
3494 const GURL& target_url) {
[email protected]4fdf6742012-01-10 20:14:363495 if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
3496 // If a BackgroundContents is created, suppress the normal WebContents.
3497 return !MaybeCreateBackgroundContents(
[email protected]03b6d552012-03-29 04:03:013498 route_id, web_contents, frame_name, target_url);
[email protected]4fdf6742012-01-10 20:14:363499 }
3500
3501 return true;
3502}
3503
3504void Browser::WebContentsCreated(WebContents* source_contents,
3505 int64 source_frame_id,
3506 const GURL& target_url,
3507 WebContents* new_contents) {
[email protected]3d61dd02012-06-07 00:05:533508 // Create a TabContents now, so all observers are in place, as the network
3509 // requests for its initial navigation will start immediately. The WebContents
3510 // will later be inserted into this browser using Browser::Navigate via
3511 // AddNewContents. The latter will retrieve the newly created TabContents from
3512 // WebContents object.
3513 new TabContents(new_contents);
[email protected]4fdf6742012-01-10 20:14:363514
3515 // Notify.
3516 RetargetingDetails details;
3517 details.source_web_contents = source_contents;
3518 details.source_frame_id = source_frame_id;
3519 details.target_url = target_url;
3520 details.target_web_contents = new_contents;
3521 details.not_yet_in_tabstrip = true;
3522 content::NotificationService::current()->Notify(
3523 chrome::NOTIFICATION_RETARGETING,
3524 content::Source<Profile>(profile_),
3525 content::Details<RetargetingDetails>(&details));
[email protected]80c7b802011-10-28 19:59:083526}
3527
[email protected]2a6bc3e2011-12-28 23:51:333528void Browser::ContentRestrictionsChanged(WebContents* source) {
[email protected]9e823662010-10-13 23:36:003529 UpdateCommandsForContentRestrictionState();
3530}
3531
[email protected]2a6bc3e2011-12-28 23:51:333532void Browser::RendererUnresponsive(WebContents* source) {
[email protected]c19d9542011-11-15 22:26:423533 // Ignore hangs if print preview is open.
[email protected]3d61dd02012-06-07 00:05:533534 TabContents* tab_contents =
3535 TabContents::GetOwningTabContentsForWebContents(source);
3536 if (tab_contents) {
[email protected]c19d9542011-11-15 22:26:423537 printing::PrintPreviewTabController* controller =
3538 printing::PrintPreviewTabController::GetInstance();
3539 if (controller) {
[email protected]3d61dd02012-06-07 00:05:533540 TabContents* preview_tab =
3541 controller->GetPrintPreviewForTab(tab_contents);
3542 if (preview_tab && preview_tab != tab_contents) {
[email protected]c19d9542011-11-15 22:26:423543 return;
3544 }
3545 }
3546 }
3547
[email protected]55452902011-06-01 21:57:473548 browser::ShowHungRendererDialog(source);
3549}
3550
[email protected]2a6bc3e2011-12-28 23:51:333551void Browser::RendererResponsive(WebContents* source) {
[email protected]55452902011-06-01 21:57:473552 browser::HideHungRendererDialog(source);
3553}
3554
[email protected]2a6bc3e2011-12-28 23:51:333555void Browser::WorkerCrashed(WebContents* source) {
[email protected]3d61dd02012-06-07 00:05:533556 TabContents* tab_contents =
3557 TabContents::GetOwningTabContentsForWebContents(source);
3558 InfoBarTabHelper* infobar_helper = tab_contents->infobar_tab_helper();
[email protected]95a33ed62011-09-30 15:07:083559 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3560 infobar_helper,
3561 NULL,
3562 l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
[email protected]55452902011-06-01 21:57:473563 true));
[email protected]0dd3a0ab2011-02-18 08:17:443564}
3565
[email protected]2a6bc3e2011-12-28 23:51:333566void Browser::DidNavigateMainFramePostCommit(WebContents* tab) {
[email protected]3d61dd02012-06-07 00:05:533567 if (tab == GetActiveWebContents())
[email protected]09b29342011-06-24 19:18:483568 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003569}
3570
[email protected]2a6bc3e2011-12-28 23:51:333571void Browser::DidNavigateToPendingEntry(WebContents* tab) {
[email protected]3d61dd02012-06-07 00:05:533572 if (tab == GetActiveWebContents())
[email protected]09b29342011-06-24 19:18:483573 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003574}
3575
[email protected]3ab9cb82011-06-03 18:02:073576content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
3577 return GetJavaScriptDialogCreatorInstance();
3578}
3579
[email protected]da8543762012-03-20 08:52:203580content::ColorChooser* Browser::OpenColorChooser(WebContents* tab,
3581 int color_chooser_id,
[email protected]55578b0a2012-04-18 14:31:323582 SkColor color) {
[email protected]da8543762012-03-20 08:52:203583#if defined(OS_WIN)
3584 // On Windows, only create a color chooser if one doesn't exist, because we
3585 // can't close the old color chooser dialog.
3586 if (!color_chooser_.get())
3587 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, tab,
3588 color));
3589#else
3590 if (color_chooser_.get())
3591 color_chooser_->End();
3592 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, tab,
3593 color));
3594#endif
3595 return color_chooser_.get();
3596}
3597
3598void Browser::DidEndColorChooser() {
3599 color_chooser_.reset();
3600}
3601
[email protected]2a6bc3e2011-12-28 23:51:333602void Browser::RunFileChooser(WebContents* tab,
[email protected]8caadeb2011-11-22 02:45:233603 const content::FileChooserParams& params) {
[email protected]33f8ad52012-05-22 18:10:133604 FileSelectHelper::RunFileChooser(tab, params);
[email protected]3a29a6e2011-08-24 18:26:213605}
3606
[email protected]33f8ad52012-05-22 18:10:133607void Browser::EnumerateDirectory(WebContents* tab,
3608 int request_id,
[email protected]3a29a6e2011-08-24 18:26:213609 const FilePath& path) {
[email protected]33f8ad52012-05-22 18:10:133610 FileSelectHelper::EnumerateDirectory(tab, request_id, path);
[email protected]3a29a6e2011-08-24 18:26:213611}
3612
[email protected]2a6bc3e2011-12-28 23:51:333613void Browser::ToggleFullscreenModeForTab(WebContents* tab,
[email protected]01a5a762011-11-21 05:40:553614 bool enter_fullscreen) {
3615 fullscreen_controller_->ToggleFullscreenModeForTab(tab, enter_fullscreen);
[email protected]8a5e0ca2011-08-25 06:30:473616}
3617
[email protected]199bba6e2012-04-04 16:19:383618bool Browser::IsFullscreenForTabOrPending(const WebContents* tab) const {
[email protected]ff475a322012-03-14 00:05:353619 return fullscreen_controller_->IsFullscreenForTabOrPending(tab);
[email protected]5d5f7af2011-10-01 01:38:123620}
3621
[email protected]2a6bc3e2011-12-28 23:51:333622void Browser::JSOutOfMemory(WebContents* tab) {
[email protected]b888919c2011-09-02 00:32:163623 JSOutOfMemoryHelper(tab);
[email protected]7d189022011-08-25 22:54:203624}
3625
[email protected]2a6bc3e2011-12-28 23:51:333626void Browser::RegisterProtocolHandler(WebContents* tab,
[email protected]7d189022011-08-25 22:54:203627 const std::string& protocol,
3628 const GURL& url,
[email protected]3a3b75a2012-06-01 08:38:363629 const string16& title,
3630 bool user_gesture) {
3631 RegisterProtocolHandlerHelper(tab, protocol, url, title, user_gesture);
[email protected]7d189022011-08-25 22:54:203632}
3633
[email protected]3a3b75a2012-06-01 08:38:363634void Browser::RegisterIntentHandler(
3635 WebContents* tab,
3636 const webkit_glue::WebIntentServiceData& data,
3637 bool user_gesture) {
3638 RegisterIntentHandlerHelper(tab, data, user_gesture);
[email protected]7d189022011-08-25 22:54:203639}
3640
[email protected]0d9989d2011-12-21 20:26:003641void Browser::WebIntentDispatch(
[email protected]2a6bc3e2011-12-28 23:51:333642 WebContents* tab, content::WebIntentsDispatcher* intents_dispatcher) {
[email protected]d9436152012-05-24 03:24:463643 if (!web_intents::IsWebIntentsEnabledForProfile(profile_))
[email protected]828e61af2011-09-14 19:45:063644 return;
3645
[email protected]86238d22012-05-22 20:00:113646 UMA_HISTOGRAM_COUNTS("WebIntents.Dispatch", 1);
3647
[email protected]3d61dd02012-06-07 00:05:533648 TabContents* tab_contents =
3649 TabContents::GetOwningTabContentsForWebContents(tab);
3650 tab_contents->web_intent_picker_controller()->SetIntentsDispatcher(
3651 intents_dispatcher);
3652 tab_contents->web_intent_picker_controller()->ShowDialog(
[email protected]0d9989d2011-12-21 20:26:003653 intents_dispatcher->GetIntent().action,
3654 intents_dispatcher->GetIntent().type);
[email protected]b888919c2011-09-02 00:32:163655}
3656
[email protected]2a6bc3e2011-12-28 23:51:333657void Browser::UpdatePreferredSize(WebContents* source,
[email protected]0548c5352011-09-07 00:33:333658 const gfx::Size& pref_size) {
3659 window_->UpdatePreferredSize(source, pref_size);
3660}
3661
[email protected]61e2b3cc2012-03-02 16:13:343662void Browser::ResizeDueToAutoResize(WebContents* source,
3663 const gfx::Size& new_size) {
3664 window_->ResizeDueToAutoResize(source, new_size);
3665}
3666
[email protected]92655362012-04-20 21:33:173667void Browser::FindReply(WebContents* tab,
3668 int request_id,
3669 int number_of_matches,
3670 const gfx::Rect& selection_rect,
3671 int active_match_ordinal,
3672 bool final_update) {
3673 FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
3674 active_match_ordinal, final_update);
3675}
3676
[email protected]a9c81f02012-06-01 00:15:443677void Browser::RequestToLockMouse(WebContents* tab,
3678 bool user_gesture,
3679 bool last_unlocked_by_target) {
3680 fullscreen_controller_->RequestToLockMouse(tab,
3681 user_gesture,
3682 last_unlocked_by_target);
[email protected]55c87fa2011-10-15 07:28:283683}
3684
[email protected]5ef8e372011-10-18 04:25:553685void Browser::LostMouseLock() {
[email protected]01a5a762011-11-21 05:40:553686 fullscreen_controller_->LostMouseLock();
[email protected]5ef8e372011-10-18 04:25:553687}
3688
[email protected]36b6dcb2008-11-12 01:19:573689///////////////////////////////////////////////////////////////////////////////
[email protected]51d83bdf2011-12-09 16:09:293690// Browser, CoreTabHelperDelegate implementation:
[email protected]a0366a52011-02-04 20:04:213691
[email protected]3d61dd02012-06-07 00:05:533692void Browser::SwapTabContents(TabContents* old_tab_contents,
3693 TabContents* new_tab_contents) {
[email protected]2fc15ae2012-05-06 00:01:373694 int index = tab_strip_model_->GetIndexOfTabContents(old_tab_contents);
[email protected]92655362012-04-20 21:33:173695 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]2fc15ae2012-05-06 00:01:373696 tab_strip_model_->ReplaceTabContentsAt(index, new_tab_contents);
[email protected]92655362012-04-20 21:33:173697}
3698
3699///////////////////////////////////////////////////////////////////////////////
3700// Browser, SearchEngineTabHelperDelegate implementation:
3701
[email protected]3613347d2012-04-27 20:27:373702void Browser::ConfirmAddSearchProvider(TemplateURL* template_url,
[email protected]92655362012-04-20 21:33:173703 Profile* profile) {
3704 window()->ConfirmAddSearchProvider(template_url, profile);
3705}
3706
3707///////////////////////////////////////////////////////////////////////////////
3708// Browser, ConstrainedWindowTabHelperDelegate implementation:
3709
[email protected]3d61dd02012-06-07 00:05:533710void Browser::SetTabContentBlocked(TabContents* tab_contents, bool blocked) {
3711 int index = tab_strip_model_->GetIndexOfTabContents(tab_contents);
[email protected]92655362012-04-20 21:33:173712 if (index == TabStripModel::kNoTab) {
3713 NOTREACHED();
3714 return;
3715 }
[email protected]2fc15ae2012-05-06 00:01:373716 tab_strip_model_->SetTabBlocked(index, blocked);
[email protected]3d61dd02012-06-07 00:05:533717 UpdatePrintingState(tab_contents->web_contents()->GetContentRestrictions());
3718 if (!blocked && GetActiveTabContents() == tab_contents)
3719 tab_contents->web_contents()->Focus();
[email protected]92655362012-04-20 21:33:173720}
3721
3722///////////////////////////////////////////////////////////////////////////////
3723// Browser, BlockedContentTabHelperDelegate implementation:
3724
[email protected]3d61dd02012-06-07 00:05:533725TabContents* Browser::GetConstrainingContentsWrapper(TabContents* source) {
[email protected]92655362012-04-20 21:33:173726 return source;
3727}
3728
3729///////////////////////////////////////////////////////////////////////////////
3730// Browser, BookmarkTabHelperDelegate implementation:
3731
[email protected]3d61dd02012-06-07 00:05:533732void Browser::URLStarredChanged(TabContents* source, bool starred) {
3733 if (source == GetActiveTabContents())
[email protected]92655362012-04-20 21:33:173734 window_->SetStarredState(starred);
3735}
3736
3737///////////////////////////////////////////////////////////////////////////////
[email protected]6f80e932012-06-04 19:00:073738// Browser, ZoomObserver implementation:
3739
[email protected]3d61dd02012-06-07 00:05:533740void Browser::OnZoomIconChanged(TabContents* source,
[email protected]6f80e932012-06-04 19:00:073741 ZoomController::ZoomIconState state) {
[email protected]3d61dd02012-06-07 00:05:533742 if (source == GetActiveTabContents())
[email protected]6f80e932012-06-04 19:00:073743 window_->SetZoomIconState(state);
3744}
3745
[email protected]3d61dd02012-06-07 00:05:533746void Browser::OnZoomChanged(TabContents* source,
[email protected]6f80e932012-06-04 19:00:073747 int zoom_percent,
3748 bool can_show_bubble) {
[email protected]3d61dd02012-06-07 00:05:533749 if (source == GetActiveTabContents()) {
[email protected]6f80e932012-06-04 19:00:073750 window_->SetZoomIconTooltipPercent(zoom_percent);
3751
3752 // Only show the zoom bubble for zoom changes in the active window.
3753 if (can_show_bubble && window_->IsActive())
3754 window_->ShowZoomBubble(zoom_percent);
3755 }
3756}
3757
3758///////////////////////////////////////////////////////////////////////////////
[email protected]92655362012-04-20 21:33:173759// Browser, ExtensionTabHelperDelegate implementation:
3760
[email protected]3d61dd02012-06-07 00:05:533761void Browser::OnDidGetApplicationInfo(TabContents* source,
[email protected]553602e12011-04-05 17:01:183762 int32 page_id) {
[email protected]3d61dd02012-06-07 00:05:533763 if (GetActiveTabContents() != source)
[email protected]553602e12011-04-05 17:01:183764 return;
3765
[email protected]10f417c52011-12-28 21:04:233766 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:463767 source->web_contents()->GetController().GetLastCommittedEntry();
[email protected]36fc0392011-12-25 03:59:513768 if (!entry || (entry->GetPageID() != page_id))
[email protected]553602e12011-04-05 17:01:183769 return;
3770
3771 switch (pending_web_app_action_) {
3772 case CREATE_SHORTCUT: {
3773 window()->ShowCreateWebAppShortcutsDialog(source);
3774 break;
3775 }
3776 case UPDATE_SHORTCUT: {
3777 web_app::UpdateShortcutForTabContents(source);
3778 break;
3779 }
3780 default:
3781 NOTREACHED();
3782 break;
3783 }
3784
3785 pending_web_app_action_ = NONE;
3786}
3787
[email protected]3d61dd02012-06-07 00:05:533788void Browser::OnInstallApplication(TabContents* source,
[email protected]553602e12011-04-05 17:01:183789 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:363790 ExtensionService* extension_service = profile()->GetExtensionService();
3791 if (!extension_service)
[email protected]553602e12011-04-05 17:01:183792 return;
3793
[email protected]d8c8f25f2011-11-02 18:18:013794 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(
3795 extension_service,
[email protected]14908b72011-04-20 06:54:363796 extension_service->show_extensions_prompts() ?
3797 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:183798 installer->InstallWebApp(web_app);
3799}
3800
[email protected]c90c6ca2011-02-16 20:11:383801///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573802// Browser, SelectFileDialog::Listener implementation:
3803
[email protected]561abe62009-04-06 18:08:343804void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:513805 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:123806 GURL file_url = net::FilePathToFileURL(path);
[email protected]b7813a22012-04-04 18:41:023807
3808#if defined(OS_CHROMEOS)
3809 gdata::util::ModifyGDataFileResourceUrl(profile_, path, &file_url);
3810#endif
3811
[email protected]e5d549d2011-12-28 01:29:203812 if (file_url.is_empty())
3813 return;
3814
3815 OpenURL(OpenURLParams(
3816 file_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED,
3817 false));
[email protected]36b6dcb2008-11-12 01:19:573818}
3819
3820///////////////////////////////////////////////////////////////////////////////
[email protected]6c2381d2011-10-19 02:52:533821// Browser, content::NotificationObserver implementation:
[email protected]36b6dcb2008-11-12 01:19:573822
[email protected]432115822011-07-10 15:52:273823void Browser::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:533824 const content::NotificationSource& source,
3825 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:273826 switch (type) {
[email protected]fbc5e5f92012-01-02 06:08:323827 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:403828 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:213829 // Pass in false so that we delay processing. We need to delay the
3830 // processing as it may close the tab, which is currently on the call
3831 // stack above us.
[email protected]fbc5e5f92012-01-02 06:08:323832 ClearUnloadState(content::Source<WebContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:403833 }
3834 break;
3835
[email protected]432115822011-07-10 15:52:273836 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:403837 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:323838 // bar to reflect the new state. Note that it's possible for the selected
3839 // tab contents to be NULL. This is because we listen for all sources
3840 // (NavigationControllers) for convenience, so the notification could
3841 // actually be for a different window while we're doing asynchronous
3842 // closing of this one.
[email protected]3d61dd02012-06-07 00:05:533843 if (GetActiveWebContents() &&
3844 &GetActiveWebContents()->GetController() ==
[email protected]c5eed492012-01-04 17:07:503845 content::Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:573846 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:403847 break;
3848
[email protected]432115822011-07-10 15:52:273849 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:363850 if (window()->GetLocationBar())
3851 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:383852
[email protected]b3f7fe22011-11-11 19:27:563853 // Close any tabs from the unloaded extension, unless it's terminated,
3854 // in which case let the sad tabs remain.
[email protected]1c321ee52012-05-21 03:02:343855 if (content::Details<extensions::UnloadedExtensionInfo>(
3856 details)->reason != extension_misc::UNLOAD_REASON_TERMINATE) {
[email protected]b3f7fe22011-11-11 19:27:563857 const Extension* extension =
[email protected]1c321ee52012-05-21 03:02:343858 content::Details<extensions::UnloadedExtensionInfo>(
3859 details)->extension;
[email protected]2fc15ae2012-05-06 00:01:373860 for (int i = tab_strip_model_->count() - 1; i >= 0; --i) {
3861 WebContents* tc =
3862 tab_strip_model_->GetTabContentsAt(i)->web_contents();
[email protected]b3f7fe22011-11-11 19:27:563863 bool close_tab_contents =
3864 tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
3865 tc->GetURL().host() == extension->id();
3866 // We want to close all panels originated by the unloaded extension.
3867 close_tab_contents = close_tab_contents ||
3868 (type_ == TYPE_PANEL &&
3869 (web_app::GetExtensionIdFromApplicationName(app_name_) ==
[email protected]f9e82d92011-10-29 00:50:453870 extension->id()));
[email protected]b3f7fe22011-11-11 19:27:563871 if (close_tab_contents) {
3872 CloseTabContents(tc);
3873 }
[email protected]894bb502009-05-21 22:39:573874 }
3875 }
3876 break;
3877 }
3878
[email protected]432115822011-07-10 15:52:273879 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
[email protected]6c2381d2011-10-19 02:52:533880 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]fe8944f2011-08-30 17:47:323881 if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:363882 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:463883 break;
3884 }
3885
[email protected]432115822011-07-10 15:52:273886 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
3887 case chrome::NOTIFICATION_EXTENSION_LOADED:
[email protected]1797f4a2011-08-30 18:00:283888 // During window creation on Windows we may end up calling into
3889 // SHAppBarMessage, which internally spawns a nested message loop. This
3890 // makes it possible for us to end up here before window creation has
3891 // completed,at which point window_ is NULL. See 94752 for details.
3892 if (window() && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:363893 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:363894 break;
[email protected]ad0c2e1b2010-01-30 00:00:103895
[email protected]6b40bb582012-03-15 20:50:383896#if defined(ENABLE_THEMES)
[email protected]432115822011-07-10 15:52:273897 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
[email protected]e001d412009-06-26 20:53:253898 window()->UserChangedTheme();
3899 break;
[email protected]6b40bb582012-03-15 20:50:383900#endif
[email protected]e001d412009-06-26 20:53:253901
[email protected]432115822011-07-10 15:52:273902 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]6c2381d2011-10-19 02:52:533903 const std::string& pref_name =
3904 *content::Details<std::string>(details).ptr();
[email protected]3cf345b2011-10-06 17:51:253905 if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:373906 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]1499b7dd2012-05-25 16:35:323907 } else if (pref_name == prefs::kInstantEnabled) {
[email protected]73de26a2010-10-17 03:23:253908 if (!InstantController::IsEnabled(profile())) {
3909 if (instant()) {
3910 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:293911 instant_.reset();
3912 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:253913 }
3914 } else {
3915 CreateInstantIfNecessary();
3916 }
[email protected]4e94ab32011-08-05 05:28:273917 } else if (pref_name == prefs::kIncognitoModeAvailability) {
[email protected]93ad8e1c2011-11-08 21:34:053918 UpdateCommandsForIncognitoAvailability();
[email protected]543432ee2010-10-22 16:32:133919 } else if (pref_name == prefs::kDevToolsDisabled) {
3920 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:043921 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]0e12d7d2011-12-01 16:21:443922 content::DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:583923 } else if (pref_name == prefs::kEditBookmarksEnabled) {
3924 UpdateCommandsForBookmarkEditing();
[email protected]3710d0002011-10-11 00:35:003925 } else if (pref_name == prefs::kShowBookmarkBar) {
[email protected]a007e732011-08-05 13:32:193926 UpdateCommandsForBookmarkBar();
[email protected]3710d0002011-10-11 00:35:003927 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]6c6b02d2011-09-02 03:36:473928 } else if (pref_name == prefs::kHomePage) {
[email protected]6c2381d2011-10-19 02:52:533929 PrefService* pref_service = content::Source<PrefService>(source).ptr();
[email protected]6c6b02d2011-09-02 03:36:473930 MarkHomePageAsChanged(pref_service);
[email protected]97b46382011-05-02 13:23:043931 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
3932 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
3933 UpdateOpenFileState();
[email protected]623294c42012-04-27 18:27:143934 } else if (pref_name == prefs::kInManagedMode) {
3935 UpdateCommandsForMultipleProfiles();
[email protected]2a7e7c152010-10-01 20:12:093936 } else {
[email protected]b9c505b2010-04-30 15:05:103937 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:093938 }
[email protected]b9c505b2010-04-30 15:05:103939 break;
3940 }
3941
[email protected]ea049a02011-12-25 21:37:093942 case chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED: {
3943 WebContents* web_contents = content::Source<WebContents>(source).ptr();
[email protected]3d61dd02012-06-07 00:05:533944 if (web_contents == GetActiveWebContents()) {
[email protected]9a9a9e22011-05-13 22:20:353945 LocationBar* location_bar = window()->GetLocationBar();
3946 if (location_bar)
3947 location_bar->UpdateContentSettingsIcons();
3948 }
3949 break;
3950 }
3951
[email protected]432115822011-07-10 15:52:273952 case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:483953 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]e397a4472011-12-21 21:47:503954 UpdateCommandsForTabState();
3955 break;
3956
3957 case content::NOTIFICATION_INTERSTITIAL_DETACHED:
3958 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
3959 UpdateCommandsForTabState();
[email protected]09b29342011-06-24 19:18:483960 break;
3961
[email protected]e83f1682008-09-07 23:57:403962 default:
3963 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:293964 }
3965}
3966
[email protected]d3b98c82010-07-14 07:45:593967///////////////////////////////////////////////////////////////////////////////
3968// Browser, ProfileSyncServiceObserver implementation:
3969
3970void Browser::OnStateChanged() {
[email protected]5e61afb92012-01-27 20:09:133971 DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
3972 profile_));
[email protected]99e652f2012-01-22 04:05:073973 // For unit tests, we don't have a window.
3974 if (!window_)
3975 return;
[email protected]93ad8e1c2011-11-08 21:34:053976 const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen());
[email protected]65549182012-02-25 00:45:403977 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
[email protected]49385da692011-08-05 04:03:393978 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]d3b98c82010-07-14 07:45:593979}
[email protected]88d74942009-01-21 22:04:443980
[email protected]36b6dcb2008-11-12 01:19:573981///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:273982// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:303983
[email protected]3d61dd02012-06-07 00:05:533984void Browser::ShowInstant(TabContents* preview_contents) {
[email protected]e3690ed2011-03-25 20:25:143985 window_->ShowInstant(preview_contents);
[email protected]42f027fb2011-10-27 16:37:483986
[email protected]3d61dd02012-06-07 00:05:533987 GetActiveWebContents()->HideContents();
[email protected]4ca15302012-01-03 05:53:203988 preview_contents->web_contents()->ShowContents();
[email protected]03bb953d2010-09-14 21:38:303989}
3990
[email protected]6b723f82010-10-05 20:14:273991void Browser::HideInstant() {
[email protected]3e481282011-10-15 15:39:503992 window_->HideInstant();
[email protected]3d61dd02012-06-07 00:05:533993 if (GetActiveWebContents())
3994 GetActiveWebContents()->ShowContents();
[email protected]42f027fb2011-10-27 16:37:483995 if (instant_->GetPreviewContents())
[email protected]4ca15302012-01-03 05:53:203996 instant_->GetPreviewContents()->web_contents()->HideContents();
[email protected]03bb953d2010-09-14 21:38:303997}
3998
[email protected]3d61dd02012-06-07 00:05:533999void Browser::CommitInstant(TabContents* preview_contents) {
4000 TabContents* tab_contents = GetActiveTabContents();
[email protected]2fc15ae2012-05-06 00:01:374001 int index = tab_strip_model_->GetIndexOfTabContents(tab_contents);
[email protected]3c9e1872010-11-18 16:17:494002 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:304003 // TabStripModel takes ownership of preview_contents.
[email protected]2fc15ae2012-05-06 00:01:374004 tab_strip_model_->ReplaceTabContentsAt(index, preview_contents);
[email protected]43032342011-03-21 14:10:314005 // InstantUnloadHandler takes ownership of tab_contents.
4006 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:334007
[email protected]d9083482012-01-06 00:38:464008 GURL url = preview_contents->web_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:524009 DCHECK(profile_->GetExtensionService());
4010 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]a9acdff2012-03-08 04:04:524011 AppLauncherHandler::RecordAppLaunchType(
4012 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT);
[email protected]46fd1ea42011-02-16 15:59:334013 }
[email protected]03bb953d2010-09-14 21:38:304014}
4015
[email protected]33b8b8e2011-03-15 14:51:554016void Browser::SetSuggestedText(const string16& text,
4017 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:364018 if (window()->GetLocationBar())
4019 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:304020}
4021
[email protected]6b723f82010-10-05 20:14:274022gfx::Rect Browser::GetInstantBounds() {
4023 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:474024}
4025
[email protected]09c69432012-03-16 16:23:284026void Browser::InstantPreviewFocused() {
4027 // NOTE: This is only invoked on aura.
4028 window_->WebContentsFocused(instant_->GetPreviewContents()->web_contents());
4029}
4030
[email protected]3d61dd02012-06-07 00:05:534031TabContents* Browser::GetInstantHostTabContents() const {
4032 return GetActiveTabContents();
[email protected]05cf2fa2012-05-29 20:36:064033}
4034
[email protected]9800de5e2011-03-11 18:19:494035///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574036// Browser, Command and state updating (private):
4037
[email protected]92655362012-04-20 21:33:174038bool Browser::IsShowingMainUI(bool is_fullscreen) {
4039#if !defined(OS_MACOSX)
4040 return is_type_tabbed() && !is_fullscreen;
4041#else
4042 return is_type_tabbed();
4043#endif
4044}
4045
[email protected]36b6dcb2008-11-12 01:19:574046void Browser::InitCommandState() {
4047 // All browser commands whose state isn't set automagically some other way
4048 // (like Back & Forward with initial page load) must have their state
4049 // initialized here, otherwise they will be forever disabled.
4050
[email protected]84214982008-12-10 18:49:104051 // Navigation commands
[email protected]1fc025202009-01-20 23:03:144052 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:164053 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:104054
4055 // Window management commands
[email protected]1fc025202009-01-20 23:03:144056 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
4057 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
4058 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
4059 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:134060 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:144061 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]cdc05ec2011-05-18 15:15:594062 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:104063
4064 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:514065 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:144066 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
4067 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
4068 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
4069 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
4070 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
4071 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
4072 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
4073 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
4074 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
4075 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
4076 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
4077 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
4078 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
4079 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
4080 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
4081 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
4082 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
4083 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
4084 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
4085 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
4086 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
4087 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
4088 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
4089 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
4090 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
4091 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
4092 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
4093 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
4094 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
4095 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
4096 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
4097 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
4098 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
4099 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
4100 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:004101 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:144102 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
4103 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:104104
[email protected]63b02932009-06-05 09:40:514105 // Zoom
4106 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
4107 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
4108 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
4109 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
4110
[email protected]84214982008-12-10 18:49:104111 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:044112 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:144113 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:134114 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:144115 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:144116 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]1fc025202009-01-20 23:03:144117 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
4118 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]d6852fd2011-05-20 17:19:124119 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:294120
[email protected]a038159b2011-08-18 02:55:364121 command_updater_.UpdateCommandEnabled(
4122 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]c8b59f92010-05-28 21:45:474123
[email protected]64ff7942008-12-17 18:11:234124 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:144125 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:234126
[email protected]11f4857282009-11-13 19:56:174127 // Navigation commands
4128 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:234129
[email protected]11f4857282009-11-13 19:56:174130 // Window management commands
[email protected]d3766932011-08-04 22:18:234131 // TODO(rohitrao): Disable fullscreen on non-Lion?
[email protected]cf299bc2010-08-12 20:27:094132 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:144133 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:174134 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
4135 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
4136 normal_window);
4137 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
4138 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
4139 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
4140 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
4141 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
4142 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
4143 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
4144 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
4145 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
4146 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
4147 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:554148#if defined(OS_MACOSX)
4149 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
[email protected]d3766932011-08-04 22:18:234150 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
4151 !(is_type_panel() && is_app()));
[email protected]c1d0d812010-07-27 20:21:554152#endif
[email protected]e662ade2009-06-08 18:20:144153
[email protected]fc33e9992010-04-08 19:40:134154 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:144155 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134156
4157 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:144158 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
4159 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
4160 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134161
[email protected]11f4857282009-11-13 19:56:174162 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:134163 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:004164
[email protected]c1bbaa82010-11-08 11:17:054165 // The upgrade entry and the view incompatibility entry should always be
4166 // enabled. Whether they are visible is a separate matter determined on menu
4167 // show.
[email protected]b21d6912010-08-31 19:22:414168 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:054169 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:414170
[email protected]b569c112010-11-22 20:53:444171 // View Background Pages entry is always enabled, but is hidden if there are
4172 // no background pages.
4173 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
4174
[email protected]afcb43562011-09-02 23:33:384175 // Toggle speech input
4176 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
4177
[email protected]9282cea2009-02-18 18:49:004178 // Initialize other commands whose state changes based on fullscreen mode.
4179 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:004180
4181 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584182
4183 UpdateCommandsForBookmarkEditing();
[email protected]93ad8e1c2011-11-08 21:34:054184
4185 UpdateCommandsForIncognitoAvailability();
4186}
4187
[email protected]93ad8e1c2011-11-08 21:34:054188void Browser::UpdateCommandsForIncognitoAvailability() {
4189 IncognitoModePrefs::Availability incognito_availability =
4190 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
4191 command_updater_.UpdateCommandEnabled(
4192 IDC_NEW_WINDOW,
4193 incognito_availability != IncognitoModePrefs::FORCED);
4194 command_updater_.UpdateCommandEnabled(
4195 IDC_NEW_INCOGNITO_WINDOW,
4196 incognito_availability != IncognitoModePrefs::DISABLED);
4197
4198 // Bookmark manager and settings page/subpages are forced to open in normal
4199 // mode. For this reason we disable these commands when incognito is forced.
4200 const bool command_enabled =
4201 incognito_availability != IncognitoModePrefs::FORCED;
4202 command_updater_.UpdateCommandEnabled(
4203 IDC_SHOW_BOOKMARK_MANAGER,
4204 browser_defaults::bookmarks_enabled && command_enabled);
4205 ExtensionService* extension_service = profile()->GetExtensionService();
4206 bool enable_extensions =
4207 extension_service && extension_service->extensions_enabled();
4208 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
4209 enable_extensions && command_enabled);
4210
4211 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4212 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
4213 show_main_ui && command_enabled);
4214 command_updater_.UpdateCommandEnabled(IDC_OPTIONS,
4215 show_main_ui && command_enabled);
[email protected]36b6dcb2008-11-12 01:19:574216}
4217
[email protected]84214982008-12-10 18:49:104218void Browser::UpdateCommandsForTabState() {
[email protected]3d61dd02012-06-07 00:05:534219 TabContents* current_tab_contents = GetActiveTabContents();
4220 if (!current_tab_contents) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:394221 return;
[email protected]3d61dd02012-06-07 00:05:534222 WebContents* current_web_contents = current_tab_contents->web_contents();
[email protected]d8375fd2008-11-25 22:45:394223
[email protected]84214982008-12-10 18:49:104224 // Navigation commands
[email protected]3d61dd02012-06-07 00:05:534225 NavigationController& nc = current_web_contents->GetController();
[email protected]ce3fa3c2009-04-20 19:55:574226 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
4227 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]3d61dd02012-06-07 00:05:534228 command_updater_.UpdateCommandEnabled(
4229 IDC_RELOAD, CanReloadContents(current_web_contents));
4230 command_updater_.UpdateCommandEnabled(
4231 IDC_RELOAD_IGNORING_CACHE, CanReloadContents(current_web_contents));
initial.commit09911bf2008-07-26 23:55:294232
[email protected]84214982008-12-10 18:49:104233 // Window management commands
[email protected]1fc025202009-01-20 23:03:144234 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:144235 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:104236
[email protected]57c6a652009-05-04 07:58:344237 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:384238 window_->SetStarredState(
[email protected]3d61dd02012-06-07 00:05:534239 current_tab_contents->bookmark_tab_helper()->is_starred());
[email protected]6f80e932012-06-04 19:00:074240 window_->SetZoomIconState(
[email protected]3d61dd02012-06-07 00:05:534241 current_tab_contents->zoom_controller()->zoom_icon_state());
[email protected]6f80e932012-06-04 19:00:074242 window_->SetZoomIconTooltipPercent(
[email protected]3d61dd02012-06-07 00:05:534243 current_tab_contents->zoom_controller()->zoom_percent());
[email protected]57c6a652009-05-04 07:58:344244 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]3d61dd02012-06-07 00:05:534245 current_web_contents->GetController().CanViewSource());
[email protected]151666e2010-10-21 17:05:254246 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
[email protected]3d61dd02012-06-07 00:05:534247 toolbar_model_->ShouldDisplayURL() &&
4248 current_web_contents->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:404249 if (is_devtools())
4250 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:254251
4252 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]e397a4472011-12-21 21:47:504253 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
[email protected]3d61dd02012-06-07 00:05:534254 current_web_contents->ShowingInterstitialPage();
[email protected]c0f82ec52010-07-27 14:22:144255 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
[email protected]3d61dd02012-06-07 00:05:534256 !is_chrome_internal && current_web_contents->IsSavable());
[email protected]c0f82ec52010-07-27 14:22:144257
[email protected]57c6a652009-05-04 07:58:344258 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254259 // TODO(pinkerton): Disable app-mode in the model until we implement it
4260 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4261#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344262 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]3d61dd02012-06-07 00:05:534263 web_app::IsValidUrl(current_web_contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254264#endif
[email protected]9e823662010-10-13 23:36:004265
4266 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584267 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004268}
4269
4270void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374271 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004272
4273 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184274 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
[email protected]9e823662010-10-13 23:36:004275 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184276 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
[email protected]9e823662010-10-13 23:36:004277 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184278 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044279 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004280 UpdatePrintingState(restrictions);
4281}
4282
[email protected]543432ee2010-10-22 16:32:134283void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044284 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424285 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134286 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4287 dev_tools_enabled);
4288 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4289 dev_tools_enabled);
4290 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4291 dev_tools_enabled);
4292}
4293
[email protected]a13f47d12011-04-14 11:41:584294void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044295 bool enabled =
4296 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4297 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584298
4299 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144300 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584301 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4302 enabled && CanBookmarkAllTabs());
[email protected]6ec11922012-06-07 03:55:124303 command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN,
4304 true);
[email protected]a13f47d12011-04-14 11:41:584305}
4306
[email protected]a007e732011-08-05 13:32:194307void Browser::UpdateCommandsForBookmarkBar() {
[email protected]93ad8e1c2011-11-08 21:34:054308 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
[email protected]a007e732011-08-05 13:32:194309 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
4310 browser_defaults::bookmarks_enabled &&
[email protected]3710d0002011-10-11 00:35:004311 !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
[email protected]a007e732011-08-05 13:32:194312 show_main_ui);
4313}
4314
[email protected]6c6b02d2011-09-02 03:36:474315void Browser::MarkHomePageAsChanged(PrefService* pref_service) {
4316 pref_service->SetBoolean(prefs::kHomePageChanged, true);
[email protected]6c6b02d2011-09-02 03:36:474317}
4318
[email protected]92655362012-04-20 21:33:174319void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
4320 const bool show_main_ui = IsShowingMainUI(is_fullscreen);
4321 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
4322
4323 // Navigation commands
4324 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
4325
4326 // Window management commands
4327 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
4328 type_ != TYPE_TABBED && !is_fullscreen);
4329
4330 // Focus various bits of UI
4331 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
4332 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
4333 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
4334 command_updater_.UpdateCommandEnabled(
4335 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
4336 command_updater_.UpdateCommandEnabled(
4337 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
4338 command_updater_.UpdateCommandEnabled(
4339 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
4340 command_updater_.UpdateCommandEnabled(
4341 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
4342
4343 // Show various bits of UI
4344 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
4345 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
4346 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
4347 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
4348
4349 // Settings page/subpages are forced to open in normal mode. We disable these
4350 // commands when incognito is forced.
4351 const bool options_enabled = show_main_ui &&
4352 IncognitoModePrefs::GetAvailability(
4353 profile_->GetPrefs()) != IncognitoModePrefs::FORCED;
4354 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
4355 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
4356
4357 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
4358 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
4359 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
4360 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]92655362012-04-20 21:33:174361#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
4362 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
4363#endif
4364
4365 UpdateCommandsForBookmarkBar();
[email protected]623294c42012-04-27 18:27:144366 UpdateCommandsForMultipleProfiles();
4367}
4368
4369void Browser::UpdateCommandsForMultipleProfiles() {
4370 bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4371 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
4372 show_main_ui &&
4373 !profile()->IsOffTheRecord() &&
4374 ProfileManager::IsMultipleProfilesEnabled());
[email protected]92655362012-04-20 21:33:174375}
4376
4377void Browser::UpdatePrintingState(int content_restrictions) {
4378 bool print_enabled = true;
4379 bool advanced_print_enabled = true;
4380 if (g_browser_process->local_state()) {
4381 print_enabled =
4382 g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled);
4383 advanced_print_enabled = print_enabled;
4384 }
4385 if (print_enabled) {
4386 // Do not print when a constrained window is showing. It's confusing.
[email protected]3d61dd02012-06-07 00:05:534387 TabContents* tab_contents = GetActiveTabContents();
4388 bool has_constrained_window =
4389 tab_contents &&
4390 tab_contents->constrained_window_tab_helper()->
4391 constrained_window_count();
[email protected]92655362012-04-20 21:33:174392 if (has_constrained_window ||
4393 content_restrictions & content::CONTENT_RESTRICTION_PRINT) {
4394 print_enabled = false;
4395 advanced_print_enabled = false;
4396 }
4397
4398 // The exception is print preview,
4399 // where advanced printing is always enabled.
4400 printing::PrintPreviewTabController* controller =
4401 printing::PrintPreviewTabController::GetInstance();
[email protected]3d61dd02012-06-07 00:05:534402 if (controller && (controller->GetPrintPreviewForTab(tab_contents) ||
[email protected]92655362012-04-20 21:33:174403 controller->is_creating_print_preview_tab())) {
4404 advanced_print_enabled = true;
4405 }
4406 }
4407 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
4408 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
4409 advanced_print_enabled);
4410}
4411
[email protected]97b46382011-05-02 13:23:044412void Browser::UpdateSaveAsState(int content_restrictions) {
[email protected]4573fbd2011-10-31 20:25:184413 bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE);
[email protected]97b46382011-05-02 13:23:044414 PrefService* state = g_browser_process->local_state();
4415 if (state)
4416 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4417
4418 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4419}
4420
4421void Browser::UpdateOpenFileState() {
4422 bool enabled = true;
4423 PrefService* local_state = g_browser_process->local_state();
4424 if (local_state)
4425 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4426
4427 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4428}
4429
[email protected]92655362012-04-20 21:33:174430void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4431 window_->UpdateReloadStopState(is_loading, force);
4432 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
4433}
4434
[email protected]36b6dcb2008-11-12 01:19:574435///////////////////////////////////////////////////////////////////////////////
4436// Browser, UI update coalescing and handling (private):
4437
4438void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3d61dd02012-06-07 00:05:534439 window_->UpdateToolbar(GetActiveTabContents(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294440}
4441
[email protected]2a6bc3e2011-12-28 23:51:334442void Browser::ScheduleUIUpdate(const WebContents* source,
[email protected]36b6dcb2008-11-12 01:19:574443 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004444 if (!source)
4445 return;
4446
[email protected]2b4355c2009-04-04 17:55:464447 // Do some synchronous updates.
[email protected]d9083482012-01-06 00:38:464448 if (changed_flags & content::INVALIDATE_TYPE_URL &&
[email protected]3d61dd02012-06-07 00:05:534449 source == GetActiveWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:574450 // Only update the URL for the current tab. Note that we do not update
4451 // the navigation commands since those would have already been updated
4452 // synchronously by NavigationStateChanged.
4453 UpdateToolbar(false);
[email protected]d9083482012-01-06 00:38:464454 changed_flags &= ~content::INVALIDATE_TYPE_URL;
[email protected]36b6dcb2008-11-12 01:19:574455 }
[email protected]d9083482012-01-06 00:38:464456 if (changed_flags & content::INVALIDATE_TYPE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574457 // Update the loading state synchronously. This is so the throbber will
4458 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004459 // this for any tab so they start & stop quickly.
[email protected]2fc15ae2012-05-06 00:01:374460 tab_strip_model_->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:404461 GetIndexOfController(&source->GetController()),
[email protected]6ebdc9b2010-09-27 16:55:574462 TabStripModelObserver::LOADING_ONLY);
[email protected]d9083482012-01-06 00:38:464463 // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too,
4464 // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from
[email protected]6ebdc9b2010-09-27 16:55:574465 // changed_flags.
[email protected]8030f012009-09-25 18:09:374466 }
4467
[email protected]d9083482012-01-06 00:38:464468 if (changed_flags & content::INVALIDATE_TYPE_TITLE && !source->IsLoading()) {
[email protected]f1cd5e82009-10-23 17:19:034469 // To correctly calculate whether the title changed while not loading
4470 // we need to process the update synchronously. This state only matters for
4471 // the TabStripModel, so we notify the TabStripModel now and notify others
4472 // asynchronously.
[email protected]2fc15ae2012-05-06 00:01:374473 tab_strip_model_->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:404474 GetIndexOfController(&source->GetController()),
[email protected]f1cd5e82009-10-23 17:19:034475 TabStripModelObserver::TITLE_NOT_LOADING);
4476 }
4477
[email protected]2b4355c2009-04-04 17:55:464478 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374479 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464480 return;
[email protected]36b6dcb2008-11-12 01:19:574481
4482 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404483 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574484
[email protected]24f1477532011-11-22 22:55:364485 if (!chrome_updater_factory_.HasWeakPtrs()) {
[email protected]36b6dcb2008-11-12 01:19:574486 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374487 MessageLoop::current()->PostDelayedTask(
4488 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:364489 base::Bind(&Browser::ProcessPendingUIUpdates,
4490 chrome_updater_factory_.GetWeakPtr()),
[email protected]11d6ab1a2012-01-12 21:37:264491 base::TimeDelta::FromMilliseconds(kUIUpdateCoalescingTimeMS));
[email protected]36b6dcb2008-11-12 01:19:574492 }
4493}
4494
4495void Browser::ProcessPendingUIUpdates() {
4496#ifndef NDEBUG
4497 // Validate that all tabs we have pending updates for exist. This is scary
4498 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004499 // deleted tabs.
[email protected]85354982009-09-25 19:58:404500 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4501 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574502 bool found = false;
4503 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]6acde6352012-01-04 16:52:204504 if (GetWebContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574505 found = true;
4506 break;
4507 }
4508 }
4509 DCHECK(found);
4510 }
4511#endif
4512
[email protected]24f1477532011-11-22 22:55:364513 chrome_updater_factory_.InvalidateWeakPtrs();
[email protected]36b6dcb2008-11-12 01:19:574514
[email protected]85354982009-09-25 19:58:404515 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4516 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574517 // Do not dereference |contents|, it may be out-of-date!
[email protected]2a6bc3e2011-12-28 23:51:334518 const WebContents* contents = i->first;
[email protected]85354982009-09-25 19:58:404519 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574520
[email protected]3d61dd02012-06-07 00:05:534521 if (contents == GetActiveWebContents()) {
[email protected]a5231662009-09-26 00:56:004522 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344523
[email protected]d9083482012-01-06 00:38:464524 if (flags & content::INVALIDATE_TYPE_PAGE_ACTIONS) {
[email protected]9800de5e2011-03-11 18:19:494525 LocationBar* location_bar = window()->GetLocationBar();
4526 if (location_bar)
4527 location_bar->UpdatePageActions();
4528 }
[email protected]6ebdc9b2010-09-27 16:55:574529 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]d9083482012-01-06 00:38:464530 if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:444531 GetStatusBubble()->SetStatus(
[email protected]3d61dd02012-06-07 00:05:534532 GetActiveTabContents()->
[email protected]51d83bdf2011-12-09 16:09:294533 core_tab_helper()->GetStatusText());
[email protected]0dd3a0ab2011-02-18 08:17:444534 }
[email protected]a5231662009-09-26 00:56:004535
[email protected]d9083482012-01-06 00:38:464536 if (flags & (content::INVALIDATE_TYPE_TAB |
4537 content::INVALIDATE_TYPE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254538// TODO(pinkerton): Disable app-mode in the model until we implement it
4539// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4540#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004541 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234542 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254543#endif
[email protected]a5231662009-09-26 00:56:004544 window_->UpdateTitleBar();
4545 }
[email protected]4d34e2e2009-05-26 22:55:284546 }
[email protected]36b6dcb2008-11-12 01:19:574547
[email protected]a5231662009-09-26 00:56:004548 // Updates that don't depend upon the selected state go here.
[email protected]d9083482012-01-06 00:38:464549 if (flags &
4550 (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
[email protected]2fc15ae2012-05-06 00:01:374551 tab_strip_model_->UpdateTabContentsStateAt(
4552 tab_strip_model_->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034553 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574554 }
4555
4556 // We don't need to process INVALIDATE_STATE, since that's not visible.
4557 }
4558
4559 scheduled_updates_.clear();
4560}
4561
[email protected]d9083482012-01-06 00:38:464562void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
[email protected]36b6dcb2008-11-12 01:19:574563 if (!contents)
4564 return;
4565
[email protected]85354982009-09-25 19:58:404566 UpdateMap::iterator i = scheduled_updates_.find(contents);
4567 if (i != scheduled_updates_.end())
4568 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294569}
4570
[email protected]d938aed92009-01-22 19:49:334571
[email protected]36b6dcb2008-11-12 01:19:574572///////////////////////////////////////////////////////////////////////////////
4573// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294574
[email protected]36b6dcb2008-11-12 01:19:574575StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094576#if !defined(OS_MACOSX)
4577 // In kiosk mode, we want to always hide the status bubble.
4578 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4579 return NULL;
4580#endif
[email protected]9b032bf2009-07-21 17:34:234581 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294582}
4583
[email protected]36b6dcb2008-11-12 01:19:574584///////////////////////////////////////////////////////////////////////////////
4585// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294586
4587void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154588 SessionService* session_service =
4589 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294590 if (session_service) {
4591 for (int i = index; i < tab_count(); ++i) {
[email protected]3d61dd02012-06-07 00:05:534592 TabContents* tab = GetTabContentsAt(i);
[email protected]81898992011-06-14 22:15:004593 if (tab) {
initial.commit09911bf2008-07-26 23:55:294594 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:004595 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404596 session_service->SetPinnedState(
4597 session_id(),
[email protected]81898992011-06-14 22:15:004598 tab->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:404599 IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294600 }
4601 }
4602 }
4603}
4604
[email protected]36b6dcb2008-11-12 01:19:574605///////////////////////////////////////////////////////////////////////////////
4606// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294607
[email protected]04b4a6c2008-08-02 00:44:474608void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214609 if (!is_attempting_to_close_browser_) {
4610 // Because we might invoke this after a delay it's possible for the value of
4611 // is_attempting_to_close_browser_ to have changed since we scheduled the
4612 // task.
4613 return;
4614 }
initial.commit09911bf2008-07-26 23:55:294615
[email protected]04b4a6c2008-08-02 00:44:474616 if (HasCompletedUnloadProcessing()) {
4617 // We've finished all the unload events and can proceed to close the
4618 // browser.
4619 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294620 return;
4621 }
4622
[email protected]04b4a6c2008-08-02 00:44:474623 // Process beforeunload tabs first. When that queue is empty, process
4624 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474625 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]a81343d232011-12-27 07:39:204626 WebContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244627 // Null check render_view_host here as this gets called on a PostTask and
4628 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524629 if (tab->GetRenderViewHost()) {
4630 tab->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244631 } else {
[email protected]08f0d612011-01-13 23:58:214632 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244633 }
[email protected]04b4a6c2008-08-02 00:44:474634 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294635 // We've finished firing all beforeunload events and can proceed with unload
4636 // events.
4637 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4638 // somewhere around here so that we have accurate measurements of shutdown
4639 // time.
[email protected]04b4a6c2008-08-02 00:44:474640 // TODO(ojan): We can probably fire all the unload events in parallel and
4641 // get a perf benefit from that in the cases where the tab hangs in it's
4642 // unload handler or takes a long time to page in.
[email protected]a81343d232011-12-27 07:39:204643 WebContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244644 // Null check render_view_host here as this gets called on a PostTask and
4645 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524646 if (tab->GetRenderViewHost()) {
4647 tab->GetRenderViewHost()->ClosePage();
[email protected]22484622009-06-10 21:17:244648 } else {
[email protected]08f0d612011-01-13 23:58:214649 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244650 }
initial.commit09911bf2008-07-26 23:55:294651 } else {
[email protected]04b4a6c2008-08-02 00:44:474652 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294653 }
4654}
4655
[email protected]d043c2cc2009-03-25 18:30:454656bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474657 return is_attempting_to_close_browser_ &&
4658 tabs_needing_before_unload_fired_.empty() &&
4659 tabs_needing_unload_fired_.empty();
4660}
4661
4662void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044663 // Closing of window can be canceled from:
4664 // - canceling beforeunload
4665 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474666 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284667 tabs_needing_before_unload_fired_.clear();
4668 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474669 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044670
[email protected]9cc821652012-04-18 18:18:104671 content::NotificationService::current()->Notify(
4672 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
4673 content::Source<Browser>(this),
4674 content::NotificationService::NoDetails());
4675
[email protected]0b4d3382010-07-14 16:13:044676 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4677 TabCloseableStateWatcher* watcher =
4678 g_browser_process->tab_closeable_state_watcher();
4679 if (watcher)
4680 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474681}
4682
[email protected]a81343d232011-12-27 07:39:204683bool Browser::RemoveFromSet(UnloadListenerSet* set, WebContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474684 DCHECK(is_attempting_to_close_browser_);
4685
[email protected]06b42f032008-12-03 18:43:054686 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4687 if (iter != set->end()) {
4688 set->erase(iter);
4689 return true;
[email protected]04b4a6c2008-08-02 00:44:474690 }
4691 return false;
4692}
initial.commit09911bf2008-07-26 23:55:294693
[email protected]a81343d232011-12-27 07:39:204694void Browser::ClearUnloadState(WebContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044695 // Closing of browser could be canceled (via IsClosingPermitted) between the
4696 // time when request was initiated and when this method is called, so check
4697 // for is_attempting_to_close_browser_ flag before proceeding.
4698 if (is_attempting_to_close_browser_) {
4699 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4700 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:214701 if (process_now) {
4702 ProcessPendingTabs();
4703 } else {
4704 MessageLoop::current()->PostTask(
4705 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:364706 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr()));
[email protected]08f0d612011-01-13 23:58:214707 }
[email protected]0b4d3382010-07-14 16:13:044708 }
initial.commit09911bf2008-07-26 23:55:294709}
4710
[email protected]36b6dcb2008-11-12 01:19:574711///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:064712// Browser, In-progress download termination handling (private):
4713
[email protected]b6a4ac2b2011-10-17 20:05:484714bool Browser::CanCloseWithInProgressDownloads() {
[email protected]5a17d492011-10-24 19:37:034715 // If we've prompted, we need to hear from the user before we
4716 // can close.
4717 if (cancel_download_confirmation_state_ != NOT_PROMPTED)
4718 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
4719
4720 int num_downloads_blocking;
4721 if (DOWNLOAD_CLOSE_OK ==
4722 OkToCloseWithInProgressDownloads(&num_downloads_blocking))
[email protected]446295a2010-04-19 23:43:004723 return true;
4724
[email protected]5a17d492011-10-24 19:37:034725 // Closing this window will kill some downloads; prompt to make sure
4726 // that's ok.
[email protected]69444cc2009-04-09 20:40:064727 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4728 window_->ConfirmBrowserCloseWithPendingDownloads();
4729
4730 // Return false so the browser does not close. We'll close if the user
4731 // confirms in the dialog.
4732 return false;
4733}
4734
4735///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574736// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:294737
[email protected]3d61dd02012-06-07 00:05:534738void Browser::SetAsDelegate(TabContents* tab, Browser* delegate) {
[email protected]075969d2012-04-17 20:05:554739 // WebContents...
[email protected]d9083482012-01-06 00:38:464740 tab->web_contents()->SetDelegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:374741
4742 // ...and all the helpers.
4743 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:144744 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]6f80e932012-06-04 19:00:074745 tab->zoom_controller()->set_observer(delegate);
[email protected]31145092011-09-30 01:49:444746 tab->constrained_window_tab_helper()->set_delegate(delegate);
[email protected]51d83bdf2011-12-09 16:09:294747 tab->core_tab_helper()->set_delegate(delegate);
[email protected]1739e57d2011-11-30 21:18:254748 tab->extension_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:124749 tab->search_engine_tab_helper()->set_delegate(delegate);
4750}
4751
[email protected]4f3dc372009-02-24 00:10:294752void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:584753 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:294754 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:004755 string16 find_text;
4756#if defined(OS_MACOSX)
4757 // We always want to search for the contents of the find pasteboard on OS X.
4758 find_text = GetFindPboardText();
4759#endif
[email protected]3d61dd02012-06-07 00:05:534760 GetActiveTabContents()->
[email protected]c90c6ca2011-02-16 20:11:384761 find_tab_helper()->StartFinding(find_text,
4762 forward_direction,
4763 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:294764 }
[email protected]fbd77592008-11-12 20:50:274765}
[email protected]cb17f7f2009-02-06 18:14:484766
[email protected]36b6dcb2008-11-12 01:19:574767void Browser::CloseFrame() {
4768 window_->Close();
initial.commit09911bf2008-07-26 23:55:294769}
4770
[email protected]3d61dd02012-06-07 00:05:534771void Browser::TabDetachedAtImpl(TabContents* contents, int index,
[email protected]c37e3b62010-01-22 00:15:174772 DetachType type) {
4773 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:154774 // Save the current location bar state, but only if the tab being detached
4775 // is the selected tab. Because saving state can conditionally revert the
4776 // location bar, saving the current tab's location bar state to a
4777 // non-selected tab can corrupt both tabs.
[email protected]3d61dd02012-06-07 00:05:534778 if (contents == GetActiveTabContents()) {
[email protected]9800de5e2011-03-11 18:19:494779 LocationBar* location_bar = window()->GetLocationBar();
4780 if (location_bar)
[email protected]83a2610a2012-01-05 01:00:274781 location_bar->SaveStateToContents(contents->web_contents());
[email protected]9800de5e2011-03-11 18:19:494782 }
[email protected]c37e3b62010-01-22 00:15:174783
[email protected]2fc15ae2012-05-06 00:01:374784 if (!tab_strip_model_->closing_all())
[email protected]c37e3b62010-01-22 00:15:174785 SyncHistoryWithTabs(0);
4786 }
4787
[email protected]9219d262011-02-15 21:05:124788 SetAsDelegate(contents, NULL);
[email protected]d9083482012-01-06 00:38:464789 RemoveScheduledUpdatesFor(contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:174790
[email protected]41f022e2012-01-31 05:56:404791 if (find_bar_controller_.get() && index == active_index()) {
[email protected]c37e3b62010-01-22 00:15:174792 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:404793 }
[email protected]c37e3b62010-01-22 00:15:174794
[email protected]08f0d612011-01-13 23:58:214795 if (is_attempting_to_close_browser_) {
4796 // If this is the last tab with unload handlers, then ProcessPendingTabs
4797 // would call back into the TabStripModel (which is invoking this method on
4798 // us). Avoid that by passing in false so that the call to
4799 // ProcessPendingTabs is delayed.
[email protected]d9083482012-01-06 00:38:464800 ClearUnloadState(contents->web_contents(), false);
[email protected]08f0d612011-01-13 23:58:214801 }
4802
[email protected]432115822011-07-10 15:52:274803 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:324804 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:504805 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]4b19ea52012-01-02 20:15:254806 content::Source<WebContents>(contents->web_contents()));
[email protected]fbc5e5f92012-01-02 06:08:324807 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
4808 content::Source<WebContents>(contents->web_contents()));
[email protected]c37e3b62010-01-22 00:15:174809}
4810
initial.commit09911bf2008-07-26 23:55:294811// static
[email protected]f87919d72011-02-02 18:46:164812void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:294813 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:514814 std::string window_pref(prefs::kBrowserWindowPlacement);
4815 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:294816 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:144817 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:164818 if (!prefs->FindPreference(window_pref.c_str())) {
4819 prefs->RegisterDictionaryPref(window_pref.c_str(),
4820 PrefService::UNSYNCABLE_PREF);
4821 }
initial.commit09911bf2008-07-26 23:55:294822}
[email protected]5c238752009-06-13 10:29:074823
[email protected]92655362012-04-20 21:33:174824void Browser::ReloadInternal(WindowOpenDisposition disposition,
4825 bool ignore_cache) {
4826 // If we are showing an interstitial, treat this as an OpenURL.
[email protected]3d61dd02012-06-07 00:05:534827 WebContents* current_tab = GetActiveWebContents();
[email protected]92655362012-04-20 21:33:174828 if (current_tab && current_tab->ShowingInterstitialPage()) {
4829 NavigationEntry* entry = current_tab->GetController().GetActiveEntry();
4830 DCHECK(entry); // Should exist if interstitial is showing.
4831 OpenURL(OpenURLParams(
4832 entry->GetURL(), Referrer(), disposition,
4833 content::PAGE_TRANSITION_RELOAD, false));
[email protected]281918912010-05-27 22:05:134834 return;
[email protected]92655362012-04-20 21:33:174835 }
[email protected]281918912010-05-27 22:05:134836
[email protected]92655362012-04-20 21:33:174837 // As this is caused by a user action, give the focus to the page.
4838 //
4839 // Also notify RenderViewHostDelegate of the user gesture; this is
4840 // normally done in Browser::Navigate, but a reload bypasses Navigate.
4841 WebContents* tab = GetOrCloneTabForDisposition(disposition);
[email protected]e35ccd552012-05-23 16:22:474842 tab->UserGestureDone();
[email protected]92655362012-04-20 21:33:174843 if (!tab->FocusLocationBarByDefault())
4844 tab->Focus();
4845 if (ignore_cache)
4846 tab->GetController().ReloadIgnoringCache(true);
4847 else
4848 tab->GetController().Reload(true);
[email protected]281918912010-05-27 22:05:134849}
[email protected]97b6c4f2010-09-27 19:31:264850
[email protected]92655362012-04-20 21:33:174851WebContents* Browser::GetOrCloneTabForDisposition(
4852 WindowOpenDisposition disposition) {
[email protected]3d61dd02012-06-07 00:05:534853 TabContents* current_tab = GetActiveTabContents();
[email protected]92655362012-04-20 21:33:174854 switch (disposition) {
4855 case NEW_FOREGROUND_TAB:
4856 case NEW_BACKGROUND_TAB: {
4857 current_tab = current_tab->Clone();
[email protected]2fc15ae2012-05-06 00:01:374858 tab_strip_model_->AddTabContents(
[email protected]92655362012-04-20 21:33:174859 current_tab, -1, content::PAGE_TRANSITION_LINK,
4860 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
4861 TabStripModel::ADD_NONE);
4862 break;
4863 }
4864 case NEW_WINDOW: {
4865 current_tab = current_tab->Clone();
4866 Browser* browser = Browser::Create(profile_);
[email protected]c0849252012-05-12 13:51:274867 browser->tab_strip_model()->AddTabContents(
[email protected]92655362012-04-20 21:33:174868 current_tab, -1, content::PAGE_TRANSITION_LINK,
4869 TabStripModel::ADD_ACTIVE);
4870 browser->window()->Show();
4871 break;
4872 }
4873 default:
4874 break;
4875 }
4876 return current_tab->web_contents();
4877}
4878
4879bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
4880 bool check_fullscreen) const {
4881 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
4882 // other platforms, we hide some controls when in fullscreen mode.
4883 bool hide_ui_for_fullscreen = false;
4884#if !defined(OS_MACOSX)
4885 hide_ui_for_fullscreen = check_fullscreen && window_ &&
4886 window_->IsFullscreen();
4887#endif
4888
4889 unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF;
4890
4891 if (is_type_tabbed())
4892 features |= FEATURE_BOOKMARKBAR;
4893
4894 if (!hide_ui_for_fullscreen) {
4895 if (!is_type_tabbed())
4896 features |= FEATURE_TITLEBAR;
4897
4898 if (is_type_tabbed())
4899 features |= FEATURE_TABSTRIP;
4900
4901 if (is_type_tabbed())
4902 features |= FEATURE_TOOLBAR;
4903
4904 if (!is_app())
4905 features |= FEATURE_LOCATIONBAR;
4906 }
4907 return !!(features & feature);
4908}
4909
4910bool Browser::IsClosingPermitted() {
4911 TabCloseableStateWatcher* watcher =
4912 g_browser_process->tab_closeable_state_watcher();
4913 bool can_close = !watcher || watcher->CanCloseBrowser(this);
4914 if (!can_close && is_attempting_to_close_browser_)
4915 CancelWindowClose();
4916 return can_close;
[email protected]3c9e1872010-11-18 16:17:494917}
4918
[email protected]6b723f82010-10-05 20:14:274919bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]3e481282011-10-15 15:39:504920 if (!instant() || !instant()->PrepareForCommit() ||
[email protected]35242602011-01-06 16:38:534921 disposition == NEW_BACKGROUND_TAB) {
4922 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
4923 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:264924 return false;
[email protected]35242602011-01-06 16:38:534925 }
[email protected]97b6c4f2010-09-27 19:31:264926
4927 if (disposition == CURRENT_TAB) {
[email protected]ad50def52011-10-19 23:17:074928 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:274929 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]3d61dd02012-06-07 00:05:534930 content::Source<TabContents>(instant()->CommitCurrentPreview(
[email protected]094b0522011-10-06 00:55:274931 INSTANT_COMMIT_PRESSED_ENTER)),
[email protected]ad50def52011-10-19 23:17:074932 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:264933 return true;
4934 }
[email protected]35242602011-01-06 16:38:534935 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3d61dd02012-06-07 00:05:534936 TabContents* preview_contents = instant()->ReleasePreviewContents(
[email protected]5419ff92012-01-06 21:17:154937 INSTANT_COMMIT_PRESSED_ENTER, NULL);
[email protected]a0df03c122011-01-05 00:22:554938 // HideInstant is invoked after release so that InstantController is not
4939 // active when HideInstant asks it for its state.
4940 HideInstant();
[email protected]d9083482012-01-06 00:38:464941 preview_contents->web_contents()->GetController().PruneAllButActive();
[email protected]2fc15ae2012-05-06 00:01:374942 tab_strip_model_->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:264943 preview_contents,
4944 -1,
[email protected]6b723f82010-10-05 20:14:274945 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:414946 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:374947 instant()->CompleteRelease(preview_contents);
[email protected]ad50def52011-10-19 23:17:074948 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:274949 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]3d61dd02012-06-07 00:05:534950 content::Source<TabContents>(preview_contents),
[email protected]ad50def52011-10-19 23:17:074951 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:264952 return true;
4953 }
4954 // The omnibox currently doesn't use other dispositions, so we don't attempt
4955 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
4956 // support for the new disposition.
4957 NOTREACHED();
4958 return false;
4959}
[email protected]2031cf9d2010-10-12 05:05:374960
4961void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:144962 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:374963 !profile()->IsOffTheRecord()) {
[email protected]05cf2fa2012-05-29 20:36:064964 instant_.reset(new InstantController(this, InstantController::INSTANT));
[email protected]5aab5e22010-12-08 22:13:294965 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:374966 }
4967}
[email protected]77d8d622010-12-15 10:30:124968
[email protected]3d61dd02012-06-07 00:05:534969void Browser::ViewSource(TabContents* contents) {
[email protected]932b7a12011-03-09 12:50:274970 DCHECK(contents);
4971
[email protected]10f417c52011-12-28 21:04:234972 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:464973 contents->web_contents()->GetController().GetActiveEntry();
[email protected]932b7a12011-03-09 12:50:274974 if (!active_entry)
4975 return;
4976
[email protected]36fc0392011-12-25 03:59:514977 ViewSource(contents, active_entry->GetURL(), active_entry->GetContentState());
[email protected]932b7a12011-03-09 12:50:274978}
4979
[email protected]3d61dd02012-06-07 00:05:534980void Browser::ViewSource(TabContents* contents,
[email protected]932b7a12011-03-09 12:50:274981 const GURL& url,
4982 const std::string& content_state) {
[email protected]7f6f44c2011-12-14 13:23:384983 content::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:124984 DCHECK(contents);
4985
[email protected]3d61dd02012-06-07 00:05:534986 TabContents* view_source_contents = contents->Clone();
[email protected]d9083482012-01-06 00:38:464987 view_source_contents->web_contents()->GetController().PruneAllButActive();
[email protected]10f417c52011-12-28 21:04:234988 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:464989 view_source_contents->web_contents()->GetController().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:504990 if (!active_entry)
4991 return;
4992
[email protected]932b7a12011-03-09 12:50:274993 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
4994 url.spec());
[email protected]36fc0392011-12-25 03:59:514995 active_entry->SetVirtualURL(view_source_url);
[email protected]1436beff2010-12-16 19:47:044996
[email protected]932b7a12011-03-09 12:50:274997 // Do not restore scroller position.
[email protected]36fc0392011-12-25 03:59:514998 active_entry->SetContentState(
[email protected]932b7a12011-03-09 12:50:274999 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
5000
[email protected]cd3d50d2010-12-18 21:03:295001 // Do not restore title, derive it from the url.
[email protected]36fc0392011-12-25 03:59:515002 active_entry->SetTitle(string16());
[email protected]77d8d622010-12-15 10:30:125003
[email protected]47b309f2010-12-28 17:35:565004 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:125005 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
5006 // If this is a tabbed browser, just create a duplicate tab inside the same
5007 // window next to the tab being duplicated.
[email protected]2fc15ae2012-05-06 00:01:375008 int index = tab_strip_model_->GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:415009 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:565010 TabStripModel::ADD_INHERIT_GROUP;
[email protected]2fc15ae2012-05-06 00:01:375011 tab_strip_model_->InsertTabContentsAt(index + 1, view_source_contents,
5012 add_types);
[email protected]77d8d622010-12-15 10:30:125013 } else {
[email protected]da22aa62012-04-04 18:54:355014 Browser* browser = Browser::CreateWithParams(
5015 Browser::CreateParams(TYPE_TABBED, profile_));
[email protected]77d8d622010-12-15 10:30:125016
5017 // Preserve the size of the original window. The new window has already
5018 // been given an offset by the OS, so we shouldn't copy the old bounds.
5019 BrowserWindow* new_window = browser->window();
5020 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
5021 window()->GetRestoredBounds().size()));
5022
5023 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]075969d2012-04-17 20:05:555024 // WebContents is invisible and won't size it.
[email protected]77d8d622010-12-15 10:30:125025 browser->window()->Show();
5026
5027 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:585028 browser->AddTab(view_source_contents, content::PAGE_TRANSITION_LINK);
[email protected]77d8d622010-12-15 10:30:125029 }
5030
[email protected]92371eb2011-04-28 11:50:155031 SessionService* session_service =
5032 SessionServiceFactory::GetForProfileIfExisting(profile_);
5033 if (session_service)
[email protected]81898992011-06-14 22:15:005034 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:125035}
[email protected]b9163e02011-04-20 16:03:375036
5037int Browser::GetContentRestrictionsForSelectedTab() {
5038 int content_restrictions = 0;
[email protected]3d61dd02012-06-07 00:05:535039 WebContents* current_tab = GetActiveWebContents();
[email protected]b9163e02011-04-20 16:03:375040 if (current_tab) {
[email protected]0bfbf882011-12-22 18:19:275041 content_restrictions = current_tab->GetContentRestrictions();
[email protected]10f417c52011-12-28 21:04:235042 NavigationEntry* active_entry =
[email protected]f5fa20e2011-12-21 22:35:565043 current_tab->GetController().GetActiveEntry();
[email protected]b9163e02011-04-20 16:03:375044 // See comment in UpdateCommandsForTabState about why we call url().
[email protected]a53209b2012-01-20 16:48:165045 if (!download_util::IsSavableURL(
[email protected]36fc0392011-12-25 03:59:515046 active_entry ? active_entry->GetURL() : GURL())
[email protected]0bfbf882011-12-22 18:19:275047 || current_tab->ShowingInterstitialPage())
[email protected]4573fbd2011-10-31 20:25:185048 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
[email protected]0bfbf882011-12-22 18:19:275049 if (current_tab->ShowingInterstitialPage())
[email protected]e397a4472011-12-21 21:47:505050 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
[email protected]b9163e02011-04-20 16:03:375051 }
5052 return content_restrictions;
5053}
[email protected]09b29342011-06-24 19:18:485054
5055void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
5056 BookmarkBar::State state;
[email protected]227393e2011-06-29 21:28:395057 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
[email protected]3710d0002011-10-11 00:35:005058 if (browser_defaults::bookmarks_enabled &&
5059 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
[email protected]227393e2011-06-29 21:28:395060 (!window_ || !window_->IsFullscreen())) {
[email protected]09b29342011-06-24 19:18:485061 state = BookmarkBar::SHOW;
5062 } else {
[email protected]3d61dd02012-06-07 00:05:535063 TabContents* tab = GetActiveTabContents();
[email protected]09b29342011-06-24 19:18:485064 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
5065 state = BookmarkBar::DETACHED;
5066 else
5067 state = BookmarkBar::HIDDEN;
5068 }
5069 if (state == bookmark_bar_state_)
5070 return;
5071
5072 bookmark_bar_state_ = state;
5073
5074 if (!window_)
5075 return; // This is called from the constructor when window_ is NULL.
5076
5077 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
5078 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
5079 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
5080 // end up querying state once they process the tab switch.
5081 return;
5082 }
5083
5084 BookmarkBar::AnimateChangeType animate_type =
5085 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
5086 BookmarkBar::ANIMATE_STATE_CHANGE :
5087 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
5088 window_->BookmarkBarStateChanged(animate_type);
5089}
[email protected]2e2cacc2011-07-12 21:54:265090
[email protected]92655362012-04-20 21:33:175091void Browser::OpenBookmarkManagerWithHash(const std::string& action,
5092 int64 node_id) {
5093 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
5094 content::RecordAction(UserMetricsAction("ShowBookmarks"));
5095 browser::NavigateParams params(GetSingletonTabNavigateParams(
5096 GURL(chrome::kChromeUIBookmarksURL).Resolve(
5097 StringPrintf("/#%s%s", action.c_str(),
5098 base::Int64ToString(node_id).c_str()))));
5099 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
5100 ShowSingletonTabOverwritingNTP(params);
[email protected]2e2cacc2011-07-12 21:54:265101}
[email protected]afcb43562011-09-02 23:33:385102
[email protected]92655362012-04-20 21:33:175103bool Browser::MaybeCreateBackgroundContents(int route_id,
5104 WebContents* opener_web_contents,
5105 const string16& frame_name,
5106 const GURL& target_url) {
5107 GURL opener_url = opener_web_contents->GetURL();
5108 ExtensionService* extensions_service = profile_->GetExtensionService();
5109
5110 if (!opener_url.is_valid() ||
5111 frame_name.empty() ||
5112 !extensions_service ||
5113 !extensions_service->is_ready())
5114 return false;
5115
5116 // Only hosted apps have web extents, so this ensures that only hosted apps
5117 // can create BackgroundContents. We don't have to check for background
5118 // permission as that is checked in RenderMessageFilter when the CreateWindow
5119 // message is processed.
5120 const Extension* extension =
5121 extensions_service->extensions()->GetHostedAppByURL(
5122 ExtensionURLInfo(opener_url));
5123 if (!extension)
5124 return false;
5125
5126 // No BackgroundContents allowed if BackgroundContentsService doesn't exist.
5127 BackgroundContentsService* service =
5128 BackgroundContentsServiceFactory::GetForProfile(profile_);
5129 if (!service)
5130 return false;
5131
5132 // Ensure that we're trying to open this from the extension's process.
5133 SiteInstance* opener_site_instance = opener_web_contents->GetSiteInstance();
5134 extensions::ProcessMap* process_map = extensions_service->process_map();
5135 if (!opener_site_instance->GetProcess() ||
5136 !process_map->Contains(
5137 extension->id(), opener_site_instance->GetProcess()->GetID())) {
5138 return false;
5139 }
5140
5141 // Only allow a single background contents per app.
5142 bool allow_js_access = extension->allow_background_js_access();
5143 BackgroundContents* existing =
5144 service->GetAppBackgroundContents(ASCIIToUTF16(extension->id()));
5145 if (existing) {
5146 // For non-scriptable background contents, ignore the request altogether,
5147 // (returning true, so that a regular WebContents isn't created either).
5148 if (!allow_js_access)
5149 return true;
5150 // For scriptable background pages, if one already exists, close it (even
5151 // if it was specified in the manifest).
5152 DLOG(INFO) << "Closing existing BackgroundContents for " << opener_url;
5153 delete existing;
5154 }
5155
5156 // If script access is not allowed, create the the background contents in a
5157 // new SiteInstance, so that a separate process is used.
5158 scoped_refptr<content::SiteInstance> site_instance =
5159 allow_js_access ?
5160 opener_site_instance :
5161 content::SiteInstance::Create(opener_web_contents->GetBrowserContext());
5162
5163 // Passed all the checks, so this should be created as a BackgroundContents.
5164 BackgroundContents* contents = service->CreateBackgroundContents(
5165 site_instance,
5166 route_id,
5167 profile_,
5168 frame_name,
5169 ASCIIToUTF16(extension->id()));
5170
5171 // When a separate process is used, the original renderer cannot access the
5172 // new window later, thus we need to navigate the window now.
5173 if (contents && !allow_js_access) {
5174 contents->web_contents()->GetController().LoadURL(
5175 target_url,
5176 content::Referrer(),
5177 content::PAGE_TRANSITION_LINK,
5178 std::string()); // No extra headers.
5179 }
5180
5181 return contents != NULL;
[email protected]afcb43562011-09-02 23:33:385182}