blob: 9f2b127dd4c455733b6ef79302ebe07d427c7285 [file] [log] [blame]
[email protected]35d06152011-01-10 22:19:421// Copyright (c) 2011 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]a9afddb2009-02-12 17:49:4232#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5433#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]5c238752009-06-13 10:29:0734#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1835#include "chrome/browser/browser_shutdown.h"
[email protected]40d59ce52009-03-06 23:20:1436#include "chrome/browser/character_encoding.h"
[email protected]0f083402011-11-22 02:59:0137#include "chrome/browser/chrome_page_zoom.h"
[email protected]55c87fa2011-10-15 07:28:2838#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]7d189022011-08-25 22:54:2039#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
40#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
[email protected]dce502762011-07-20 08:53:4941#include "chrome/browser/debugger/devtools_toggle_action.h"
42#include "chrome/browser/debugger/devtools_window.h"
[email protected]8a282712011-08-23 19:28:0043#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]59560e0b2009-06-04 03:30:2244#include "chrome/browser/download/download_item_model.h"
[email protected]9bb54ee2011-10-12 17:43:3545#include "chrome/browser/download/download_service.h"
46#include "chrome/browser/download/download_service_factory.h"
[email protected]59560e0b2009-06-04 03:30:2247#include "chrome/browser/download/download_started_animation.h"
[email protected]bb461532010-11-26 21:50:2348#include "chrome/browser/extensions/crx_installer.h"
[email protected]49098f702011-10-13 03:47:1849#include "chrome/browser/extensions/default_apps_trial.h"
[email protected]9fd542df2009-09-30 07:32:0150#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]0c6da502009-08-14 22:32:3951#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
[email protected]6d7a6042010-08-12 20:12:4252#include "chrome/browser/extensions/extension_host.h"
[email protected]10abd192010-09-30 02:03:4953#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0054#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0855#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5956#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0457#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]3a29a6e2011-08-24 18:26:2158#include "chrome/browser/file_select_helper.h"
[email protected]820735792010-07-29 23:40:0159#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4960#include "chrome/browser/google/google_url_tracker.h"
61#include "chrome/browser/google/google_util.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]95a33ed62011-09-30 15:07:0866#include "chrome/browser/intents/web_intents_registry_factory.h"
[email protected]90f39902009-10-03 04:25:3767#include "chrome/browser/net/browser_url_util.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]d952a052011-09-06 18:42:4573#include "chrome/browser/prerender/prerender_tab_helper.h"
[email protected]02337592010-09-27 18:38:2574#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]0996e9b2011-08-26 17:59:0175#include "chrome/browser/printing/print_preview_tab_controller.h"
[email protected]68761472011-08-31 18:55:1476#include "chrome/browser/printing/print_view_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3377#include "chrome/browser/profiles/profile.h"
[email protected]5a17d492011-10-24 19:37:0378#include "chrome/browser/profiles/profile_manager.h"
[email protected]a7be6982011-12-12 21:53:5779#include "chrome/browser/profiles/profile_metrics.h"
[email protected]67baffc82011-12-19 18:03:0780#include "chrome/browser/repost_form_warning_controller.h"
[email protected]81898992011-06-14 22:15:0081#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4482#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1583#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1884#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0685#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1586#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1387#include "chrome/browser/sync/profile_sync_service.h"
[email protected]40f047972009-11-25 03:54:4088#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0489#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2990#include "chrome/browser/tab_contents/background_contents.h"
[email protected]7cceebac2011-03-03 00:32:2191#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]1ab4ddf2011-07-21 04:48:0492#include "chrome/browser/tab_contents/tab_util.h"
[email protected]07d490bc2011-03-07 17:05:2693#include "chrome/browser/tabs/tab_finder.h"
[email protected]c848d3d92010-09-16 21:57:4594#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]ffa6f592011-06-24 22:03:5795#include "chrome/browser/themes/theme_service.h"
96#include "chrome/browser/themes/theme_service_factory.h"
[email protected]3ab9cb82011-06-03 18:02:0797#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:3798#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:1499#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]55452902011-06-01 21:57:47100#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:04101#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:37102#include "chrome/browser/ui/browser_navigator.h"
[email protected]fb7da4132011-03-15 15:51:00103#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]00070c732011-04-09 15:31:33104#include "chrome/browser/ui/browser_window.h"
[email protected]31145092011-09-30 01:49:44105#include "chrome/browser/ui/constrained_window_tab_helper.h"
[email protected]45300ad42010-12-02 15:51:14106#include "chrome/browser/ui/find_bar/find_bar.h"
107#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:38108#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]bf8708692011-12-20 21:24:28109#include "chrome/browser/ui/fullscreen_controller.h"
[email protected]2f516c792011-09-19 22:22:09110#include "chrome/browser/ui/global_error.h"
111#include "chrome/browser/ui/global_error_service.h"
112#include "chrome/browser/ui/global_error_service_factory.h"
[email protected]943b8612011-08-31 21:07:13113#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
[email protected]6a3ec2312010-12-02 19:30:19114#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:43115#include "chrome/browser/ui/panels/panel.h"
116#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:12117#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19118#include "chrome/browser/ui/status_bubble.h"
[email protected]3da95a102011-11-30 21:47:45119#include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
[email protected]51d83bdf2011-12-09 16:09:29120#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19121#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:44122#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:19123#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]f847e6082011-03-24 00:08:26124#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]265a1492011-02-27 05:58:07125#include "chrome/browser/ui/webui/bug_report_ui.h"
[email protected]02b075972011-10-19 18:39:00126#include "chrome/browser/ui/webui/chrome_web_ui.h"
[email protected]6a1622a2011-09-20 22:37:45127#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
[email protected]5c557f372011-02-26 15:09:20128#include "chrome/browser/ui/webui/options/content_settings_handler.h"
[email protected]9a800652010-12-02 17:08:44129#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54130#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50131#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33132#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:27133#include "chrome/common/chrome_notification_types.h"
[email protected]d938aed92009-01-22 19:49:33134#include "chrome/common/chrome_switches.h"
[email protected]7d189022011-08-25 22:54:20135#include "chrome/common/custom_handlers/protocol_handler.h"
[email protected]5b1a0e22009-05-26 19:00:58136#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33137#include "chrome/common/extensions/extension_constants.h"
[email protected]8a53ee042009-01-21 16:41:33138#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25139#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34140#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23141#include "chrome/common/web_apps.h"
[email protected]b8148ac2011-07-13 22:03:25142#include "content/browser/browser_url_handler.h"
[email protected]3a29a6e2011-08-24 18:26:21143#include "content/browser/child_process_security_policy.h"
[email protected]0ffaa482011-07-14 23:41:28144#include "content/browser/download/save_package.h"
[email protected]b6021d32011-02-26 01:25:54145#include "content/browser/host_zoom_map.h"
[email protected]a01efd22011-03-01 00:38:32146#include "content/browser/renderer_host/render_view_host.h"
147#include "content/browser/site_instance.h"
[email protected]a01efd22011-03-01 00:38:32148#include "content/browser/tab_contents/interstitial_page.h"
149#include "content/browser/tab_contents/navigation_controller.h"
150#include "content/browser/tab_contents/navigation_entry.h"
[email protected]4a63e242011-12-12 15:23:08151#include "content/browser/tab_contents/tab_contents.h"
[email protected]a01efd22011-03-01 00:38:32152#include "content/browser/tab_contents/tab_contents_view.h"
[email protected]0e12d7d2011-12-01 16:21:44153#include "content/public/browser/devtools_manager.h"
[email protected]e582fdd2011-12-20 16:48:17154#include "content/public/browser/download_item.h"
155#include "content/public/browser/download_manager.h"
[email protected]7f6f44c2011-12-14 13:23:38156#include "content/public/browser/notification_details.h"
157#include "content/public/browser/notification_service.h"
[email protected]3a5180ae2011-12-21 02:39:38158#include "content/public/browser/plugin_service.h"
[email protected]7f6f44c2011-12-14 13:23:38159#include "content/public/browser/user_metrics.h"
[email protected]0d9989d2011-12-21 20:26:00160#include "content/public/browser/web_intents_dispatcher.h"
[email protected]4573fbd2011-10-31 20:25:18161#include "content/public/common/content_restriction.h"
[email protected]c08950d22011-10-13 22:20:29162#include "content/public/common/content_switches.h"
[email protected]0f083402011-11-22 02:59:01163#include "content/public/common/page_zoom.h"
[email protected]a3e18c42009-03-04 23:36:05164#include "grit/chromium_strings.h"
165#include "grit/generated_resources.h"
166#include "grit/locale_settings.h"
[email protected]d952a052011-09-06 18:42:45167#include "grit/theme_resources_standard.h"
[email protected]8a53ee042009-01-21 16:41:33168#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33169#include "net/base/net_util.h"
170#include "net/base/registry_controlled_domain.h"
171#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39172#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17173#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38174#include "ui/gfx/point.h"
[email protected]ce9751942011-09-21 01:57:24175#include "webkit/glue/web_intent_data.h"
[email protected]4a19be92011-09-22 14:25:02176#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33177#include "webkit/glue/window_open_disposition.h"
[email protected]3a5180ae2011-12-21 02:39:38178#include "webkit/plugins/webplugininfo.h"
[email protected]8a53ee042009-01-21 16:41:33179
180#if defined(OS_WIN)
[email protected]36d5e5592010-11-15 20:45:59181#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15182#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59183#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12184#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19185#include "chrome/browser/ui/view_ids.h"
186#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]dcd57762011-06-25 12:18:51187#include "ui/base/win/shell.h"
[email protected]8a53ee042009-01-21 16:41:33188#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33189
[email protected]6a4f5af22009-09-23 22:43:00190#if defined(OS_MACOSX)
[email protected]8aee8ed32011-06-14 20:16:41191#include "content/browser/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00192#endif
193
[email protected]b7969202010-05-14 21:29:26194#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35195#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]2166c432011-12-07 20:18:28196#include "chrome/browser/chromeos/dbus/dbus_thread_manager.h"
197#include "chrome/browser/chromeos/dbus/power_manager_client.h"
[email protected]efda32f92011-07-06 22:47:04198#include "chrome/browser/ui/webui/active_downloads_ui.h"
[email protected]eab8c0f2011-11-18 22:33:50199#endif
200
201#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]efda32f92011-07-06 22:47:04202#include "chrome/browser/download/download_shelf.h"
[email protected]b7969202010-05-14 21:29:26203#endif
204
[email protected]cb6dbc52011-08-10 17:34:39205#if defined(FILE_MANAGER_EXTENSION)
[email protected]8baf0dbb2011-11-27 22:47:02206#include "chrome/browser/extensions/file_manager_util.h"
[email protected]cb6dbc52011-08-10 17:34:39207#endif
208
[email protected]8a53ee042009-01-21 16:41:33209using base::TimeDelta;
[email protected]3a5180ae2011-12-21 02:39:38210using content::PluginService;
[email protected]7f6f44c2011-12-14 13:23:38211using content::UserMetricsAction;
initial.commit09911bf2008-07-26 23:55:29212
[email protected]36b6dcb2008-11-12 01:19:57213///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29214
[email protected]505323e22009-01-24 02:47:58215namespace {
216
[email protected]91a79232010-11-10 18:15:08217// The URL to be loaded to display Help.
[email protected]8332c162011-01-26 12:01:54218const char kHelpContentUrl[] =
[email protected]91a79232010-11-10 18:15:08219#if defined(OS_CHROMEOS)
[email protected]8332c162011-01-26 12:01:54220 #if defined(OFFICIAL_BUILD)
221 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html";
222 #else
[email protected]95fc6f92011-04-13 00:37:20223 "https://www.google.com/support/chromeos/";
[email protected]8332c162011-01-26 12:01:54224 #endif
[email protected]91a79232010-11-10 18:15:08225#else
[email protected]95fc6f92011-04-13 00:37:20226 "https://www.google.com/support/chrome/";
[email protected]91a79232010-11-10 18:15:08227#endif
228
229// The URL to be opened when the Help link on the Autofill dialog is clicked.
230const char kAutofillHelpUrl[] =
231#if defined(OS_CHROMEOS)
[email protected]95fc6f92011-04-13 00:37:20232 "https://www.google.com/support/chromeos/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08233#else
[email protected]95fc6f92011-04-13 00:37:20234 "https://www.google.com/support/chrome/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08235#endif
236
237// The URL to be loaded to display the "Report a broken page" form.
238const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20239 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08240 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
241
242// The URL for the privacy dashboard.
243const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
244
245// How long we wait before updating the browser chrome while loading a page.
246const int kUIUpdateCoalescingTimeMS = 200;
247
248const char kHashMark[] = "#";
249
[email protected]50dc3deb2011-07-07 01:07:19250// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
251bool HasInternalURL(const NavigationEntry* entry) {
252 if (!entry)
253 return false;
254
255 // Check the |virtual_url()| first. This catches regular chrome:// URLs
256 // including URLs that were rewritten (such as chrome://bookmarks).
257 if (entry->virtual_url().SchemeIs(chrome::kChromeUIScheme))
258 return true;
259
260 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
261 // view-source: of a chrome:// URL.
262 if (entry->virtual_url().SchemeIs(chrome::kViewSourceScheme))
263 return entry->url().SchemeIs(chrome::kChromeUIScheme);
264
265 return false;
266}
267
[email protected]b6cb7702011-11-15 05:33:11268// Get the launch URL for a given extension, with optional override/fallback.
269// |override_url|, if non-empty, will be preferred over the extension's
270// launch url.
271GURL UrlForExtension(const Extension* extension, const GURL& override_url) {
272 if (!extension)
273 return override_url;
274
275 GURL url;
276 if (!override_url.is_empty()) {
277 DCHECK(extension->web_extent().MatchesURL(override_url));
278 url = override_url;
279 } else {
280 url = extension->GetFullLaunchURL();
281 }
282
283 // For extensions lacking launch urls, determine a reasonable fallback.
284 if (!url.is_valid()) {
285 url = extension->options_url();
286 if (!url.is_valid()) {
287 url = GURL(std::string(chrome::kChromeUISettingsURL) +
288 chrome::kExtensionsSubPage);
289 }
290 }
291
292 return url;
293}
294
[email protected]505323e22009-01-24 02:47:58295} // namespace
296
[email protected]b35b26b32011-05-05 20:35:14297////////////////////////////////////////////////////////////////////////////////
298// Browser, CreateParams:
299
300Browser::CreateParams::CreateParams(Type type, Profile* profile)
301 : type(type),
302 profile(profile) {
303}
304
[email protected]36b6dcb2008-11-12 01:19:57305///////////////////////////////////////////////////////////////////////////////
306// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29307
[email protected]299dabd2008-11-19 02:27:16308Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05309 : type_(type),
310 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39311 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40312 ALLOW_THIS_IN_INITIALIZER_LIST(
313 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14314 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29315 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05316 chrome_updater_factory_(this),
317 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06318 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]400eaf82011-08-22 15:47:39319 show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]8bc061f2011-08-31 22:46:23320 is_session_restore_(false),
[email protected]24f1477532011-11-22 22:55:36321 weak_factory_(this),
[email protected]867125a02009-12-10 06:01:48322 block_command_execution_(false),
323 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51324 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00325 pending_web_app_action_(NONE),
326 ALLOW_THIS_IN_INITIALIZER_LIST(
327 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48328 new BrowserTabRestoreServiceDelegate(this))),
[email protected]afefa74e2011-07-26 05:04:23329 ALLOW_THIS_IN_INITIALIZER_LIST(
330 synced_window_delegate_(
331 new BrowserSyncedWindowDelegate(this))),
[email protected]8a5e0ca2011-08-25 06:30:47332 bookmark_bar_state_(BookmarkBar::HIDDEN),
[email protected]2f516c792011-09-19 22:22:09333 window_has_shown_(false) {
[email protected]432115822011-07-10 15:52:27334 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
[email protected]ad50def52011-10-19 23:17:07335 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27336 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
[email protected]a93089b12011-11-22 20:47:38337 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27338 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]a93089b12011-11-22 20:47:38339 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27340 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]a93089b12011-11-22 20:47:38341 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27342 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
[email protected]a93089b12011-11-22 20:47:38343 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27344 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
[email protected]ad50def52011-10-19 23:17:07345 content::NotificationService::AllSources());
[email protected]ffa6f592011-06-24 22:03:57346 registrar_.Add(
[email protected]432115822011-07-10 15:52:27347 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
[email protected]6c2381d2011-10-19 02:52:53348 content::Source<ThemeService>(
349 ThemeServiceFactory::GetForProfile(profile_)));
[email protected]432115822011-07-10 15:52:27350 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENT_SETTINGS_CHANGED,
[email protected]ad50def52011-10-19 23:17:07351 content::NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29352
[email protected]9e823662010-10-13 23:36:00353 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04354 if (local_state) {
355 local_pref_registrar_.Init(local_state);
356 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
357 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
[email protected]3819f2ee2011-08-21 09:44:38358 local_pref_registrar_.Add(prefs::kMetricsReportingEnabled, this);
[email protected]97b46382011-05-02 13:23:04359 }
360
361 profile_pref_registrar_.Init(profile_->GetPrefs());
362 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
363 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
[email protected]3710d0002011-10-11 00:35:00364 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this);
[email protected]6c6b02d2011-09-02 03:36:47365 profile_pref_registrar_.Add(prefs::kHomePage, this);
[email protected]97b46382011-05-02 13:23:04366 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]4e94ab32011-08-05 05:28:27367 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
[email protected]3819f2ee2011-08-21 09:44:38368 profile_pref_registrar_.Add(prefs::kSearchSuggestEnabled, this);
[email protected]9e823662010-10-13 23:36:00369
initial.commit09911bf2008-07-26 23:55:29370 InitCommandState();
371 BrowserList::AddBrowser(this);
372
[email protected]97b46382011-05-02 13:23:04373 // NOTE: These prefs all need to be explicitly destroyed in the destructor
374 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29375 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
376 profile_->GetPrefs(), NULL);
[email protected]281918912010-05-27 22:05:13377
[email protected]92371eb2011-04-28 11:50:15378 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13379 if (tab_restore_service_) {
380 tab_restore_service_->AddObserver(this);
381 TabRestoreServiceChanged(tab_restore_service_);
382 }
[email protected]d3b98c82010-07-14 07:45:59383
384 if (profile_->GetProfileSyncService())
385 profile_->GetProfileSyncService()->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30386
[email protected]2031cf9d2010-10-12 05:05:37387 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26388
389 // Make sure TabFinder has been created. This does nothing if TabFinder is
390 // not enabled.
391 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48392
393 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
[email protected]a7be6982011-12-12 21:53:57394
395 FilePath profile_path = profile->GetPath();
396 ProfileMetrics::LogProfileLaunch(profile_path);
initial.commit09911bf2008-07-26 23:55:29397}
398
399Browser::~Browser() {
[email protected]d3b98c82010-07-14 07:45:59400 if (profile_->GetProfileSyncService())
401 profile_->GetProfileSyncService()->RemoveObserver(this);
402
initial.commit09911bf2008-07-26 23:55:29403 BrowserList::RemoveBrowser(this);
404
[email protected]7be64502011-05-03 17:51:47405#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29406 if (!BrowserList::HasBrowserWithProfile(profile_)) {
407 // We're the last browser window with this profile. We need to nuke the
408 // TabRestoreService, which will start the shutdown of the
409 // NavigationControllers and allow for proper shutdown. If we don't do this
410 // chrome won't shutdown cleanly, and may end up crashing when some
411 // thread tries to use the IO thread (or another thread) that is no longer
412 // valid.
[email protected]fbc947b2009-06-19 13:28:24413 // This isn't a valid assumption for Mac OS, as it stays running after
414 // the last browser has closed. The Mac equivalent is in its app
415 // controller.
[email protected]92371eb2011-04-28 11:50:15416 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29417 }
[email protected]fbc947b2009-06-19 13:28:24418#endif
initial.commit09911bf2008-07-26 23:55:29419
[email protected]92371eb2011-04-28 11:50:15420 SessionService* session_service =
421 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29422 if (session_service)
423 session_service->WindowClosed(session_id_);
424
[email protected]92371eb2011-04-28 11:50:15425 TabRestoreService* tab_restore_service =
426 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]d8375fd2008-11-25 22:45:39427 if (tab_restore_service)
[email protected]fb7da4132011-03-15 15:51:00428 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39429
[email protected]97b46382011-05-02 13:23:04430 profile_pref_registrar_.RemoveAll();
431 local_pref_registrar_.RemoveAll();
432
[email protected]9a8c4022011-01-25 14:25:33433 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33434
initial.commit09911bf2008-07-26 23:55:29435 if (profile_->IsOffTheRecord() &&
[email protected]474e5db2011-08-12 13:02:23436 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
[email protected]0d1add32011-04-07 00:06:50437 // An incognito profile is no longer needed, this indirectly
[email protected]860f55492009-03-27 19:50:59438 // frees its cache and cookies.
439 profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
initial.commit09911bf2008-07-26 23:55:29440 }
441
442 // There may be pending file dialogs, we need to tell them that we've gone
443 // away so they don't try and call back to us.
444 if (select_file_dialog_.get())
445 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13446
447 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29448}
449
[email protected]01a5a762011-11-21 05:40:55450bool Browser::IsFullscreenForTab() const {
451 return fullscreen_controller_->IsFullscreenForTab();
452}
453
[email protected]15952e462008-11-14 00:29:05454// static
455Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14456 Browser* browser = new Browser(TYPE_TABBED, profile);
457 browser->InitBrowserWindow();
458 return browser;
459}
460
461// static
462Browser* Browser::CreateWithParams(const CreateParams& params) {
463 Browser* browser = new Browser(params.type, params.profile);
464 browser->app_name_ = params.app_name;
[email protected]81b2b0ac2011-11-23 01:54:48465 browser->set_override_bounds(params.initial_bounds);
[email protected]9800de5e2011-03-11 18:19:49466 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05467 return browser;
468}
[email protected]6104acf2008-11-11 22:27:34469
[email protected]15952e462008-11-14 00:29:05470// static
[email protected]9ee17e8c2010-08-10 19:17:31471Browser* Browser::CreateForType(Type type, Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14472 CreateParams params(type, profile);
473 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05474}
475
476// static
[email protected]b35b26b32011-05-05 20:35:14477Browser* Browser::CreateForApp(Type type,
478 const std::string& app_name,
[email protected]5c209242011-06-06 20:36:17479 const gfx::Rect& window_bounds,
[email protected]b35b26b32011-05-05 20:35:14480 Profile* profile) {
481 DCHECK(type != TYPE_TABBED);
482 DCHECK(!app_name.empty());
[email protected]f075fe0a22010-04-26 04:06:43483
[email protected]b35b26b32011-05-05 20:35:14484 RegisterAppPrefs(app_name, profile);
485
[email protected]7e7a28092011-12-09 22:24:55486#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]b35b26b32011-05-05 20:35:14487 if (type == TYPE_PANEL &&
[email protected]7e7a28092011-12-09 22:24:55488 !PanelManager::ShouldUsePanels(
489 web_app::GetExtensionIdFromApplicationName(app_name))) {
[email protected]b35b26b32011-05-05 20:35:14490 type = TYPE_POPUP;
[email protected]5530ac652010-09-25 05:35:49491 }
[email protected]384cb192011-10-14 20:46:51492#if defined(TOOLKIT_GTK)
[email protected]4517b272011-11-09 01:58:05493 // Panels are only supported on a white list of window managers for Linux.
494 if (type == TYPE_PANEL) {
[email protected]ca595c8f2011-11-10 19:30:58495 ui::WindowManagerName wm_type = ui::GuessWindowManager();
496 if (wm_type != ui::WM_COMPIZ &&
497 wm_type != ui::WM_ICE_WM &&
498 wm_type != ui::WM_KWIN &&
499 wm_type != ui::WM_METACITY &&
500 wm_type != ui::WM_MUTTER) {
[email protected]4517b272011-11-09 01:58:05501 type = TYPE_POPUP;
502 }
503 }
[email protected]384cb192011-10-14 20:46:51504#endif // TOOLKIT_GTK
[email protected]7e7a28092011-12-09 22:24:55505#endif // !OS_CHROMEOS || USE_AURA
[email protected]f075fe0a22010-04-26 04:06:43506
[email protected]b35b26b32011-05-05 20:35:14507 CreateParams params(type, profile);
508 params.app_name = app_name;
[email protected]81b2b0ac2011-11-23 01:54:48509 params.initial_bounds = window_bounds;
[email protected]b35b26b32011-05-05 20:35:14510 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05511}
512
[email protected]8e48e982009-12-25 11:22:46513// static
514Browser* Browser::CreateForDevTools(Profile* profile) {
[email protected]4befe2ec2011-08-31 16:13:39515#if defined(OS_CHROMEOS)
516 CreateParams params(TYPE_TABBED, profile);
517#else
[email protected]b35b26b32011-05-05 20:35:14518 CreateParams params(TYPE_POPUP, profile);
[email protected]4befe2ec2011-08-31 16:13:39519#endif
[email protected]b35b26b32011-05-05 20:35:14520 params.app_name = DevToolsWindow::kDevToolsApp;
521 return CreateWithParams(params);
[email protected]8e48e982009-12-25 11:22:46522}
523
[email protected]9800de5e2011-03-11 18:19:49524void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05525 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43526
[email protected]9800de5e2011-03-11 18:19:49527 window_ = CreateBrowserWindow();
[email protected]01a5a762011-11-21 05:40:55528 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
[email protected]15952e462008-11-14 00:29:05529
[email protected]5e37c452011-09-06 19:31:39530#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]45446a52010-11-04 17:41:00531 {
532 // TODO: This might hit the disk
533 // http://code.google.com/p/chromium/issues/detail?id=61638
534 base::ThreadRestrictions::ScopedAllowIO allow_io;
535
536 // Set the app user model id for this application to that of the application
537 // name. See http://crbug.com/7028.
[email protected]dcd57762011-06-25 12:18:51538 ui::win::SetAppIdForWindow(
[email protected]2de2d622011-10-21 22:07:37539 is_app() && !is_type_panel() ?
[email protected]45446a52010-11-04 17:41:00540 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
541 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
542 window()->GetNativeHandle());
[email protected]2de2d622011-10-21 22:07:37543
544 if (is_type_panel()) {
545 ui::win::SetAppIconForWindow(
546 ShellIntegration::GetChromiumIconPath(),
547 window()->GetNativeHandle());
548 }
[email protected]45446a52010-11-04 17:41:00549 }
[email protected]80cf3562009-11-17 08:17:24550#endif
551
[email protected]ad50def52011-10-19 23:17:07552 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27553 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
[email protected]6c2381d2011-10-19 02:52:53554 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:07555 content::NotificationService::NoDetails());
[email protected]14d8c66e2009-09-22 00:32:52556
[email protected]15952e462008-11-14 00:29:05557 PrefService* local_state = g_browser_process->local_state();
[email protected]2f516c792011-09-19 22:22:09558 if (local_state && local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01559 prefs::kAutofillPersonalDataManagerFirstRun) &&
560 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46561 // Notify PDM that this is a first run.
562#if defined(OS_WIN)
[email protected]ea9edcb02011-09-23 22:05:04563 ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_));
[email protected]f69c8852010-10-12 02:36:46564#endif // defined(OS_WIN)
565 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01566 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46567 }
[email protected]6a1622a2011-09-20 22:37:45568
569 // Permanently dismiss ntp4 bubble for new users.
570 if (FirstRun::IsChromeFirstRun())
[email protected]27e96a972011-10-20 20:06:55571 NewTabPageHandler::DismissIntroMessage(local_state);
initial.commit09911bf2008-07-26 23:55:29572}
573
[email protected]bf8708692011-12-20 21:24:28574void Browser::SetWindowForTesting(BrowserWindow* window) {
575 DCHECK(!window_);
576 window_ = window;
577 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
578}
579
[email protected]36b6dcb2008-11-12 01:19:57580///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07581// Getters & Setters
582
[email protected]b77cb302009-10-29 04:09:17583FindBarController* Browser::GetFindBarController() {
584 if (!find_bar_controller_.get()) {
[email protected]632983f2011-08-08 22:51:24585 FindBar* find_bar = window_->CreateFindBar();
[email protected]b77cb302009-10-29 04:09:17586 find_bar_controller_.reset(new FindBarController(find_bar));
587 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24588 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17589 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
590 }
591 return find_bar_controller_.get();
592}
593
[email protected]24db8a072009-10-29 20:35:37594bool Browser::HasFindBarController() const {
595 return find_bar_controller_.get() != NULL;
596}
597
[email protected]b35b26b32011-05-05 20:35:14598bool Browser::is_app() const {
599 return !app_name_.empty();
600}
601
602bool Browser::is_devtools() const {
603 return app_name_ == DevToolsWindow::kDevToolsApp;
604}
605
[email protected]5c238752009-06-13 10:29:07606///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57607// Browser, Creation Helpers:
608
609// static
[email protected]15952e462008-11-14 00:29:05610void Browser::OpenEmptyWindow(Profile* profile) {
611 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57612 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05613 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29614}
615
[email protected]36b6dcb2008-11-12 01:19:57616// static
[email protected]fbc947b2009-06-19 13:28:24617void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15618 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24619 if (service)
620 service->RestoreMostRecentEntry(NULL);
621}
622
623// static
[email protected]36b6dcb2008-11-12 01:19:57624void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55625 Browser* browser = GetOrCreateTabbedBrowser(
626 profile->GetOffTheRecordProfile());
[email protected]2905f742011-10-13 03:51:58627 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK);
[email protected]15952e462008-11-14 00:29:05628 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17629}
630
[email protected]36b6dcb2008-11-12 01:19:57631// static
[email protected]d83a5602010-09-16 00:22:48632TabContents* Browser::OpenApplication(
633 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02634 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39635 extension_misc::LaunchContainer container,
[email protected]b6cb7702011-11-15 05:33:11636 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16637 WindowOpenDisposition disposition) {
[email protected]56869382010-05-11 21:45:46638 TabContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04639 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
640 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37641
[email protected]9b217652010-10-08 22:04:23642 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
643
[email protected]bbadaa782010-04-28 21:21:53644 switch (container) {
[email protected]d83a5602010-09-16 00:22:48645 case extension_misc::LAUNCH_WINDOW:
646 case extension_misc::LAUNCH_PANEL:
[email protected]cfc6cca2011-12-01 02:30:06647 case extension_misc::LAUNCH_SHELL:
[email protected]bbadaa782010-04-28 21:21:53648 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]b6cb7702011-11-15 05:33:11649 override_url, NULL);
[email protected]c28071ad2010-03-12 17:28:56650 break;
[email protected]d83a5602010-09-16 00:22:48651 case extension_misc::LAUNCH_TAB: {
[email protected]b6cb7702011-11-15 05:33:11652 tab = Browser::OpenApplicationTab(profile, extension, override_url,
653 disposition);
[email protected]c28071ad2010-03-12 17:28:56654 break;
655 }
656 default:
657 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53658 break;
[email protected]c28071ad2010-03-12 17:28:56659 }
[email protected]bbadaa782010-04-28 21:21:53660 return tab;
[email protected]c28071ad2010-03-12 17:28:56661}
662
663// static
[email protected]bbadaa782010-04-28 21:21:53664TabContents* Browser::OpenApplicationWindow(
665 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02666 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48667 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26668 const GURL& url_input,
669 Browser** app_browser) {
[email protected]b6cb7702011-11-15 05:33:11670 DCHECK(!url_input.is_empty() || extension);
671 GURL url = UrlForExtension(extension, url_input);
[email protected]f381dfa2010-04-29 04:41:37672
[email protected]2f1c09d2011-01-14 14:58:14673 std::string app_name;
[email protected]b6cb7702011-11-15 05:33:11674 app_name = extension ?
675 web_app::GenerateApplicationNameFromExtensionId(extension->id()) :
676 web_app::GenerateApplicationNameFromURL(url);
[email protected]2f1c09d2011-01-14 14:58:14677
[email protected]cfc6cca2011-12-01 02:30:06678 Type type = TYPE_POPUP;
679 if (extension) {
680 switch (container) {
681 case extension_misc::LAUNCH_PANEL:
682 type = TYPE_PANEL;
683 break;
684 case extension_misc::LAUNCH_SHELL:
685 type = TYPE_SHELL;
686 break;
687 default: break;
688 }
689 }
[email protected]94ce7252010-12-20 21:46:33690
[email protected]5c209242011-06-06 20:36:17691 gfx::Rect window_bounds;
692 if (extension) {
693 window_bounds.set_width(extension->launch_width());
694 window_bounds.set_height(extension->launch_height());
695 }
[email protected]94ce7252010-12-20 21:46:33696
[email protected]5c209242011-06-06 20:36:17697 Browser* browser = Browser::CreateForApp(type, app_name, window_bounds,
[email protected]b35b26b32011-05-05 20:35:14698 profile);
[email protected]011396a2011-04-13 23:35:28699
[email protected]0e71e4152010-12-07 04:16:26700 if (app_browser)
701 *app_browser = browser;
702
[email protected]3c9e1872010-11-18 16:17:49703 TabContentsWrapper* wrapper =
[email protected]2905f742011-10-13 03:51:58704 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_START_PAGE);
[email protected]3c9e1872010-11-18 16:17:49705 TabContents* contents = wrapper->tab_contents();
[email protected]cecc93a2010-10-05 15:58:55706 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:52707 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]cecc93a2010-10-05 15:58:55708 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53709
[email protected]68f009f2009-02-26 19:43:35710 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
711 // focus explicitly.
[email protected]d487beefe2011-12-21 05:41:21712 contents->GetView()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26713 return contents;
714}
[email protected]eabfdae92009-12-11 06:13:51715
[email protected]0e71e4152010-12-07 04:16:26716TabContents* Browser::OpenAppShortcutWindow(Profile* profile,
717 const GURL& url,
718 bool update_shortcut) {
719 Browser* app_browser;
720 TabContents* tab = OpenApplicationWindow(
721 profile,
722 NULL, // this is a URL app. No extension.
723 extension_misc::LAUNCH_WINDOW,
724 url,
725 &app_browser);
726
727 if (!tab)
728 return NULL;
729
730 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35731 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
732 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
733 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46734 // OnDidGetApplicationInfo, which calls
735 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
736 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26737 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35738 }
[email protected]0e71e4152010-12-07 04:16:26739 return tab;
[email protected]c28071ad2010-03-12 17:28:56740}
741
742// static
[email protected]bbadaa782010-04-28 21:21:53743TabContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02744 const Extension* extension,
[email protected]b6cb7702011-11-15 05:33:11745 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16746 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14747 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]cecc93a2010-10-05 15:58:55748 TabContents* contents = NULL;
[email protected]78d78a62011-09-29 18:24:33749 if (!browser) {
750 // No browser for this profile, need to open a new one.
751 browser = Browser::Create(profile);
752 browser->window()->Show();
753 // There's no current tab in this browser window, so add a new one.
754 disposition = NEW_FOREGROUND_TAB;
755 }
[email protected]c28071ad2010-03-12 17:28:56756
[email protected]10abd192010-09-30 02:03:49757 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36758 ExtensionService* extension_service = profile->GetExtensionService();
759 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59760
[email protected]10abd192010-09-30 02:03:49761 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36762 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02763 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23764 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]333b1de2011-09-12 18:28:50765
[email protected]49098f702011-10-13 03:47:18766 static bool default_apps_trial_exists =
[email protected]568c3312011-12-06 15:36:04767 base::FieldTrialList::TrialExists(kDefaultAppsTrialName);
[email protected]49098f702011-10-13 03:47:18768 if (default_apps_trial_exists) {
769 UMA_HISTOGRAM_ENUMERATION(
770 base::FieldTrial::MakeName("Extensions.AppTabLaunchType",
[email protected]568c3312011-12-06 15:36:04771 kDefaultAppsTrialName),
[email protected]49098f702011-10-13 03:47:18772 launch_type, 100);
773 }
[email protected]333b1de2011-09-12 18:28:50774
[email protected]eaca0ad12011-04-18 15:53:41775 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49776 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
777 add_type |= TabStripModel::ADD_PINNED;
778
[email protected]b6cb7702011-11-15 05:33:11779 GURL extension_url = UrlForExtension(extension, override_url);
[email protected]10abd192010-09-30 02:03:49780 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
781 // cases.
[email protected]37fcf262011-01-26 19:39:15782 browser::NavigateParams params(browser, extension_url,
[email protected]2905f742011-10-13 03:51:58783 content::PAGE_TRANSITION_START_PAGE);
[email protected]616381f02010-11-02 15:15:33784 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16785 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39786
[email protected]7e41c2b2011-05-06 10:31:16787 if (disposition == CURRENT_TAB) {
788 TabContents* existing_tab = browser->GetSelectedTabContents();
[email protected]24bf2022010-10-14 16:34:39789 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49790 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39791
[email protected]bce1f1c2011-12-05 15:11:58792 existing_tab->OpenURL(OpenURLParams(
793 extension_url,
794 content::Referrer(existing_tab->GetURL(),
795 WebKit::WebReferrerPolicyDefault),
796 disposition, content::PAGE_TRANSITION_LINK, false));
[email protected]616381f02010-11-02 15:15:33797 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39798 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49799 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26800 }
[email protected]eaca0ad12011-04-18 15:53:41801 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
802 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39803
804 contents = existing_tab;
805 } else {
[email protected]616381f02010-11-02 15:15:33806 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:49807 contents = params.target_contents->tab_contents();
[email protected]24bf2022010-10-14 16:34:39808 }
809
[email protected]7bd42fc2011-02-09 17:32:42810 // TODO(skerner): If we are already in full screen mode, and the user
811 // set the app to open as a regular or pinned tab, what should happen?
812 // Today we open the tab, but stay in full screen mode. Should we leave
813 // full screen mode in this case?
814 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
[email protected]b6cb7702011-11-15 05:33:11815 !browser->window()->IsFullscreen()) {
[email protected]55c87fa2011-10-15 07:28:28816 browser->ToggleFullscreenMode(false);
[email protected]b6cb7702011-11-15 05:33:11817 }
[email protected]10abd192010-09-30 02:03:49818
[email protected]cecc93a2010-10-05 15:58:55819 return contents;
[email protected]c28071ad2010-03-12 17:28:56820}
821
822// static
[email protected]90a8bf252010-03-12 00:09:47823void Browser::OpenBookmarkManagerWindow(Profile* profile) {
824 Browser* browser = Browser::Create(profile);
[email protected]0af8f132011-07-16 01:37:02825 browser->OpenBookmarkManager();
[email protected]90a8bf252010-03-12 00:09:47826 browser->window()->Show();
827}
828
[email protected]057d959a2010-03-12 02:56:20829#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47830// static
[email protected]91a5b3e2009-10-30 19:32:22831void Browser::OpenHistoryWindow(Profile* profile) {
832 Browser* browser = Browser::Create(profile);
833 browser->ShowHistoryTab();
834 browser->window()->Show();
835}
836
837// static
838void Browser::OpenDownloadsWindow(Profile* profile) {
839 Browser* browser = Browser::Create(profile);
840 browser->ShowDownloadsTab();
841 browser->window()->Show();
842}
843
844// static
[email protected]1fdff702009-10-22 00:36:18845void Browser::OpenHelpWindow(Profile* profile) {
846 Browser* browser = Browser::Create(profile);
[email protected]202802e42011-07-06 11:40:46847 browser->ShowHelpTab();
[email protected]1fdff702009-10-22 00:36:18848 browser->window()->Show();
849}
[email protected]4a42d272010-06-18 01:29:42850
[email protected]eca258132010-11-15 23:33:08851// static
[email protected]4a42d272010-06-18 01:29:42852void Browser::OpenOptionsWindow(Profile* profile) {
853 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49854 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42855 browser->window()->Show();
856}
[email protected]c8de64a2011-01-25 17:10:23857
858// static
[email protected]ddddfda2011-07-14 23:19:39859void Browser::OpenClearBrowsingDataDialogWindow(Profile* profile) {
[email protected]c8de64a2011-01-25 17:10:23860 Browser* browser = Browser::Create(profile);
861 browser->OpenClearBrowsingDataDialog();
862 browser->window()->Show();
863}
864
865// static
866void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
867 Browser* browser = Browser::Create(profile);
868 browser->OpenImportSettingsDialog();
869 browser->window()->Show();
870}
[email protected]b99081b2011-03-10 17:43:47871
872// static
873void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
874 Browser* browser = Browser::Create(profile);
875 browser->OpenInstantConfirmDialog();
876 browser->window()->Show();
877}
[email protected]1fdff702009-10-22 00:36:18878#endif
879
[email protected]ccb55cf52010-03-06 22:02:04880// static
881void Browser::OpenExtensionsWindow(Profile* profile) {
882 Browser* browser = Browser::Create(profile);
883 browser->ShowExtensionsTab();
884 browser->window()->Show();
885}
886
[email protected]36b6dcb2008-11-12 01:19:57887///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57888// Browser, State Storage and Retrieval for UI:
889
[email protected]57ecc4b2010-08-11 03:02:51890std::string Browser::GetWindowPlacementKey() const {
891 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57892 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51893 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57894 name.append(app_name_);
895 }
[email protected]bc9a5152008-11-15 00:32:04896 return name;
897}
[email protected]36b6dcb2008-11-12 01:19:57898
[email protected]bc9a5152008-11-15 00:32:04899bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14900 switch (type_) {
901 case TYPE_TABBED:
902 return true;
903 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:51904 // Only save the window placement of popups if they are restored,
905 // or the window belongs to DevTools.
906 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:14907 case TYPE_PANEL:
908 // Do not save the window placement of panels.
909 return false;
[email protected]cfc6cca2011-12-01 02:30:06910 case TYPE_SHELL:
911 return true;
[email protected]b35b26b32011-05-05 20:35:14912 default:
913 return false;
914 }
[email protected]bc9a5152008-11-15 00:32:04915}
[email protected]36b6dcb2008-11-12 01:19:57916
[email protected]400eaf82011-08-22 15:47:39917void Browser::SaveWindowPlacement(const gfx::Rect& bounds,
918 ui::WindowShowState show_state) {
[email protected]bc9a5152008-11-15 00:32:04919 // Save to the session storage service, used when reloading a past session.
920 // Note that we don't want to be the ones who cause lazy initialization of
921 // the session service. This function gets called during initial window
922 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:15923 SessionService* session_service =
924 SessionServiceFactory::GetForProfileIfExisting(profile());
925 if (session_service)
[email protected]400eaf82011-08-22 15:47:39926 session_service->SetWindowBounds(session_id_, bounds, show_state);
[email protected]36b6dcb2008-11-12 01:19:57927}
928
[email protected]15952e462008-11-14 00:29:05929gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]bb975362009-01-21 01:00:22930 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05931 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
932 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
933 if (record_mode || playback_mode) {
934 // In playback/record mode we always fix the size of the browser and
935 // move it to (0,0). The reason for this is two reasons: First we want
936 // resize/moves in the playback to still work, and Second we want
937 // playbacks to work (as much as possible) on machines w/ different
938 // screen sizes.
939 return gfx::Rect(0, 0, 800, 600);
940 }
941
942 gfx::Rect restored_bounds = override_bounds_;
[email protected]f87919d72011-02-02 18:46:16943 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]ea9dad92011-11-17 16:10:00944 &restored_bounds);
[email protected]15952e462008-11-14 00:29:05945 return restored_bounds;
946}
947
[email protected]400eaf82011-08-22 15:47:39948ui::WindowShowState Browser::GetSavedWindowShowState() const {
[email protected]bb975362009-01-21 01:00:22949 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]400eaf82011-08-22 15:47:39950 return ui::SHOW_STATE_MAXIMIZED;
[email protected]15952e462008-11-14 00:29:05951
[email protected]400eaf82011-08-22 15:47:39952 if (show_state_ != ui::SHOW_STATE_DEFAULT)
953 return show_state_;
[email protected]2e716622009-03-09 21:11:01954
[email protected]96f20102011-11-16 17:20:32955 const DictionaryValue* window_pref =
956 profile()->GetPrefs()->GetDictionary(GetWindowPlacementKey().c_str());
[email protected]2e716622009-03-09 21:11:01957 bool maximized = false;
[email protected]96f20102011-11-16 17:20:32958 window_pref->GetBoolean("maximized", &maximized);
959
[email protected]400eaf82011-08-22 15:47:39960 return maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
[email protected]36b6dcb2008-11-12 01:19:57961}
962
963SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:04964 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:23965 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
966 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:04967 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57968}
969
[email protected]731f8a42009-07-20 22:07:32970string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3c9e1872010-11-18 16:17:49971 TabContents* contents = GetSelectedTabContents();
[email protected]dda5dfa32009-07-10 00:33:29972 string16 title;
[email protected]c7c42332008-11-15 01:10:54973
[email protected]731f8a42009-07-20 22:07:32974 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
975 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57976 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29977 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57978 FormatTitleForDisplay(&title);
979 }
980 if (title.empty())
[email protected]51d83bdf2011-12-09 16:09:29981 title = CoreTabHelper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57982
[email protected]16779842009-07-08 23:45:29983#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:33984 // On Mac or ChromeOS, we don't want to suffix the page title with
985 // the application name.
[email protected]d904bc82009-07-07 00:41:04986 return title;
[email protected]7be64502011-05-03 17:51:47987#else
[email protected]edb5e6a2009-04-08 23:46:17988 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55989 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:14990 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:17991 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29992 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50993#endif
[email protected]36b6dcb2008-11-12 01:19:57994}
995
996// static
[email protected]dda5dfa32009-07-10 00:33:29997void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57998 size_t current_index = 0;
999 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:511000 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:151001 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:571002 current_index = match_index;
1003 }
1004}
1005
1006///////////////////////////////////////////////////////////////////////////////
1007// Browser, OnBeforeUnload handling:
1008
[email protected]460a2942010-12-15 19:43:151009bool Browser::TabsNeedBeforeUnloadFired() {
1010 if (tabs_needing_before_unload_fired_.empty()) {
1011 for (int i = 0; i < tab_count(); ++i) {
1012 TabContents* contents = GetTabContentsAt(i);
1013 if (contents->NeedToFireBeforeUnload())
1014 tabs_needing_before_unload_fired_.insert(contents);
1015 }
1016 }
1017 return !tabs_needing_before_unload_fired_.empty();
1018}
1019
[email protected]36b6dcb2008-11-12 01:19:571020bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:061021 if (!CanCloseWithInProgressDownloads())
1022 return false;
1023
1024 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:041025 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:061026
[email protected]36b6dcb2008-11-12 01:19:571027 is_attempting_to_close_browser_ = true;
1028
[email protected]460a2942010-12-15 19:43:151029 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:041030 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:571031
1032 ProcessPendingTabs();
1033 return false;
1034}
1035
1036void Browser::OnWindowClosing() {
1037 if (!ShouldCloseWindow())
1038 return;
1039
[email protected]911f8152010-03-18 16:46:401040 bool exiting = false;
1041
[email protected]c984d9f2010-07-20 20:52:201042 // Application should shutdown on last window close if the user is explicitly
1043 // trying to quit, or if there is nothing keeping the browser alive (such as
1044 // AppController on the Mac, or BackgroundContentsService for background
1045 // pages).
1046 bool should_quit_if_last_browser =
1047 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:501048
1049 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:571050 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:401051 exiting = true;
1052 }
[email protected]36b6dcb2008-11-12 01:19:571053
[email protected]92371eb2011-04-28 11:50:151054 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:571055 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:151056 SessionService* session_service =
1057 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:571058 if (session_service)
1059 session_service->WindowClosing(session_id());
1060
[email protected]92371eb2011-04-28 11:50:151061 TabRestoreService* tab_restore_service =
1062 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]b35b26b32011-05-05 20:35:141063 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:001064 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:391065
[email protected]911f8152010-03-18 16:46:401066 // TODO(sky): convert session/tab restore to use notification.
[email protected]ad50def52011-10-19 23:17:071067 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:271068 chrome::NOTIFICATION_BROWSER_CLOSING,
[email protected]6c2381d2011-10-19 02:52:531069 content::Source<Browser>(this),
1070 content::Details<bool>(&exiting));
[email protected]911f8152010-03-18 16:46:401071
[email protected]36b6dcb2008-11-12 01:19:571072 CloseAllTabs();
1073}
1074
[email protected]28788c7d2011-05-20 23:03:451075void Browser::OnWindowActivated() {
1076 // On some platforms we want to automatically reload tabs that are
1077 // killed when the user selects them.
1078 TabContents* contents = GetSelectedTabContents();
1079 if (contents && contents->crashed_status() ==
1080 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
1081 if (CommandLine::ForCurrentProcess()->HasSwitch(
1082 switches::kReloadKilledTabs)) {
1083 Reload(CURRENT_TAB);
1084 }
1085 }
1086}
1087
[email protected]69444cc2009-04-09 20:40:061088////////////////////////////////////////////////////////////////////////////////
1089// In-progress download termination handling:
1090
1091void Browser::InProgressDownloadResponse(bool cancel_downloads) {
1092 if (cancel_downloads) {
1093 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1094 CloseWindow();
1095 return;
1096 }
1097
1098 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1099 // close again we'll show the warning again.
1100 cancel_download_confirmation_state_ = NOT_PROMPTED;
1101
1102 // Show the download page so the user can figure-out what downloads are still
1103 // in-progress.
1104 ShowDownloadsTab();
1105}
1106
[email protected]5a17d492011-10-24 19:37:031107Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
1108 int* num_downloads_blocking) const {
1109 DCHECK(num_downloads_blocking);
1110 *num_downloads_blocking = 0;
1111
1112 if (is_attempting_to_close_browser_)
1113 return DOWNLOAD_CLOSE_OK;
1114
1115 // If we're not running a full browser process with a profile manager
1116 // (testing), it's ok to close the browser.
1117 if (!g_browser_process->profile_manager())
1118 return DOWNLOAD_CLOSE_OK;
1119
1120 int total_download_count = DownloadService::DownloadCountAllProfiles();
1121 if (total_download_count == 0)
1122 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
1123
1124 // Figure out how many windows are open total, and associated with this
1125 // profile, that are relevant for the ok-to-close decision.
1126 int profile_window_count = 0;
1127 int total_window_count = 0;
1128 for (BrowserList::const_iterator iter = BrowserList::begin();
1129 iter != BrowserList::end(); ++iter) {
1130 // Don't count this browser window or any other in the process of closing.
1131 Browser* const browser = *iter;
1132 // Check is_attempting_to_close_browser_ as window closing may be
1133 // delayed, and windows that are in the process of closing don't
1134 // count against our totals.
1135 if (browser == this || browser->is_attempting_to_close_browser_)
1136 continue;
1137
1138 if ((*iter)->profile() == profile())
1139 profile_window_count++;
1140 total_window_count++;
1141 }
1142
1143 // If there aren't any other windows, we're at browser shutdown,
1144 // which would cancel all current downloads.
1145 if (total_window_count == 0) {
1146 *num_downloads_blocking = total_download_count;
1147 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
1148 }
1149
1150 // If there aren't any other windows on our profile, and we're an incognito
1151 // profile, and there are downloads associated with that profile,
1152 // those downloads would be cancelled by our window (-> profile) close.
1153 DownloadService* download_service =
1154 DownloadServiceFactory::GetForProfile(profile());
1155 if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
1156 profile()->IsOffTheRecord()) {
1157 *num_downloads_blocking = download_service->DownloadCount();
1158 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
1159 }
1160
1161 // Those are the only conditions under which we will block shutdown.
1162 return DOWNLOAD_CLOSE_OK;
1163}
1164
[email protected]69444cc2009-04-09 20:40:061165////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451166// Browser, TabStripModel pass-thrus:
1167
1168int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:401169 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:451170}
1171
[email protected]1ea49d52011-04-12 17:44:441172int Browser::active_index() const {
1173 return tab_handler_->GetTabStripModel()->active_index();
[email protected]c848d3d92010-09-16 21:57:451174}
1175
1176int Browser::GetIndexOfController(
1177 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:401178 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451179}
1180
[email protected]3c9e1872010-11-18 16:17:491181TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
[email protected]fb7e74922011-06-09 01:39:421182 return tabstrip_model()->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491183}
[email protected]b375c5d2011-05-03 21:15:041184
[email protected]3c9e1872010-11-18 16:17:491185TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
1186 return tabstrip_model()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451187}
1188
1189TabContents* Browser::GetSelectedTabContents() const {
[email protected]3c9e1872010-11-18 16:17:491190 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1191 if (wrapper)
1192 return wrapper->tab_contents();
1193 return NULL;
1194}
1195
1196TabContents* Browser::GetTabContentsAt(int index) const {
1197 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
1198 if (wrapper)
1199 return wrapper->tab_contents();
1200 return NULL;
[email protected]c848d3d92010-09-16 21:57:451201}
1202
[email protected]eaca0ad12011-04-18 15:53:411203void Browser::ActivateTabAt(int index, bool user_gesture) {
1204 tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451205}
1206
[email protected]fb7da4132011-03-15 15:51:001207bool Browser::IsTabPinned(int index) const {
1208 return tabstrip_model()->IsTabPinned(index);
1209}
1210
[email protected]002efb042011-10-07 17:30:241211bool Browser::IsTabDiscarded(int index) const {
1212 return tab_handler_->GetTabStripModel()->IsTabDiscarded(index);
1213}
1214
[email protected]c848d3d92010-09-16 21:57:451215void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:401216 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451217}
1218
1219////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571220// Browser, Tab adding/showing functions:
1221
[email protected]95bf8a5b2010-12-22 16:04:071222bool Browser::IsTabStripEditable() const {
1223 return window()->IsTabStripEditable();
1224}
1225
[email protected]b3344872010-05-03 15:52:291226int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:401227 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
1228 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291229}
1230
[email protected]dad09ce42011-08-25 23:11:301231TabContentsWrapper* Browser::AddSelectedTabWithURL(
1232 const GURL& url,
[email protected]2905f742011-10-13 03:51:581233 content::PageTransition transition) {
[email protected]616381f02010-11-02 15:15:331234 browser::NavigateParams params(this, url, transition);
1235 params.disposition = NEW_FOREGROUND_TAB;
1236 browser::Navigate(&params);
1237 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571238}
1239
[email protected]3c9e1872010-11-18 16:17:491240TabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]2905f742011-10-13 03:51:581241 content::PageTransition type) {
[email protected]ecc523f62010-09-28 22:45:401242 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]eaca0ad12011-04-18 15:53:411243 tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
[email protected]3c9e1872010-11-18 16:17:491244 return tab_contents->tab_contents();
[email protected]36b6dcb2008-11-12 01:19:571245}
1246
[email protected]e0c7c262009-04-23 23:09:431247void Browser::AddTabContents(TabContents* new_contents,
1248 WindowOpenDisposition disposition,
1249 const gfx::Rect& initial_pos,
1250 bool user_gesture) {
1251 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1252}
1253
1254void Browser::CloseTabContents(TabContents* contents) {
1255 CloseContents(contents);
1256}
1257
[email protected]b86451c2011-08-16 02:13:441258gfx::NativeWindow Browser::BrowserShowHtmlDialog(
[email protected]62c1f7a2011-10-01 01:12:041259 HtmlDialogUIDelegate* delegate,
[email protected]22c830d2011-11-29 20:00:371260 gfx::NativeWindow parent_window,
1261 DialogStyle style) {
[email protected]62c1f7a2011-10-01 01:12:041262#if defined(OS_CHROMEOS)
1263 // For Chrome OS, first try to parent the dialog over the current browser --
1264 // it's likely to be maximized onscreen. If it isn't tabbed (e.g. it's a
1265 // panel), find a browser that is.
1266 parent_window = window_->GetNativeHandle();
1267 if (!is_type_tabbed()) {
1268 Browser* tabbed_browser = BrowserList::FindTabbedBrowser(profile_, true);
1269 if (tabbed_browser && tabbed_browser->window())
1270 parent_window = tabbed_browser->window()->GetNativeHandle();
1271 }
1272#endif // defined(OS_CHROMEOS)
1273 if (!parent_window)
1274 parent_window = window_->GetNativeHandle();
1275
[email protected]22c830d2011-11-29 20:00:371276 return browser::ShowHtmlDialog(parent_window, profile_, delegate, style);
[email protected]e0c7c262009-04-23 23:09:431277}
1278
1279void Browser::BrowserRenderWidgetShowing() {
1280 RenderWidgetShowing();
1281}
1282
[email protected]c9bd2e82011-04-15 23:28:191283void Browser::BookmarkBarSizeChanged(bool is_animating) {
1284 window_->ToolbarSizeChanged(is_animating);
[email protected]e0c7c262009-04-23 23:09:431285}
1286
[email protected]ce3fa3c2009-04-20 19:55:571287TabContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571288 const std::vector<TabNavigation>& navigations,
1289 int tab_index,
1290 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081291 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091292 bool select,
[email protected]5e369672009-11-03 23:48:301293 bool pin,
[email protected]6ee12c42010-09-14 09:36:071294 bool from_last_session,
1295 SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041296 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1297 TabContentsWrapper* wrapper = TabContentsFactory(
1298 profile(),
1299 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]3c9e1872010-11-18 16:17:491300 MSG_ROUTING_NONE,
1301 GetSelectedTabContents(),
[email protected]ecc523f62010-09-28 22:45:401302 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:491303 TabContents* new_tab = wrapper->tab_contents();
[email protected]36fb2c7c2011-04-04 15:49:081304 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]03838e22011-06-06 15:27:141305 std::vector<NavigationEntry*> entries;
1306 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1307 profile_, navigations, &entries);
[email protected]10b833e2011-12-21 17:36:301308 new_tab->controller().Restore(
[email protected]03838e22011-06-06 15:27:141309 selected_navigation, from_last_session, &entries);
1310 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571311
[email protected]eaca0ad12011-04-18 15:53:411312 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211313 TabStripModel::ADD_NONE;
1314 if (pin) {
1315 tab_index = std::min(tab_index, tabstrip_model()->IndexOfFirstNonMiniTab());
1316 add_types |= TabStripModel::ADD_PINNED;
1317 }
1318 tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1319 add_types);
[email protected]c93a9dd2010-04-22 20:25:181320 if (select) {
[email protected]77bc6732009-04-20 22:01:031321 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181322 } else {
1323 // We set the size of the view here, before WebKit does its initial
1324 // layout. If we don't, the initial layout of background tabs will be
1325 // performed with a view width of 0, which may cause script outputs and
1326 // anchor link location calculations to be incorrect even after a new
1327 // layout with proper view dimensions. TabStripModel::AddTabContents()
1328 // contains similar logic.
[email protected]d487beefe2011-12-21 05:41:211329 new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size());
[email protected]c93a9dd2010-04-22 20:25:181330 new_tab->HideContents();
[email protected]10b833e2011-12-21 17:36:301331 new_tab->controller().LoadIfNecessary();
[email protected]c93a9dd2010-04-22 20:25:181332 }
[email protected]92371eb2011-04-28 11:50:151333 SessionService* session_service =
1334 SessionServiceFactory::GetForProfileIfExisting(profile_);
1335 if (session_service)
[email protected]81898992011-06-14 22:15:001336 session_service->TabRestored(wrapper, pin);
[email protected]ce3fa3c2009-04-20 19:55:571337 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571338}
1339
1340void Browser::ReplaceRestoredTab(
1341 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301342 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101343 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071344 const std::string& extension_app_id,
1345 SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041346 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1347 TabContentsWrapper* wrapper = TabContentsFactory(
1348 profile(),
1349 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]ecc523f62010-09-28 22:45:401350 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:491351 GetSelectedTabContents(),
[email protected]6ee12c42010-09-14 09:36:071352 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081353 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]3c9e1872010-11-18 16:17:491354 TabContents* replacement = wrapper->tab_contents();
[email protected]03838e22011-06-06 15:27:141355 std::vector<NavigationEntry*> entries;
1356 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1357 profile_, navigations, &entries);
[email protected]10b833e2011-12-21 17:36:301358 replacement->controller().Restore(
[email protected]03838e22011-06-06 15:27:141359 selected_navigation, from_last_session, &entries);
1360 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571361
[email protected]ecc523f62010-09-28 22:45:401362 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
[email protected]1ea49d52011-04-12 17:44:441363 tab_handler_->GetTabStripModel()->active_index(),
[email protected]3c9e1872010-11-18 16:17:491364 wrapper);
[email protected]36b6dcb2008-11-12 01:19:571365}
1366
[email protected]a8eff102009-04-14 15:23:431367bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131368 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431369}
1370
[email protected]3698f172010-03-17 20:50:291371bool Browser::NavigateToIndexWithDisposition(int index,
1372 WindowOpenDisposition disp) {
1373 NavigationController& controller =
[email protected]10b833e2011-12-21 17:36:301374 GetOrCloneTabForDisposition(disp)->controller();
[email protected]cb84d642010-06-10 00:56:281375 if (index < 0 || index >= controller.entry_count())
[email protected]3698f172010-03-17 20:50:291376 return false;
[email protected]cb84d642010-06-10 00:56:281377 controller.GoToIndex(index);
1378 return true;
[email protected]3698f172010-03-17 20:50:291379}
1380
[email protected]fee320542011-03-02 01:30:491381browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1382 const GURL& url) {
[email protected]2905f742011-10-13 03:51:581383 browser::NavigateParams params(
1384 this, url, content::PAGE_TRANSITION_AUTO_BOOKMARK);
[email protected]616381f02010-11-02 15:15:331385 params.disposition = SINGLETON_TAB;
[email protected]7d329992011-04-15 18:20:021386 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:351387 params.user_gesture = true;
[email protected]fee320542011-03-02 01:30:491388 return params;
1389}
1390
1391void Browser::ShowSingletonTab(const GURL& url) {
1392 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331393 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571394}
[email protected]d938aed92009-01-22 19:49:331395
[email protected]578c6962011-08-24 22:06:401396void Browser::ShowSingletonTabRespectRef(const GURL& url) {
1397 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1398 params.ref_behavior = browser::NavigateParams::RESPECT_REF;
1399 browser::Navigate(&params);
1400}
1401
[email protected]ddddfda2011-07-14 23:19:391402void Browser::ShowSingletonTabOverwritingNTP(
1403 const browser::NavigateParams& params) {
1404 browser::NavigateParams local_params(params);
1405 TabContents* contents = GetSelectedTabContents();
[email protected]842a648c2011-07-20 23:23:161406 if (contents) {
1407 const GURL& contents_url = contents->GetURL();
1408 if ((contents_url == GURL(chrome::kChromeUINewTabURL) ||
1409 contents_url == GURL(chrome::kAboutBlankURL)) &&
1410 browser::GetIndexOfSingletonTab(&local_params) < 0) {
1411 local_params.disposition = CURRENT_TAB;
1412 }
[email protected]ddddfda2011-07-14 23:19:391413 }
1414
1415 browser::Navigate(&local_params);
1416}
1417
[email protected]227393e2011-06-29 21:28:391418void Browser::WindowFullscreenStateChanged() {
[email protected]01a5a762011-11-21 05:40:551419 fullscreen_controller_->WindowFullscreenStateChanged();
[email protected]9adb8b12011-12-09 06:49:131420 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1421 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
[email protected]ae2622c2009-07-30 23:47:581422}
1423
[email protected]36b6dcb2008-11-12 01:19:571424///////////////////////////////////////////////////////////////////////////////
1425// Browser, Assorted browser commands:
1426
[email protected]cb84d642010-06-10 00:56:281427TabContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291428 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491429 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]bbafdc72011-07-06 22:27:171430 switch (disposition) {
1431 case NEW_FOREGROUND_TAB:
1432 case NEW_BACKGROUND_TAB: {
1433 current_tab = current_tab->Clone();
1434 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]2905f742011-10-13 03:51:581435 current_tab, -1, content::PAGE_TRANSITION_LINK,
[email protected]bbafdc72011-07-06 22:27:171436 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
1437 TabStripModel::ADD_NONE);
1438 break;
1439 }
1440 case NEW_WINDOW: {
1441 current_tab = current_tab->Clone();
1442 Browser* browser = Browser::Create(profile_);
1443 browser->tabstrip_model()->AddTabContents(
[email protected]2905f742011-10-13 03:51:581444 current_tab, -1, content::PAGE_TRANSITION_LINK,
1445 TabStripModel::ADD_ACTIVE);
[email protected]bbafdc72011-07-06 22:27:171446 browser->window()->Show();
1447 break;
1448 }
1449 default:
1450 break;
[email protected]3698f172010-03-17 20:50:291451 }
[email protected]3c9e1872010-11-18 16:17:491452 return current_tab->tab_contents();
[email protected]3698f172010-03-17 20:50:291453}
1454
[email protected]018cf362010-05-05 22:43:221455bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1456 bool check_fullscreen) const {
1457 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1458 // other platforms, we hide some controls when in fullscreen mode.
1459 bool hide_ui_for_fullscreen = false;
1460#if !defined(OS_MACOSX)
1461 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1462 window_->IsFullscreen();
1463#endif
1464
[email protected]8b8e7c92010-08-19 18:05:561465 unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
[email protected]018cf362010-05-05 22:43:221466
[email protected]eab8c0f2011-11-18 22:33:501467#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]018cf362010-05-05 22:43:221468 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1469 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1470 features |= FEATURE_DOWNLOADSHELF;
[email protected]eab8c0f2011-11-18 22:33:501471#endif // !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]018cf362010-05-05 22:43:221472
[email protected]b35b26b32011-05-05 20:35:141473 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221474 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221475
1476 if (!hide_ui_for_fullscreen) {
[email protected]b35b26b32011-05-05 20:35:141477 if (!is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221478 features |= FEATURE_TITLEBAR;
1479
[email protected]b35b26b32011-05-05 20:35:141480 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221481 features |= FEATURE_TABSTRIP;
1482
[email protected]b35b26b32011-05-05 20:35:141483 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221484 features |= FEATURE_TOOLBAR;
1485
[email protected]b35b26b32011-05-05 20:35:141486 if (!is_app())
[email protected]018cf362010-05-05 22:43:221487 features |= FEATURE_LOCATIONBAR;
1488 }
1489 return !!(features & feature);
1490}
1491
[email protected]0b4d3382010-07-14 16:13:041492bool Browser::IsClosingPermitted() {
1493 TabCloseableStateWatcher* watcher =
1494 g_browser_process->tab_closeable_state_watcher();
1495 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1496 if (!can_close && is_attempting_to_close_browser_)
1497 CancelWindowClose();
1498 return can_close;
1499}
1500
[email protected]43c9dc722011-08-20 02:05:091501bool Browser::CanGoBack() const {
[email protected]4a63e242011-12-12 15:23:081502 return GetSelectedTabContentsWrapper()->
[email protected]10b833e2011-12-21 17:36:301503 tab_contents()->controller().CanGoBack();
[email protected]43c9dc722011-08-20 02:05:091504}
1505
[email protected]485fba42009-03-24 23:27:291506void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381507 content::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271508
[email protected]3c9e1872010-11-18 16:17:491509 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]43c9dc722011-08-20 02:05:091510 if (CanGoBack()) {
[email protected]cb84d642010-06-10 00:56:281511 TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061512 // If we are on an interstitial page and clone the tab, it won't be copied
1513 // to the new tab, so we don't need to go back.
[email protected]3c9e1872010-11-18 16:17:491514 if (current_tab->tab_contents()->showing_interstitial_page() &&
1515 (new_tab != current_tab->tab_contents()))
[email protected]d497b0782010-03-29 19:19:061516 return;
[email protected]10b833e2011-12-21 17:36:301517 new_tab->controller().GoBack();
[email protected]485fba42009-03-24 23:27:291518 }
[email protected]36b6dcb2008-11-12 01:19:571519}
1520
[email protected]43c9dc722011-08-20 02:05:091521bool Browser::CanGoForward() const {
[email protected]4a63e242011-12-12 15:23:081522 return GetSelectedTabContentsWrapper()->
[email protected]10b833e2011-12-21 17:36:301523 tab_contents()->controller().CanGoForward();
[email protected]43c9dc722011-08-20 02:05:091524}
1525
[email protected]3698f172010-03-17 20:50:291526void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381527 content::RecordAction(UserMetricsAction("Forward"));
[email protected]43c9dc722011-08-20 02:05:091528 if (CanGoForward())
[email protected]10b833e2011-12-21 17:36:301529 GetOrCloneTabForDisposition(disposition)->controller().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571530}
1531
[email protected]cb84d642010-06-10 00:56:281532void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381533 content::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281534 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161535}
[email protected]fbd77592008-11-12 20:50:271536
[email protected]cb84d642010-06-10 00:56:281537void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381538 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281539 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161540}
1541
[email protected]cb84d642010-06-10 00:56:281542void Browser::ReloadInternal(WindowOpenDisposition disposition,
1543 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571544 // If we are showing an interstitial, treat this as an OpenURL.
1545 TabContents* current_tab = GetSelectedTabContents();
[email protected]cb84d642010-06-10 00:56:281546 if (current_tab && current_tab->showing_interstitial_page()) {
[email protected]10b833e2011-12-21 17:36:301547 NavigationEntry* entry = current_tab->controller().GetActiveEntry();
[email protected]cb84d642010-06-10 00:56:281548 DCHECK(entry); // Should exist if interstitial is showing.
[email protected]2905f742011-10-13 03:51:581549 OpenURL(entry->url(), GURL(), disposition, content::PAGE_TRANSITION_RELOAD);
[email protected]cb84d642010-06-10 00:56:281550 return;
[email protected]36b6dcb2008-11-12 01:19:571551 }
[email protected]cb84d642010-06-10 00:56:281552
1553 // As this is caused by a user action, give the focus to the page.
[email protected]3c9e1872010-11-18 16:17:491554 TabContents* tab = GetOrCloneTabForDisposition(disposition);
1555 if (!tab->FocusLocationBarByDefault())
1556 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281557 if (ignore_cache)
[email protected]10b833e2011-12-21 17:36:301558 tab->controller().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281559 else
[email protected]10b833e2011-12-21 17:36:301560 tab->controller().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571561}
1562
[email protected]485fba42009-03-24 23:27:291563void Browser::Home(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381564 content::RecordAction(UserMetricsAction("Home"));
[email protected]2905f742011-10-13 03:51:581565 OpenURL(
[email protected]671f9c62011-10-28 19:22:071566 profile_->GetHomePage(), GURL(), disposition,
[email protected]2905f742011-10-13 03:51:581567 content::PageTransitionFromInt(
1568 content::PAGE_TRANSITION_AUTO_BOOKMARK |
1569 content::PAGE_TRANSITION_HOME_PAGE));
[email protected]36b6dcb2008-11-12 01:19:571570}
1571
[email protected]fbd77592008-11-12 20:50:271572void Browser::OpenCurrentURL() {
[email protected]7f6f44c2011-12-14 13:23:381573 content::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351574 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491575 if (!location_bar)
1576 return;
1577
[email protected]9d0306ea2009-09-02 19:38:391578 WindowOpenDisposition open_disposition =
1579 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271580 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301581 return;
[email protected]03bb953d2010-09-14 21:38:301582
[email protected]537de682011-08-08 18:10:141583 GURL url(location_bar->GetInputString());
[email protected]07d490bc2011-03-07 17:05:261584
1585 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1586 Browser* existing_browser = NULL;
1587 TabContents* existing_tab = TabFinder::GetInstance()->FindTab(
1588 this, url, &existing_browser);
1589 if (existing_tab) {
1590 existing_browser->ActivateContents(existing_tab);
1591 return;
1592 }
1593 }
1594
[email protected]616381f02010-11-02 15:15:331595 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1596 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251597 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1598 // inherit the opener. In some cases the tabstrip will determine the group
1599 // should be inherited, in which case the group is inherited instead of the
1600 // opener.
[email protected]616381f02010-11-02 15:15:331601 params.tabstrip_add_types =
1602 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1603 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331604
[email protected]6e37fe32011-03-02 09:06:521605 DCHECK(profile_->GetExtensionService());
1606 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:331607 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1608 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1609 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1610 }
[email protected]fbd77592008-11-12 20:50:271611}
1612
[email protected]84214982008-12-10 18:49:101613void Browser::Stop() {
[email protected]7f6f44c2011-12-14 13:23:381614 content::RecordAction(UserMetricsAction("Stop"));
[email protected]3c9e1872010-11-18 16:17:491615 GetSelectedTabContentsWrapper()->tab_contents()->Stop();
[email protected]84214982008-12-10 18:49:101616}
1617
1618void Browser::NewWindow() {
[email protected]4e94ab32011-08-05 05:28:271619 IncognitoModePrefs::Availability incognito_avail =
1620 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
[email protected]047e7272010-06-03 19:53:351621 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
[email protected]4e94ab32011-08-05 05:28:271622 incognito_avail != IncognitoModePrefs::DISABLED &&
[email protected]6b0dd2ab2011-07-26 02:31:081623 (CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito) ||
[email protected]4e94ab32011-08-05 05:28:271624 incognito_avail == IncognitoModePrefs::FORCED)) {
[email protected]047e7272010-06-03 19:53:351625 NewIncognitoWindow();
1626 return;
1627 }
[email protected]7f6f44c2011-12-14 13:23:381628 content::RecordAction(UserMetricsAction("NewWindow"));
[email protected]c9b19942010-03-26 15:58:081629 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:151630 SessionServiceFactory::GetForProfile(profile_->GetOriginalProfile());
[email protected]c9b19942010-03-26 15:58:081631 if (!session_service ||
1632 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1633 Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1634 }
[email protected]84214982008-12-10 18:49:101635}
1636
1637void Browser::NewIncognitoWindow() {
[email protected]4e94ab32011-08-05 05:28:271638 if (IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) ==
1639 IncognitoModePrefs::DISABLED) {
[email protected]6e6f6cb2011-01-27 13:26:551640 NewWindow();
1641 return;
1642 }
1643
[email protected]7f6f44c2011-12-14 13:23:381644 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]84214982008-12-10 18:49:101645 Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1646}
1647
[email protected]84214982008-12-10 18:49:101648void Browser::CloseWindow() {
[email protected]7f6f44c2011-12-14 13:23:381649 content::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101650 window_->Close();
1651}
1652
[email protected]fbd77592008-11-12 20:50:271653void Browser::NewTab() {
[email protected]7f6f44c2011-12-14 13:23:381654 content::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261655
[email protected]b35b26b32011-05-05 20:35:141656 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271657 AddBlankTab(true);
[email protected]d487beefe2011-12-21 05:41:211658 GetSelectedTabContentsWrapper()->tab_contents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271659 } else {
[email protected]1a6b30a2009-08-19 03:52:111660 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271661 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051662 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111663 // The call to AddBlankTab above did not set the focus to the tab as its
1664 // window was not active, so we have to do it explicitly.
1665 // See http://crbug.com/6380.
[email protected]d487beefe2011-12-21 05:41:211666 b->GetSelectedTabContentsWrapper()->tab_contents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271667 }
1668}
1669
1670void Browser::CloseTab() {
[email protected]7f6f44c2011-12-14 13:23:381671 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211672 if (CanCloseTab())
1673 tab_handler_->GetTabStripModel()->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271674}
1675
[email protected]fbd77592008-11-12 20:50:271676void Browser::SelectNextTab() {
[email protected]7f6f44c2011-12-14 13:23:381677 content::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]ecc523f62010-09-28 22:45:401678 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271679}
1680
1681void Browser::SelectPreviousTab() {
[email protected]7f6f44c2011-12-14 13:23:381682 content::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]ecc523f62010-09-28 22:45:401683 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271684}
1685
[email protected]91ac9202010-07-30 18:32:351686void Browser::OpenTabpose() {
1687#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031688 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1689 switches::kEnableExposeForTabs)) {
1690 return;
1691 }
1692
[email protected]7f6f44c2011-12-14 13:23:381693 content::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351694 window()->OpenTabpose();
1695#else
1696 NOTREACHED();
1697#endif
1698}
1699
[email protected]9ac7fcb2009-09-14 18:22:521700void Browser::MoveTabNext() {
[email protected]7f6f44c2011-12-14 13:23:381701 content::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]ecc523f62010-09-28 22:45:401702 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521703}
1704
1705void Browser::MoveTabPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381706 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]ecc523f62010-09-28 22:45:401707 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521708}
1709
[email protected]fbd77592008-11-12 20:50:271710void Browser::SelectNumberedTab(int index) {
1711 if (index < tab_count()) {
[email protected]7f6f44c2011-12-14 13:23:381712 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]eaca0ad12011-04-18 15:53:411713 tab_handler_->GetTabStripModel()->ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271714 }
1715}
1716
1717void Browser::SelectLastTab() {
[email protected]7f6f44c2011-12-14 13:23:381718 content::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]ecc523f62010-09-28 22:45:401719 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271720}
1721
1722void Browser::DuplicateTab() {
[email protected]7f6f44c2011-12-14 13:23:381723 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441724 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271725}
1726
1727void Browser::RestoreTab() {
[email protected]7f6f44c2011-12-14 13:23:381728 content::RecordAction(UserMetricsAction("RestoreTab"));
[email protected]92371eb2011-04-28 11:50:151729 TabRestoreService* service =
1730 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]fbd77592008-11-12 20:50:271731 if (!service)
1732 return;
1733
[email protected]fb7da4132011-03-15 15:51:001734 service->RestoreMostRecentEntry(tab_restore_service_delegate());
[email protected]fbd77592008-11-12 20:50:271735}
1736
[email protected]0c4c3882009-10-01 21:42:141737void Browser::WriteCurrentURLToClipboard() {
1738 // TODO(ericu): There isn't currently a metric for this. Should there be?
1739 // We don't appear to track the action when it comes from the
1740 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141741
1742 TabContents* contents = GetSelectedTabContents();
[email protected]cd8d90db2011-10-06 19:31:271743 if (!toolbar_model_.ShouldDisplayURL())
[email protected]0c4c3882009-10-01 21:42:141744 return;
1745
[email protected]90f39902009-10-03 04:25:371746 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141747 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171748 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141749 g_browser_process->clipboard());
1750}
1751
[email protected]fbd77592008-11-12 20:50:271752void Browser::ConvertPopupToTabbedBrowser() {
[email protected]7f6f44c2011-12-14 13:23:381753 content::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]1ea49d52011-04-12 17:44:441754 int tab_strip_index = tab_handler_->GetTabStripModel()->active_index();
[email protected]3c9e1872010-11-18 16:17:491755 TabContentsWrapper* contents =
[email protected]ecc523f62010-09-28 22:45:401756 tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
[email protected]15952e462008-11-14 00:29:051757 Browser* browser = Browser::Create(profile_);
1758 browser->tabstrip_model()->AppendTabContents(contents, true);
1759 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271760}
1761
[email protected]55c87fa2011-10-15 07:28:281762// TODO(koz): Change |for_tab| to an enum.
1763void Browser::ToggleFullscreenMode(bool for_tab) {
[email protected]01a5a762011-11-21 05:40:551764 fullscreen_controller_->ToggleFullscreenMode(for_tab);
[email protected]9282cea2009-02-18 18:49:001765}
1766
[email protected]d3766932011-08-04 22:18:231767#if defined(OS_MACOSX)
[email protected]55c87fa2011-10-15 07:28:281768void Browser::TogglePresentationMode(bool for_tab) {
[email protected]01a5a762011-11-21 05:40:551769 fullscreen_controller_->TogglePresentationMode(for_tab);
[email protected]d3766932011-08-04 22:18:231770}
1771#endif
1772
[email protected]da17b372010-01-22 23:37:221773#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331774void Browser::Search() {
[email protected]64559862010-09-23 19:00:161775 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101776 if (window_->IsFullscreen()) {
[email protected]55c87fa2011-10-15 07:28:281777 ToggleFullscreenMode(false);
[email protected]ebdda9092010-10-22 17:59:101778 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1779 // visible at this point. Wait for next event cycle which toggles
1780 // the visibility of omnibox before creating new tab.
1781 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:361782 FROM_HERE, base::Bind(&Browser::Search, weak_factory_.GetWeakPtr()));
[email protected]ebdda9092010-10-22 17:59:101783 return;
1784 }
[email protected]64559862010-09-23 19:00:161785
[email protected]0080c4f2011-10-03 21:56:371786 const GURL& url = GetSelectedTabContents()->GetURL();
1787 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1788 url.host() == chrome::kChromeUINewTabHost) {
1789 // If the NTP is showing, focus the omnibox.
1790 window_->SetFocusToLocationBar(true);
1791 } else {
1792 // Otherwise, open the NTP.
1793 NewTab();
1794 }
[email protected]f97d7f632010-06-01 21:08:331795}
[email protected]d14af522010-12-02 03:54:501796
1797void Browser::ShowKeyboardOverlay() {
1798 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1799}
[email protected]20d17242009-10-26 20:21:051800#endif
1801
[email protected]fbd77592008-11-12 20:50:271802void Browser::Exit() {
[email protected]7f6f44c2011-12-14 13:23:381803 content::RecordAction(UserMetricsAction("Exit"));
[email protected]b8b60082011-12-13 14:16:021804 BrowserList::AttemptUserExit();
[email protected]fbd77592008-11-12 20:50:271805}
1806
[email protected]36b6dcb2008-11-12 01:19:571807void Browser::BookmarkCurrentPage() {
[email protected]7f6f44c2011-12-14 13:23:381808 content::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271809
[email protected]76624fde2009-10-09 18:13:231810 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571811 if (!model || !model->IsLoaded())
1812 return; // Ignore requests until bookmarks are loaded.
1813
[email protected]76624fde2009-10-09 18:13:231814 GURL url;
[email protected]261cd762010-08-20 05:45:371815 string16 title;
[email protected]b375c5d2011-05-03 21:15:041816 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
1817 bookmark_utils::GetURLAndTitleToBookmark(tab->tab_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441818 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211819 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321820 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211821 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041822 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211823 }
[email protected]4394f2b2011-09-03 03:07:561824 bookmark_utils::AddIfNotBookmarked(model, url, title);
[email protected]11dbbd22009-11-06 18:55:041825 // Make sure the model actually added a bookmark before showing the star. A
1826 // bookmark isn't created if the url is invalid.
1827 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271828 // Only show the bubble if the window is active, otherwise we may get into
1829 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441830 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271831 }
[email protected]36b6dcb2008-11-12 01:19:571832}
1833
[email protected]40bdb6d92009-02-25 00:22:271834void Browser::SavePage() {
[email protected]7f6f44c2011-12-14 13:23:381835 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]15d04ae2010-10-30 01:04:501836 TabContents* current_tab = GetSelectedTabContents();
1837 if (current_tab && current_tab->contents_mime_type() == "application/pdf")
[email protected]7f6f44c2011-12-14 13:23:381838 content::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]c7dd2f62011-07-18 15:57:591839 GetSelectedTabContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271840}
1841
[email protected]77d8d622010-12-15 10:30:121842void Browser::ViewSelectedSource() {
1843 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571844}
initial.commit09911bf2008-07-26 23:55:291845
[email protected]4801ecc2009-04-05 04:52:581846void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171847 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581848}
1849
[email protected]a3e18c42009-03-04 23:36:051850bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221851 return SupportsWindowFeatureImpl(feature, true);
1852}
[email protected]f5bf8ccf2010-02-05 18:19:251853
[email protected]018cf362010-05-05 22:43:221854bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1855 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051856}
1857
[email protected]89d6e6e2009-12-03 23:06:511858void Browser::EmailPageLocation() {
[email protected]7f6f44c2011-12-14 13:23:381859 content::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]d221a392011-05-24 14:34:241860 TabContents* tc = GetSelectedTabContents();
1861 DCHECK(tc);
1862
[email protected]4a19be92011-09-22 14:25:021863 std::string title = net::EscapeQueryParamValue(
1864 UTF16ToUTF8(tc->GetTitle()), false);
1865 std::string page_url = net::EscapeQueryParamValue(tc->GetURL().spec(), false);
[email protected]d221a392011-05-24 14:34:241866 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1867 title + "&body=%0A%0A" + page_url;
1868 platform_util::OpenExternal(GURL(mailto));
[email protected]89d6e6e2009-12-03 23:06:511869}
1870
[email protected]fbd77592008-11-12 20:50:271871void Browser::Print() {
[email protected]8980e0d2011-05-27 19:16:231872 if (switches::IsPrintPreviewEnabled())
1873 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1874 else
[email protected]49fe2262011-04-15 20:56:151875 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]fbd77592008-11-12 20:50:271876}
1877
[email protected]0996e9b2011-08-26 17:59:011878void Browser::AdvancedPrint() {
1879 GetSelectedTabContentsWrapper()->print_view_manager()->AdvancedPrintNow();
1880}
1881
[email protected]fbd77592008-11-12 20:50:271882void Browser::ToggleEncodingAutoDetect() {
[email protected]7f6f44c2011-12-14 13:23:381883 content::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271884 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181885 // If "auto detect" is turned on, then any current override encoding
1886 // is cleared. This also implicitly performs a reload.
1887 // OTOH, if "auto detect" is turned off, we don't change the currently
1888 // active encoding.
1889 if (encoding_auto_detect_.GetValue()) {
1890 TabContents* contents = GetSelectedTabContents();
1891 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081892 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181893 }
[email protected]fbd77592008-11-12 20:50:271894}
1895
1896void Browser::OverrideEncoding(int encoding_id) {
[email protected]7f6f44c2011-12-14 13:23:381897 content::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401898 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271899 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]57c6a652009-05-04 07:58:341900 TabContents* contents = GetSelectedTabContents();
1901 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081902 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271903 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401904 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191905 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1906 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401907 encoding_id,
1908 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271909 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191910 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271911 }
[email protected]36b6dcb2008-11-12 01:19:571912}
1913
[email protected]84214982008-12-10 18:49:101914void Browser::Cut() {
[email protected]7f6f44c2011-12-14 13:23:381915 content::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231916 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571917}
1918
[email protected]84214982008-12-10 18:49:101919void Browser::Copy() {
[email protected]7f6f44c2011-12-14 13:23:381920 content::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231921 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571922}
1923
[email protected]84214982008-12-10 18:49:101924void Browser::Paste() {
[email protected]7f6f44c2011-12-14 13:23:381925 content::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231926 window()->Paste();
[email protected]84214982008-12-10 18:49:101927}
1928
1929void Browser::Find() {
[email protected]7f6f44c2011-12-14 13:23:381930 content::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291931 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101932}
1933
1934void Browser::FindNext() {
[email protected]7f6f44c2011-12-14 13:23:381935 content::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291936 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101937}
1938
1939void Browser::FindPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381940 content::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291941 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101942}
1943
[email protected]54087fe2011-10-28 22:02:481944void Browser::Zoom(content::PageZoom zoom) {
[email protected]0bffaa322011-07-18 17:37:541945 if (is_devtools())
1946 return;
1947
[email protected]4a63e242011-12-12 15:23:081948 RenderViewHost* host =
[email protected]151a63d2011-12-20 22:32:521949 GetSelectedTabContentsWrapper()->tab_contents()->GetRenderViewHost();
[email protected]0f083402011-11-22 02:59:011950 if (zoom == content::PAGE_ZOOM_RESET) {
1951 host->SetZoomLevel(0);
[email protected]7f6f44c2011-12-14 13:23:381952 content::RecordAction(UserMetricsAction("ZoomNormal"));
[email protected]0f083402011-11-22 02:59:011953 return;
1954 }
[email protected]896220042010-03-23 18:14:281955
[email protected]0f083402011-11-22 02:59:011956 double current_zoom_level = GetSelectedTabContents()->GetZoomLevel();
1957 double default_zoom_level =
1958 profile_->GetPrefs()->GetDouble(prefs::kDefaultZoomLevel);
1959
1960 // Generate a vector of zoom levels from an array of known presets along with
1961 // the default level added if necessary.
1962 std::vector<double> zoom_levels =
1963 chrome_page_zoom::PresetZoomLevels(default_zoom_level);
1964
1965 if (zoom == content::PAGE_ZOOM_OUT) {
1966 // Iterate through the zoom levels in reverse order to find the next
1967 // lower level based on the current zoom level for this page.
1968 for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin();
1969 i != zoom_levels.rend(); ++i) {
1970 double zoom_level = *i;
1971 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
1972 continue;
1973 if (zoom_level < current_zoom_level) {
1974 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:381975 content::RecordAction(UserMetricsAction("ZoomMinus"));
[email protected]0f083402011-11-22 02:59:011976 return;
1977 }
[email protected]7f6f44c2011-12-14 13:23:381978 content::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum"));
[email protected]0f083402011-11-22 02:59:011979 }
1980 } else {
1981 // Iterate through the zoom levels in normal order to find the next
1982 // higher level based on the current zoom level for this page.
1983 for (std::vector<double>::const_iterator i = zoom_levels.begin();
1984 i != zoom_levels.end(); ++i) {
1985 double zoom_level = *i;
1986 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
1987 continue;
1988 if (zoom_level > current_zoom_level) {
1989 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:381990 content::RecordAction(UserMetricsAction("ZoomPlus"));
[email protected]0f083402011-11-22 02:59:011991 return;
1992 }
1993 }
[email protected]7f6f44c2011-12-14 13:23:381994 content::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum"));
[email protected]0f083402011-11-22 02:59:011995 }
[email protected]84214982008-12-10 18:49:101996}
1997
1998void Browser::FocusToolbar() {
[email protected]7f6f44c2011-12-14 13:23:381999 content::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:102000 window_->FocusToolbar();
2001}
2002
[email protected]bdb7ff62010-07-20 01:56:522003void Browser::FocusAppMenu() {
[email protected]7f6f44c2011-12-14 13:23:382004 content::RecordAction(UserMetricsAction("FocusAppMenu"));
[email protected]bdb7ff62010-07-20 01:56:522005 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:012006}
2007
[email protected]84214982008-12-10 18:49:102008void Browser::FocusLocationBar() {
[email protected]7f6f44c2011-12-14 13:23:382009 content::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:582010 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:102011}
2012
[email protected]83548a42010-06-18 13:53:372013void Browser::FocusBookmarksToolbar() {
[email protected]7f6f44c2011-12-14 13:23:382014 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:372015 window_->FocusBookmarksToolbar();
2016}
2017
2018void Browser::FocusChromeOSStatus() {
[email protected]7f6f44c2011-12-14 13:23:382019 content::RecordAction(UserMetricsAction("FocusChromeOSStatus"));
[email protected]83548a42010-06-18 13:53:372020 window_->FocusChromeOSStatus();
2021}
2022
2023void Browser::FocusNextPane() {
[email protected]7f6f44c2011-12-14 13:23:382024 content::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:372025 window_->RotatePaneFocus(true);
2026}
2027
2028void Browser::FocusPreviousPane() {
[email protected]7f6f44c2011-12-14 13:23:382029 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:372030 window_->RotatePaneFocus(false);
2031}
2032
[email protected]84214982008-12-10 18:49:102033void Browser::FocusSearch() {
2034 // TODO(beng): replace this with FocusLocationBar
[email protected]7f6f44c2011-12-14 13:23:382035 content::RecordAction(UserMetricsAction("FocusSearch"));
[email protected]7745b822009-01-27 20:15:352036 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:102037}
2038
2039void Browser::OpenFile() {
[email protected]7f6f44c2011-12-14 13:23:382040 content::RecordAction(UserMetricsAction("OpenFile"));
[email protected]84214982008-12-10 18:49:102041 if (!select_file_dialog_.get())
2042 select_file_dialog_ = SelectFileDialog::Create(this);
2043
[email protected]35896a32010-06-09 08:42:512044 const FilePath directory = profile_->last_selected_directory();
2045
[email protected]84214982008-12-10 18:49:102046 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:562047 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:102048 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:512049 string16(), directory,
[email protected]b949f1112009-04-12 20:03:082050 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]d9898912011-04-15 21:10:002051 GetSelectedTabContents(),
[email protected]d56bcd22009-03-16 19:51:562052 parent_window, NULL);
[email protected]84214982008-12-10 18:49:102053}
2054
2055void Browser::OpenCreateShortcutsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382056 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:472057#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:492058 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
2059 DCHECK(current_tab &&
2060 web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
2061 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:512062
[email protected]4a63e242011-12-12 15:23:082063 NavigationEntry* entry =
[email protected]10b833e2011-12-21 17:36:302064 current_tab->tab_contents()->controller().GetLastCommittedEntry();
[email protected]ed5431872009-11-17 08:39:512065 if (!entry)
2066 return;
2067
[email protected]eabfdae92009-12-11 06:13:512068 // RVH's GetApplicationInfo should not be called before it returns.
2069 DCHECK(pending_web_app_action_ == NONE);
2070 pending_web_app_action_ = CREATE_SHORTCUT;
2071
[email protected]a2cf65eb2010-01-18 08:20:382072 // Start fetching web app info for CreateApplicationShortcut dialog and show
2073 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]553602e12011-04-05 17:01:182074 current_tab->extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]98f6e022009-06-05 22:49:532075#else
2076 NOTIMPLEMENTED();
2077#endif
[email protected]36b6dcb2008-11-12 01:19:572078}
2079
[email protected]2a8a98122010-07-16 11:58:482080void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
[email protected]e3791ce92011-08-09 01:03:322081 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
[email protected]7f6f44c2011-12-14 13:23:382082 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
[email protected]e3791ce92011-08-09 01:03:322083 else
[email protected]7f6f44c2011-12-14 13:23:382084 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]e3791ce92011-08-09 01:03:322085
[email protected]aebdd072011-07-07 12:36:592086 DevToolsWindow::ToggleDevToolsWindow(
[email protected]151a63d2011-12-20 22:32:522087 GetSelectedTabContentsWrapper()->tab_contents()->GetRenderViewHost(),
[email protected]4a63e242011-12-12 15:23:082088 action);
[email protected]fbd77592008-11-12 20:50:272089}
2090
[email protected]adb6a84d2011-02-07 16:58:402091void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]7f6f44c2011-12-14 13:23:382092 content::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:402093 if (highlight_background_resources)
2094 window_->ShowBackgroundPages();
2095 else
2096 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:102097}
2098
[email protected]84214982008-12-10 18:49:102099void Browser::OpenBugReportDialog() {
[email protected]7f6f44c2011-12-14 13:23:382100 content::RecordAction(UserMetricsAction("ReportBug"));
[email protected]40916632011-07-02 01:11:012101 browser::ShowHtmlBugReportView(this, std::string(), 0);
[email protected]84214982008-12-10 18:49:102102}
[email protected]44b2c8852009-03-18 00:57:492103
[email protected]84214982008-12-10 18:49:102104void Browser::ToggleBookmarkBar() {
[email protected]7f6f44c2011-12-14 13:23:382105 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:102106 window_->ToggleBookmarkBar();
2107}
2108
[email protected]84214982008-12-10 18:49:102109void Browser::OpenBookmarkManager() {
[email protected]7f6f44c2011-12-14 13:23:382110 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
2111 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]0af8f132011-07-16 01:37:022112 ShowSingletonTabOverwritingNTP(
[email protected]a179fac72011-08-29 22:22:422113 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIBookmarksURL)));
[email protected]0af8f132011-07-16 01:37:022114}
2115
[email protected]4c9ee222011-08-17 19:51:352116void Browser::OpenBookmarkManagerWithHash(const std::string& action,
2117 int64 node_id) {
[email protected]7f6f44c2011-12-14 13:23:382118 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
2119 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]f6c13362011-08-16 12:39:522120 browser::NavigateParams params(GetSingletonTabNavigateParams(
2121 GURL(chrome::kChromeUIBookmarksURL).Resolve(
[email protected]4c9ee222011-08-17 19:51:352122 StringPrintf("/#%s%s", action.c_str(),
2123 base::Int64ToString(node_id).c_str()))));
[email protected]f6c13362011-08-16 12:39:522124 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2125 ShowSingletonTabOverwritingNTP(params);
[email protected]84214982008-12-10 18:49:102126}
[email protected]8bf80e922009-03-09 20:56:362127
[email protected]4c9ee222011-08-17 19:51:352128void Browser::OpenBookmarkManagerForNode(int64 node_id) {
2129 OpenBookmarkManagerWithHash("", node_id);
2130}
2131
2132void Browser::OpenBookmarkManagerEditNode(int64 node_id) {
2133 OpenBookmarkManagerWithHash("e=", node_id);
2134}
2135
[email protected]fdb98512009-08-26 01:37:102136void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:122137 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:102138 window_->ShowAppMenu();
2139}
2140
[email protected]7d2d08152011-10-25 22:58:472141void Browser::ShowAvatarMenu() {
2142 window_->ShowAvatarBubbleFromAvatarButton();
2143}
2144
[email protected]8bf80e922009-03-09 20:56:362145void Browser::ShowHistoryTab() {
[email protected]7f6f44c2011-12-14 13:23:382146 content::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]ddddfda2011-07-14 23:19:392147 ShowSingletonTabOverwritingNTP(
2148 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIHistoryURL)));
[email protected]8bf80e922009-03-09 20:56:362149}
[email protected]84214982008-12-10 18:49:102150
2151void Browser::ShowDownloadsTab() {
[email protected]7f6f44c2011-12-14 13:23:382152 content::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]efda32f92011-07-06 22:47:042153#if !defined(OS_CHROMEOS)
2154 // ChromiumOS uses ActiveDownloadsUI instead of of DownloadShelf.
[email protected]3d037ce72011-04-04 17:43:452155 if (window()) {
2156 DownloadShelf* shelf = window()->GetDownloadShelf();
2157 if (shelf->IsShowing())
2158 shelf->Close();
2159 }
[email protected]efda32f92011-07-06 22:47:042160#endif
[email protected]ddddfda2011-07-14 23:19:392161 ShowSingletonTabOverwritingNTP(
2162 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIDownloadsURL)));
[email protected]84214982008-12-10 18:49:102163}
2164
[email protected]34085a32009-11-06 22:49:482165void Browser::ShowExtensionsTab() {
[email protected]7f6f44c2011-12-14 13:23:382166 content::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]f98bcde52011-09-13 09:55:522167 ShowOptionsTab(chrome::kExtensionsSubPage);
[email protected]34085a32009-11-06 22:49:482168}
2169
[email protected]c1bbaa82010-11-08 11:17:052170void Browser::ShowAboutConflictsTab() {
[email protected]7f6f44c2011-12-14 13:23:382171 content::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:492172 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:052173}
2174
[email protected]10e457c2010-04-29 03:35:232175void Browser::ShowBrokenPageTab(TabContents* contents) {
[email protected]7f6f44c2011-12-14 13:23:382176 content::RecordAction(UserMetricsAction("ReportBug"));
[email protected]10e457c2010-04-29 03:35:232177 string16 page_title = contents->GetTitle();
[email protected]10b833e2011-12-21 17:36:302178 NavigationEntry* entry = contents->controller().GetActiveEntry();
[email protected]10e457c2010-04-29 03:35:232179 if (!entry)
2180 return;
2181 std::string page_url = entry->url().spec();
2182 std::vector<std::string> subst;
2183 subst.push_back(UTF16ToASCII(page_title));
2184 subst.push_back(page_url);
2185 std::string report_page_url =
2186 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:492187 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:232188}
2189
[email protected]12e816bde2010-09-14 19:59:292190void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]fcca741b2011-06-17 22:46:372191 browser::NavigateParams params(GetSingletonTabNavigateParams(
2192 GURL(chrome::kChromeUISettingsURL + sub_page)));
[email protected]fee320542011-03-02 01:30:492193 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
[email protected]fcca741b2011-06-17 22:46:372194
[email protected]ddddfda2011-07-14 23:19:392195 ShowSingletonTabOverwritingNTP(params);
[email protected]4a42d272010-06-18 01:29:422196}
2197
[email protected]84214982008-12-10 18:49:102198void Browser::OpenClearBrowsingDataDialog() {
[email protected]7f6f44c2011-12-14 13:23:382199 content::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:052200 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:102201}
2202
[email protected]84214982008-12-10 18:49:102203void Browser::OpenOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382204 content::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]fcca741b2011-06-17 22:46:372205 ShowOptionsTab("");
[email protected]fbd77592008-11-12 20:50:272206}
2207
2208void Browser::OpenPasswordManager() {
[email protected]7f6f44c2011-12-14 13:23:382209 content::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:042210 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272211}
2212
[email protected]1bdf29e2009-05-11 23:45:252213void Browser::OpenImportSettingsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382214 content::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052215 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252216}
[email protected]1bdf29e2009-05-11 23:45:252217
[email protected]b99081b2011-03-10 17:43:472218void Browser::OpenInstantConfirmDialog() {
2219 ShowOptionsTab(chrome::kInstantConfirmPage);
2220}
2221
[email protected]ca38d8e2009-08-20 18:08:162222void Browser::OpenSyncMyBookmarksDialog() {
[email protected]40f047972009-11-25 03:54:402223 sync_ui_util::OpenSyncMyBookmarksDialog(
[email protected]c8de64a2011-01-25 17:10:232224 profile_, this, ProfileSyncService::START_FROM_WRENCH);
[email protected]ca38d8e2009-08-20 18:08:162225}
[email protected]ca38d8e2009-08-20 18:08:162226
[email protected]fbd77592008-11-12 20:50:272227void Browser::OpenAboutChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382228 content::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]976e69f2010-08-13 18:28:172229#if defined(OS_CHROMEOS)
[email protected]01c3857e2011-06-09 04:35:482230 std::string chrome_settings(chrome::kChromeUISettingsURL);
2231 ShowSingletonTab(GURL(chrome_settings.append(chrome::kAboutOptionsSubPage)));
[email protected]976e69f2010-08-13 18:28:172232#else
[email protected]2d46c842008-11-14 19:24:312233 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:172234#endif
[email protected]fbd77592008-11-12 20:50:272235}
2236
[email protected]b1b73942010-05-26 20:11:542237void Browser::OpenUpdateChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382238 content::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542239 window_->ShowUpdateChromeDialog();
2240}
2241
[email protected]202802e42011-07-06 11:40:462242void Browser::ShowHelpTab() {
[email protected]7f6f44c2011-12-14 13:23:382243 content::RecordAction(UserMetricsAction("ShowHelpTab"));
[email protected]0a4a0be2010-11-09 10:42:472244 GURL help_url(kHelpContentUrl);
[email protected]0a4a0be2010-11-09 10:42:472245 GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
[email protected]202802e42011-07-06 11:40:462246 ShowSingletonTab(localized_help_url);
[email protected]fbd77592008-11-12 20:50:272247}
2248
[email protected]31cc1c022010-10-15 20:03:472249void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]3e0505452010-11-02 21:45:242250 OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
[email protected]2905f742011-10-13 03:51:582251 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK);
[email protected]31cc1c022010-10-15 20:03:472252 window_->Activate();
2253}
2254
[email protected]663bd9e2011-03-21 01:07:012255void Browser::OpenAutofillHelpTabAndActivate() {
[email protected]91a79232010-11-10 18:15:082256 GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
[email protected]2905f742011-10-13 03:51:582257 AddSelectedTabWithURL(help_url, content::PAGE_TRANSITION_LINK);
[email protected]bb8fe2d2010-06-28 20:04:222258}
2259
[email protected]024617a2010-08-20 05:08:052260void Browser::OpenSearchEngineOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382261 content::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052262 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052263}
2264
[email protected]45c52c9d2011-07-19 12:08:142265#if defined(FILE_MANAGER_EXTENSION)
[email protected]ec2fd5a2011-04-30 06:16:052266void Browser::OpenFileManager() {
[email protected]7f6f44c2011-12-14 13:23:382267 content::RecordAction(UserMetricsAction("OpenFileManager"));
[email protected]7ffb1612011-09-03 00:11:282268 ShowSingletonTabRespectRef(GURL(chrome::kChromeUIFileManagerURL));
[email protected]ec2fd5a2011-04-30 06:16:052269}
[email protected]45c52c9d2011-07-19 12:08:142270#endif
[email protected]ec2fd5a2011-04-30 06:16:052271
[email protected]45c52c9d2011-07-19 12:08:142272#if defined(OS_CHROMEOS)
[email protected]05a44b6e2011-12-01 07:52:322273void Browser::LockScreen() {
[email protected]7f6f44c2011-12-14 13:23:382274 content::RecordAction(UserMetricsAction("LockScreen"));
[email protected]b0cfc1c2011-12-15 13:16:192275 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
[email protected]05a44b6e2011-12-01 07:52:322276 NotifyScreenLockRequested();
2277}
2278
[email protected]2166c432011-12-07 20:18:282279void Browser::Shutdown() {
[email protected]7f6f44c2011-12-14 13:23:382280 content::RecordAction(UserMetricsAction("Shutdown"));
[email protected]2166c432011-12-07 20:18:282281 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
2282 RequestShutdown();
2283}
2284
[email protected]5dcbc02f2010-01-26 22:32:062285void Browser::OpenSystemOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382286 content::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"));
[email protected]445177652011-03-09 02:04:052287 ShowOptionsTab(chrome::kSystemOptionsSubPage);
[email protected]5dcbc02f2010-01-26 22:32:062288}
2289
2290void Browser::OpenInternetOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382291 content::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"));
[email protected]445177652011-03-09 02:04:052292 ShowOptionsTab(chrome::kInternetOptionsSubPage);
[email protected]024617a2010-08-20 05:08:052293}
2294
2295void Browser::OpenLanguageOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382296 content::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"));
[email protected]445177652011-03-09 02:04:052297 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
[email protected]be715072009-07-07 15:43:202298}
[email protected]46b92f852010-10-06 13:12:052299
2300void Browser::OpenSystemTabAndActivate() {
2301 OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
[email protected]2905f742011-10-13 03:51:582302 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK);
[email protected]46b92f852010-10-06 13:12:052303 window_->Activate();
2304}
2305
[email protected]38017612010-10-13 18:46:002306void Browser::OpenMobilePlanTabAndActivate() {
[email protected]e7137b2c2011-10-24 20:16:552307 if (CommandLine::ForCurrentProcess()->HasSwitch(
2308 switches::kEnableMobileSetupDialog)) {
2309 window_->ShowMobileSetup();
2310 } else {
2311 OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
2312 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK);
2313 window_->Activate();
2314 }
[email protected]38017612010-10-13 18:46:002315}
[email protected]be715072009-07-07 15:43:202316#endif
2317
[email protected]a003d8e2010-10-02 21:03:352318void Browser::OpenPluginsTabAndActivate() {
[email protected]37ae3f22011-07-12 03:56:142319 OpenURL(GURL(chrome::kChromeUIPluginsURL), GURL(),
[email protected]2905f742011-10-13 03:51:582320 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK);
[email protected]a003d8e2010-10-02 21:03:352321 window_->Activate();
2322}
2323
[email protected]36b6dcb2008-11-12 01:19:572324///////////////////////////////////////////////////////////////////////////////
2325
2326// static
[email protected]79117172009-08-28 16:11:442327void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542328 const PrefService::Preference* home_page_pref =
2329 prefs->FindPreference(prefs::kHomePage);
2330 if (home_page_pref &&
2331 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192332 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:332333 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:192334 GoogleURLTracker::kDefaultGoogleHomepage);
2335 }
[email protected]8fe6e1c2010-05-27 08:21:542336 const PrefService::Preference* home_page_is_new_tab_page_pref =
2337 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2338 if (home_page_is_new_tab_page_pref &&
2339 !home_page_is_new_tab_page_pref->IsManaged() &&
2340 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332341 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442342}
2343
2344// static
[email protected]36b6dcb2008-11-12 01:19:572345void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572346 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]8b8e7c92010-08-19 18:05:562347 prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
[email protected]d9898912011-04-15 21:10:002348 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]4e72ebb2011-10-18 05:02:182349 prefs->RegisterBooleanPref(prefs::kShouldShowFirstRunBubble, false);
[email protected]36b6dcb2008-11-12 01:19:572350}
2351
2352// static
2353void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182354 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]d36f941b2011-05-09 06:19:162355 chrome::kChromeUINewTabURL,
2356 PrefService::SYNCABLE_PREF);
[email protected]6c6b02d2011-09-02 03:36:472357 prefs->RegisterBooleanPref(prefs::kHomePageChanged,
2358 false,
2359 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162360 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2361 true,
2362 PrefService::SYNCABLE_PREF);
2363 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2364 false,
2365 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092366#if defined(OS_MACOSX)
2367 // This really belongs in platform code, but there's no good place to
2368 // initialize it between the time when the AppController is created
2369 // (where there's no profile) and the time the controller gets another
2370 // crack at the start of the main event loop. By that time, BrowserInit
2371 // has already created the browser window, and it's too late: we need the
2372 // pref to be already initialized. Doing it here also saves us from having
2373 // to hard-code pref registration in the several unit tests that use
2374 // this preference.
[email protected]d36f941b2011-05-09 06:19:162375 prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
2376 false,
2377 PrefService::SYNCABLE_PREF);
2378 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2379 true,
2380 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092381#endif
[email protected]d36f941b2011-05-09 06:19:162382 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2383 true,
2384 PrefService::SYNCABLE_PREF);
2385 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2386 true,
2387 PrefService::SYNCABLE_PREF);
2388 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2389 true,
2390 PrefService::SYNCABLE_PREF);
2391 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2392 true,
2393 PrefService::SYNCABLE_PREF);
2394 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2395 false,
2396 PrefService::SYNCABLE_PREF);
2397 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2398 false,
2399 PrefService::SYNCABLE_PREF);
2400 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2401 0,
2402 PrefService::SYNCABLE_PREF);
2403 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2404 true,
2405 PrefService::UNSYNCABLE_PREF);
2406 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2407 true,
2408 PrefService::UNSYNCABLE_PREF);
2409 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2410 true,
2411 PrefService::UNSYNCABLE_PREF);
2412 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2413 true,
2414 PrefService::UNSYNCABLE_PREF);
2415 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2416 true,
2417 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162418 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2419 true,
2420 PrefService::SYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162421 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2422 std::string(),
2423 PrefService::UNSYNCABLE_PREF);
2424 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2425 true,
2426 PrefService::UNSYNCABLE_PREF);
[email protected]1af419c2011-10-31 23:45:412427 prefs->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled,
2428 true,
2429 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162430 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2431 false,
2432 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162433 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
2434 -1,
2435 PrefService::UNSYNCABLE_PREF);
2436 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2437 PrefService::UNSYNCABLE_PREF);
2438 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2439 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122440 prefs->RegisterBooleanPref(prefs::kImportBookmarks,
2441 true,
2442 PrefService::UNSYNCABLE_PREF);
2443 prefs->RegisterBooleanPref(prefs::kImportHistory,
2444 true,
2445 PrefService::UNSYNCABLE_PREF);
2446 prefs->RegisterBooleanPref(prefs::kImportHomepage,
2447 true,
2448 PrefService::UNSYNCABLE_PREF);
2449 prefs->RegisterBooleanPref(prefs::kImportSearchEngine,
2450 true,
2451 PrefService::UNSYNCABLE_PREF);
2452 prefs->RegisterBooleanPref(prefs::kImportSavedPasswords,
2453 true,
2454 PrefService::UNSYNCABLE_PREF);
[email protected]f6e680912011-09-21 20:26:192455 // The map of timestamps of the last used file browser handlers.
2456 prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers,
2457 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122458
[email protected]2bf2bd92011-03-31 07:12:442459 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162460 // them even though they're only typically controlled via policy.
2461 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2462 false,
2463 PrefService::UNSYNCABLE_PREF);
2464 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2465 false,
2466 PrefService::UNSYNCABLE_PREF);
2467 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2468 false,
2469 PrefService::UNSYNCABLE_PREF);
2470 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2471 true,
2472 PrefService::UNSYNCABLE_PREF);
2473 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2474 true,
2475 PrefService::UNSYNCABLE_PREF);
[email protected]781be952011-08-31 20:22:142476 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled,
2477 true,
2478 PrefService::UNSYNCABLE_PREF);
[email protected]80b07612011-12-12 16:04:302479 prefs->RegisterBooleanPref(prefs::kEnableMemoryInfo,
2480 false,
2481 PrefService::UNSYNCABLE_PREF);
[email protected]f2df3112011-11-18 10:21:482482
2483 // Initialize the disk cache prefs.
2484 prefs->RegisterFilePathPref(prefs::kDiskCacheDir,
2485 FilePath(),
2486 PrefService::UNSYNCABLE_PREF);
2487 prefs->RegisterIntegerPref(prefs::kDiskCacheSize,
2488 0,
2489 PrefService::UNSYNCABLE_PREF);
2490 prefs->RegisterIntegerPref(prefs::kMediaCacheSize,
2491 0,
2492 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572493}
2494
2495// static
[email protected]ecc523f62010-09-28 22:45:402496bool Browser::RunUnloadEventsHelper(TabContents* contents) {
2497 // If the TabContents is not connected yet, then there's no unload
2498 // handler we can fire even if the TabContents has an unload listener.
2499 // One case where we hit this is in a tab that has an infinite loop
2500 // before load.
[email protected]5aab5e22010-12-08 22:13:292501 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402502 // If the page has unload listeners, then we tell the renderer to fire
2503 // them. Once they have fired, we'll get a message back saying whether
2504 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292505 // with the NeedToFireBeforeUnload bit cleared.
[email protected]151a63d2011-12-20 22:32:522506 contents->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]ecc523f62010-09-28 22:45:402507 return true;
2508 }
2509 return false;
2510}
2511
2512// static
[email protected]36b6dcb2008-11-12 01:19:572513Browser* Browser::GetBrowserForController(
2514 const NavigationController* controller, int* index_result) {
2515 BrowserList::const_iterator it;
2516 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]ecc523f62010-09-28 22:45:402517 int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
2518 controller);
[email protected]36b6dcb2008-11-12 01:19:572519 if (index != TabStripModel::kNoTab) {
2520 if (index_result)
2521 *index_result = index;
2522 return *it;
2523 }
2524 }
2525
2526 return NULL;
2527}
2528
[email protected]3a29a6e2011-08-24 18:26:212529// static
2530void Browser::RunFileChooserHelper(
[email protected]8caadeb2011-11-22 02:45:232531 TabContents* tab, const content::FileChooserParams& params) {
[email protected]3a29a6e2011-08-24 18:26:212532 Profile* profile =
2533 Profile::FromBrowserContext(tab->browser_context());
[email protected]9f054aa12011-09-29 19:13:452534 // FileSelectHelper adds a reference to itself and only releases it after
2535 // sending the result message. It won't be destroyed when this reference
2536 // goes out of scope.
2537 scoped_refptr<FileSelectHelper> file_select_helper(
2538 new FileSelectHelper(profile));
[email protected]151a63d2011-12-20 22:32:522539 file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params);
[email protected]3a29a6e2011-08-24 18:26:212540}
2541
2542// static
2543void Browser::EnumerateDirectoryHelper(TabContents* tab, int request_id,
2544 const FilePath& path) {
2545 ChildProcessSecurityPolicy* policy =
2546 ChildProcessSecurityPolicy::GetInstance();
[email protected]151a63d2011-12-20 22:32:522547 if (!policy->CanReadDirectory(tab->GetRenderProcessHost()->GetID(), path))
[email protected]3a29a6e2011-08-24 18:26:212548 return;
[email protected]3a29a6e2011-08-24 18:26:212549
2550 Profile* profile =
2551 Profile::FromBrowserContext(tab->browser_context());
[email protected]9f054aa12011-09-29 19:13:452552 // FileSelectHelper adds a reference to itself and only releases it after
2553 // sending the result message. It won't be destroyed when this reference
2554 // goes out of scope.
2555 scoped_refptr<FileSelectHelper> file_select_helper(
2556 new FileSelectHelper(profile));
[email protected]3a29a6e2011-08-24 18:26:212557 file_select_helper->EnumerateDirectory(request_id,
[email protected]151a63d2011-12-20 22:32:522558 tab->GetRenderViewHost(),
[email protected]3a29a6e2011-08-24 18:26:212559 path);
2560}
2561
[email protected]7d189022011-08-25 22:54:202562// static
2563void Browser::JSOutOfMemoryHelper(TabContents* tab) {
2564 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2565 tab);
2566 if (tcw) {
[email protected]95a33ed62011-09-30 15:07:082567 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2568 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
2569 infobar_helper,
2570 NULL,
2571 l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT),
[email protected]7d189022011-08-25 22:54:202572 true));
2573 }
2574}
2575
2576// static
2577void Browser::RegisterProtocolHandlerHelper(TabContents* tab,
2578 const std::string& protocol,
2579 const GURL& url,
2580 const string16& title) {
2581 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2582 tab);
2583 if (!tcw || tcw->profile()->IsOffTheRecord())
2584 return;
2585
2586 ChildProcessSecurityPolicy* policy =
2587 ChildProcessSecurityPolicy::GetInstance();
2588 if (policy->IsPseudoScheme(protocol) || policy->IsDisabledScheme(protocol))
2589 return;
2590
2591 ProtocolHandler handler =
2592 ProtocolHandler::CreateProtocolHandler(protocol, url, title);
2593
2594 ProtocolHandlerRegistry* registry =
2595 tcw->profile()->GetProtocolHandlerRegistry();
[email protected]7d189022011-08-25 22:54:202596
[email protected]a50af292011-10-25 03:07:402597 if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) {
[email protected]7f6f44c2011-12-14 13:23:382598 content::RecordAction(
[email protected]7d189022011-08-25 22:54:202599 UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown"));
[email protected]95a33ed62011-09-30 15:07:082600 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2601 infobar_helper->AddInfoBar(
2602 new RegisterProtocolHandlerInfoBarDelegate(infobar_helper,
2603 registry,
2604 handler));
[email protected]7d189022011-08-25 22:54:202605 }
2606}
2607
2608// static
2609void Browser::RegisterIntentHandlerHelper(TabContents* tab,
2610 const string16& action,
2611 const string16& type,
2612 const string16& href,
[email protected]63c239322011-10-31 23:56:302613 const string16& title,
2614 const string16& disposition) {
[email protected]8229b5e2011-11-18 05:49:562615 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents))
2616 return;
2617
[email protected]7d189022011-08-25 22:54:202618 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2619 tab);
2620 if (!tcw || tcw->profile()->IsOffTheRecord())
2621 return;
2622
[email protected]8229b5e2011-11-18 05:49:562623 FaviconService* favicon_service =
2624 tcw->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
[email protected]7d189022011-08-25 22:54:202625
[email protected]8229b5e2011-11-18 05:49:562626 // |href| can be relative to originating URL. Resolve if necessary.
[email protected]7d189022011-08-25 22:54:202627 GURL service_url(href);
2628 if (!service_url.is_valid()) {
2629 const GURL& url = tab->GetURL();
2630 service_url = url.Resolve(href);
2631 }
2632
[email protected]56624422011-11-01 22:11:272633 webkit_glue::WebIntentServiceData service;
[email protected]ce9751942011-09-21 01:57:242634 service.service_url = service_url;
2635 service.action = action;
2636 service.type = type;
2637 service.title = title;
[email protected]63c239322011-10-31 23:56:302638 service.setDisposition(disposition);
2639
[email protected]3826a8a02011-11-11 17:03:312640 RegisterIntentHandlerInfoBarDelegate::MaybeShowIntentInfoBar(
2641 tcw->infobar_tab_helper(),
[email protected]95a33ed62011-09-30 15:07:082642 WebIntentsRegistryFactory::GetForProfile(tcw->profile()),
[email protected]8229b5e2011-11-18 05:49:562643 service,
2644 favicon_service,
2645 tab->GetURL());
[email protected]7d189022011-08-25 22:54:202646}
2647
2648// static
[email protected]b888919c2011-09-02 00:32:162649void Browser::FindReplyHelper(TabContents* tab,
2650 int request_id,
2651 int number_of_matches,
2652 const gfx::Rect& selection_rect,
2653 int active_match_ordinal,
2654 bool final_update) {
2655 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2656 tab);
2657 if (!tcw || !tcw->find_tab_helper())
2658 return;
2659
2660 tcw->find_tab_helper()->HandleFindReply(request_id, number_of_matches,
2661 selection_rect, active_match_ordinal,
2662 final_update);
2663}
2664
[email protected]d952a052011-09-06 18:42:452665// static
2666void Browser::CrashedPluginHelper(TabContents* tab,
2667 const FilePath& plugin_path) {
2668 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2669 tab);
2670 if (!tcw)
2671 return;
2672
2673 DCHECK(!plugin_path.value().empty());
2674
2675 string16 plugin_name = plugin_path.LossyDisplayName();
2676 webkit::WebPluginInfo plugin_info;
[email protected]88ca4912011-10-12 14:00:432677 if (PluginService::GetInstance()->GetPluginInfoByPath(
[email protected]d952a052011-09-06 18:42:452678 plugin_path, &plugin_info) &&
2679 !plugin_info.name.empty()) {
2680 plugin_name = plugin_info.name;
2681#if defined(OS_MACOSX)
2682 // Many plugins on the Mac have .plugin in the actual name, which looks
2683 // terrible, so look for that and strip it off if present.
2684 const std::string kPluginExtension = ".plugin";
2685 if (EndsWith(plugin_name, ASCIIToUTF16(kPluginExtension), true))
2686 plugin_name.erase(plugin_name.length() - kPluginExtension.length());
2687#endif // OS_MACOSX
2688 }
2689 gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
2690 IDR_INFOBAR_PLUGIN_CRASHED);
[email protected]95a33ed62011-09-30 15:07:082691 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2692 infobar_helper->AddInfoBar(
[email protected]d952a052011-09-06 18:42:452693 new SimpleAlertInfoBarDelegate(
[email protected]95a33ed62011-09-30 15:07:082694 infobar_helper,
[email protected]d952a052011-09-06 18:42:452695 icon,
2696 l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, plugin_name),
2697 true));
2698}
2699
2700// static
2701void Browser::UpdateTargetURLHelper(TabContents* tab, int32 page_id,
2702 const GURL& url) {
2703 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2704 tab);
2705 if (!tcw || !tcw->prerender_tab_helper())
2706 return;
2707 tcw->prerender_tab_helper()->UpdateTargetURL(page_id, url);
2708}
2709
[email protected]485fba42009-03-24 23:27:292710void Browser::ExecuteCommandWithDisposition(
2711 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142712 // No commands are enabled if there is not yet any selected tab.
2713 // TODO(pkasting): It seems like we should not need this, because either
2714 // most/all commands should not have been enabled yet anyway or the ones that
2715 // are enabled should be global, or safe themselves against having no selected
2716 // tab. However, Ben says he tried removing this before and got lots of
2717 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2718 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492719 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142720 return;
2721
[email protected]59c9f002010-11-19 00:38:052722 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2723 << id;
[email protected]36b6dcb2008-11-12 01:19:572724
[email protected]867125a02009-12-10 06:01:482725 // If command execution is blocked then just record the command and return.
2726 if (block_command_execution_) {
2727 // We actually only allow no more than one blocked command, otherwise some
2728 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062729 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482730 last_blocked_command_id_ = id;
2731 last_blocked_command_disposition_ = disposition;
2732 return;
2733 }
2734
[email protected]fbd77592008-11-12 20:50:272735 // The order of commands in this switch statement must match the function
2736 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572737 switch (id) {
[email protected]84214982008-12-10 18:49:102738 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282739 case IDC_BACK: GoBack(disposition); break;
2740 case IDC_FORWARD: GoForward(disposition); break;
2741 case IDC_RELOAD: Reload(disposition); break;
2742 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2743 case IDC_HOME: Home(disposition); break;
2744 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282745 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572746
[email protected]84214982008-12-10 18:49:102747 // Window management commands
[email protected]cb84d642010-06-10 00:56:282748 case IDC_NEW_WINDOW: NewWindow(); break;
2749 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282750 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2751 case IDC_NEW_TAB: NewTab(); break;
2752 case IDC_CLOSE_TAB: CloseTab(); break;
2753 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2754 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352755 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282756 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2757 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572758 case IDC_SELECT_TAB_0:
2759 case IDC_SELECT_TAB_1:
2760 case IDC_SELECT_TAB_2:
2761 case IDC_SELECT_TAB_3:
2762 case IDC_SELECT_TAB_4:
2763 case IDC_SELECT_TAB_5:
2764 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542765 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282766 break;
2767 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2768 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2769 case IDC_RESTORE_TAB: RestoreTab(); break;
2770 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2771 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
[email protected]55c87fa2011-10-15 07:28:282772 case IDC_FULLSCREEN: ToggleFullscreenMode(false); break;
[email protected]d3766932011-08-04 22:18:232773#if defined(OS_MACOSX)
[email protected]55c87fa2011-10-15 07:28:282774 case IDC_PRESENTATION_MODE: TogglePresentationMode(false); break;
[email protected]d3766932011-08-04 22:18:232775#endif
[email protected]cb84d642010-06-10 00:56:282776 case IDC_EXIT: Exit(); break;
[email protected]da17b372010-01-22 23:37:222777#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282778 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:502779 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052780#endif
[email protected]36b6dcb2008-11-12 01:19:572781
[email protected]84214982008-12-10 18:49:102782 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282783 case IDC_SAVE_PAGE: SavePage(); break;
2784 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2785 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122786 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282787 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2788 case IDC_PRINT: Print(); break;
[email protected]0996e9b2011-08-26 17:59:012789 case IDC_ADVANCED_PRINT: AdvancedPrint(); break;
[email protected]cb84d642010-06-10 00:56:282790 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572791 case IDC_ENCODING_UTF8:
2792 case IDC_ENCODING_UTF16LE:
2793 case IDC_ENCODING_ISO88591:
2794 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492795 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572796 case IDC_ENCODING_GB18030:
2797 case IDC_ENCODING_BIG5HKSCS:
2798 case IDC_ENCODING_BIG5:
2799 case IDC_ENCODING_KOREAN:
2800 case IDC_ENCODING_SHIFTJIS:
2801 case IDC_ENCODING_ISO2022JP:
2802 case IDC_ENCODING_EUCJP:
2803 case IDC_ENCODING_THAI:
2804 case IDC_ENCODING_ISO885915:
2805 case IDC_ENCODING_MACINTOSH:
2806 case IDC_ENCODING_ISO88592:
2807 case IDC_ENCODING_WINDOWS1250:
2808 case IDC_ENCODING_ISO88595:
2809 case IDC_ENCODING_WINDOWS1251:
2810 case IDC_ENCODING_KOI8R:
2811 case IDC_ENCODING_KOI8U:
2812 case IDC_ENCODING_ISO88597:
2813 case IDC_ENCODING_WINDOWS1253:
2814 case IDC_ENCODING_ISO88594:
2815 case IDC_ENCODING_ISO885913:
2816 case IDC_ENCODING_WINDOWS1257:
2817 case IDC_ENCODING_ISO88593:
2818 case IDC_ENCODING_ISO885910:
2819 case IDC_ENCODING_ISO885914:
2820 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572821 case IDC_ENCODING_WINDOWS1254:
2822 case IDC_ENCODING_ISO88596:
2823 case IDC_ENCODING_WINDOWS1256:
2824 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002825 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572826 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282827 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572828
[email protected]84214982008-12-10 18:49:102829 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282830 case IDC_CUT: Cut(); break;
2831 case IDC_COPY: Copy(); break;
2832 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102833
2834 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282835 case IDC_FIND: Find(); break;
2836 case IDC_FIND_NEXT: FindNext(); break;
2837 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102838
2839 // Zoom
[email protected]54087fe2011-10-28 22:02:482840 case IDC_ZOOM_PLUS: Zoom(content::PAGE_ZOOM_IN); break;
2841 case IDC_ZOOM_NORMAL: Zoom(content::PAGE_ZOOM_RESET); break;
2842 case IDC_ZOOM_MINUS: Zoom(content::PAGE_ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102843
2844 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282845 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2846 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2847 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522848 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372849 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
2850 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
2851 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2852 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102853
2854 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282855 case IDC_OPEN_FILE: OpenFile(); break;
2856 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482857 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2858 DEVTOOLS_TOGGLE_ACTION_NONE);
2859 break;
2860 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2861 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2862 break;
2863 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2864 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2865 break;
[email protected]adb6a84d2011-02-07 16:58:402866 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2867 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]1c41a932010-11-22 23:41:232868 case IDC_FEEDBACK: OpenBugReportDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492869
[email protected]cb84d642010-06-10 00:56:282870 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252871 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492872
[email protected]cb84d642010-06-10 00:56:282873 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2874 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]7d2d08152011-10-25 22:58:472875 case IDC_SHOW_AVATAR_MENU: ShowAvatarMenu(); break;
[email protected]cb84d642010-06-10 00:56:282876 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2877 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2878 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
2879 case IDC_SYNC_BOOKMARKS: OpenSyncMyBookmarksDialog(); break;
2880 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052881 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282882 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2883 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2884 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412885 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2886 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052887 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]202802e42011-07-06 11:40:462888 case IDC_HELP_PAGE: ShowHelpTab(); break;
[email protected]16779842009-07-08 23:45:292889#if defined(OS_CHROMEOS)
[email protected]05a44b6e2011-12-01 07:52:322890 case IDC_LOCK_SCREEN: LockScreen(); break;
[email protected]2166c432011-12-07 20:18:282891 case IDC_SHUTDOWN: Shutdown(); break;
[email protected]ec2fd5a2011-04-30 06:16:052892 case IDC_FILE_MANAGER: OpenFileManager(); break;
[email protected]cb84d642010-06-10 00:56:282893 case IDC_SYSTEM_OPTIONS: OpenSystemOptionsDialog(); break;
2894 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:052895 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:202896#endif
[email protected]2e2cacc2011-07-12 21:54:262897 case IDC_SHOW_SYNC_SETUP: ShowSyncSetup(); break;
[email protected]afcb43562011-09-02 23:33:382898 case IDC_TOGGLE_SPEECH_INPUT: ToggleSpeechInput(); break;
[email protected]d938aed92009-01-22 19:49:332899
[email protected]36b6dcb2008-11-12 01:19:572900 default:
[email protected]84214982008-12-10 18:49:102901 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272902 break;
[email protected]36b6dcb2008-11-12 01:19:572903 }
2904}
2905
[email protected]dee11352011-09-05 13:34:082906void Browser::ExecuteCommand(int id, int event_flags) {
2907 ExecuteCommandWithDisposition(
2908 id, browser::DispositionFromEventFlags(event_flags));
2909}
2910
[email protected]3ab6796d32010-12-21 23:56:072911bool Browser::ExecuteCommandIfEnabled(int id) {
2912 if (command_updater_.SupportsCommand(id) &&
2913 command_updater_.IsCommandEnabled(id)) {
2914 ExecuteCommand(id);
2915 return true;
2916 }
2917 return false;
2918}
2919
[email protected]06181422011-02-09 17:44:212920bool Browser::IsReservedCommandOrKey(int command_id,
2921 const NativeWebKeyboardEvent& event) {
[email protected]06181422011-02-09 17:44:212922#if defined(OS_CHROMEOS)
2923 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
2924 // aren't able to block Chrome from performing the standard actions for F1-F4
2925 // (F5-7 are grabbed by other X clients and hence don't need this protection,
2926 // and F8-10 are handled separately in Chrome via a GDK event filter, but
2927 // let's future-proof this).
2928 ui::KeyboardCode key_code =
[email protected]6a1ae6cd2011-02-11 20:06:092929 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]06181422011-02-09 17:44:212930 if (key_code == ui::VKEY_F1 ||
2931 key_code == ui::VKEY_F2 ||
2932 key_code == ui::VKEY_F3 ||
2933 key_code == ui::VKEY_F4 ||
2934 key_code == ui::VKEY_F5 ||
2935 key_code == ui::VKEY_F6 ||
2936 key_code == ui::VKEY_F7 ||
2937 key_code == ui::VKEY_F8 ||
2938 key_code == ui::VKEY_F9 ||
2939 key_code == ui::VKEY_F10) {
[email protected]6a1ae6cd2011-02-11 20:06:092940 return true;
[email protected]06181422011-02-09 17:44:212941 }
2942#endif
2943
[email protected]fa2d2ce22011-09-19 08:21:062944 if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN)
2945 return true;
[email protected]6a1ae6cd2011-02-11 20:06:092946 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:482947 command_id == IDC_CLOSE_WINDOW ||
2948 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2949 command_id == IDC_NEW_TAB ||
2950 command_id == IDC_NEW_WINDOW ||
2951 command_id == IDC_RESTORE_TAB ||
2952 command_id == IDC_SELECT_NEXT_TAB ||
2953 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:552954 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:332955 command_id == IDC_EXIT ||
2956 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:482957}
2958
2959void Browser::SetBlockCommandExecution(bool block) {
2960 block_command_execution_ = block;
2961 if (block) {
2962 last_blocked_command_id_ = -1;
2963 last_blocked_command_disposition_ = CURRENT_TAB;
2964 }
2965}
2966
2967int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2968 if (disposition)
2969 *disposition = last_blocked_command_disposition_;
2970 return last_blocked_command_id_;
2971}
2972
[email protected]3c9e1872010-11-18 16:17:492973void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]2905f742011-10-13 03:51:582974 content::PageTransition transition,
[email protected]19d9f3a2010-10-14 21:49:362975 bool user_initiated) {
2976 tabstrip_model()->TabNavigating(contents, transition);
2977
[email protected]3c9e1872010-11-18 16:17:492978 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:362979 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2980 // Forcibly reset the location bar if the url is going to change in the
2981 // current tab, since otherwise it won't discard any ongoing user edits,
2982 // since it doesn't realize this is a user-initiated action.
2983 window()->GetLocationBar()->Revert();
2984 }
2985
2986 if (GetStatusBubble())
2987 GetStatusBubble()->Hide();
2988
2989 // Update the location bar. This is synchronous. We specifically don't
2990 // update the load state since the load hasn't started yet and updating it
2991 // will put it out of sync with the actual state like whether we're
2992 // displaying a favicon, which controls the throbber. If we updated it here,
2993 // the throbber will show the default favicon for a split second when
2994 // navigating away from the new tab page.
[email protected]3c9e1872010-11-18 16:17:492995 ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
[email protected]19d9f3a2010-10-14 21:49:362996
2997 if (contents_is_selected)
[email protected]3c9e1872010-11-18 16:17:492998 contents->tab_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:362999}
3000
[email protected]36b6dcb2008-11-12 01:19:573001///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:403002// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:363003
[email protected]00c37fc2011-08-02 00:22:503004// TODO(adriansc): Remove this method once refactoring changed all call sites.
[email protected]992e4542011-07-20 23:09:253005TabContents* Browser::OpenURL(const GURL& url,
3006 const GURL& referrer,
3007 WindowOpenDisposition disposition,
[email protected]2905f742011-10-13 03:51:583008 content::PageTransition transition) {
[email protected]39c90bb2011-12-02 15:44:103009 // For specifying a referrer, use the version of OpenURL taking OpenURLParams.
3010 DCHECK(referrer.is_empty());
[email protected]bce1f1c2011-12-05 15:11:583011 return OpenURLFromTab(NULL, OpenURLParams(
3012 url, content::Referrer(), disposition, transition, false));
[email protected]00c37fc2011-08-02 00:22:503013}
3014
3015TabContents* Browser::OpenURL(const OpenURLParams& params) {
3016 return OpenURLFromTab(NULL, params);
[email protected]ecc523f62010-09-28 22:45:403017}
3018
3019///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:293020// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
3021
3022void Browser::ExecuteCommand(int id) {
3023 ExecuteCommandWithDisposition(id, CURRENT_TAB);
3024}
3025
3026///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:403027// Browser, TabHandlerDelegate implementation:
3028
3029Profile* Browser::GetProfile() const {
3030 return profile();
3031}
3032
3033Browser* Browser::AsBrowser() {
3034 return this;
3035}
3036
3037///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573038// Browser, TabStripModelDelegate implementation:
3039
[email protected]3c9e1872010-11-18 16:17:493040TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:583041 return AddBlankTabAt(-1, foreground);
3042}
3043
[email protected]3c9e1872010-11-18 16:17:493044TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:053045 // Time new tab page creation time. We keep track of the timing data in
3046 // TabContents, but we want to include the time it takes to create the
3047 // TabContents object too.
3048 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:333049 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
[email protected]2905f742011-10-13 03:51:583050 content::PAGE_TRANSITION_TYPED);
[email protected]616381f02010-11-02 15:15:333051 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
3052 params.tabstrip_index = index;
3053 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:493054 params.target_contents->tab_contents()->set_new_tab_start_time(
3055 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:333056 return params.target_contents;
[email protected]15952e462008-11-14 00:29:053057}
3058
[email protected]3c9e1872010-11-18 16:17:493059Browser* Browser::CreateNewStripWithContents(
3060 TabContentsWrapper* detached_contents,
3061 const gfx::Rect& window_bounds,
3062 const DockInfo& dock_info,
3063 bool maximize) {
[email protected]018cf362010-05-05 22:43:223064 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:063065
[email protected]5e495462008-11-20 23:07:413066 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:413067 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
3068 dock_info.AdjustOtherWindowBounds();
3069
[email protected]36b6dcb2008-11-12 01:19:573070 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:143071 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:413072 browser->set_override_bounds(new_window_bounds);
[email protected]400eaf82011-08-22 15:47:393073 browser->set_show_state(
3074 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
[email protected]9800de5e2011-03-11 18:19:493075 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:053076 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:273077 // Make sure the loading state is updated correctly, otherwise the throbber
3078 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:493079 browser->LoadingStateChanged(detached_contents->tab_contents());
[email protected]3d1104f2009-03-26 15:30:283080 return browser;
[email protected]36b6dcb2008-11-12 01:19:573081}
3082
3083int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:403084 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
3085 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:573086}
3087
[email protected]3c9e1872010-11-18 16:17:493088TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]3ebe558b2011-12-06 08:05:083089 const GURL& url, const content::Referrer& referrer, Profile* profile,
[email protected]2905f742011-10-13 03:51:583090 content::PageTransition transition, bool defer_load,
[email protected]36b6dcb2008-11-12 01:19:573091 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:493092 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:403093 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:493094 GetSelectedTabContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:573095 if (!defer_load) {
3096 // Load the initial URL before adding the new tab contents to the tab strip
3097 // so that the tab contents has navigation state.
[email protected]10b833e2011-12-21 17:36:303098 contents->tab_contents()->controller().LoadURL(
[email protected]4a63e242011-12-12 15:23:083099 url, referrer, transition, std::string());
[email protected]36b6dcb2008-11-12 01:19:573100 }
3101
3102 return contents;
3103}
3104
3105bool Browser::CanDuplicateContentsAt(int index) {
[email protected]10b833e2011-12-21 17:36:303106 NavigationController& nc = GetTabContentsAt(index)->controller();
[email protected]ce3fa3c2009-04-20 19:55:573107 return nc.tab_contents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:573108}
3109
3110void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:493111 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:333112 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:123113 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:563114
3115 bool pinned = false;
3116 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
3117 // If this is a tabbed browser, just create a duplicate tab inside the same
3118 // window next to the tab being duplicated.
3119 int index = tab_handler_->GetTabStripModel()->
3120 GetIndexOfTabContents(contents);
3121 pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:413122 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:563123 TabStripModel::ADD_INHERIT_GROUP |
3124 (pinned ? TabStripModel::ADD_PINNED : 0);
3125 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
3126 contents_dupe,
3127 add_types);
3128 } else {
3129 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:143130 if (is_app()) {
3131 CHECK(!is_type_popup());
3132 CHECK(!is_type_panel());
[email protected]5c209242011-06-06 20:36:173133 browser = Browser::CreateForApp(TYPE_POPUP, app_name_, gfx::Rect(),
[email protected]b35b26b32011-05-05 20:35:143134 profile_);
3135 } else if (is_type_popup()) {
[email protected]47b309f2010-12-28 17:35:563136 browser = Browser::CreateForType(TYPE_POPUP, profile_);
3137 }
3138
3139 // Preserve the size of the original window. The new window has already
3140 // been given an offset by the OS, so we shouldn't copy the old bounds.
3141 BrowserWindow* new_window = browser->window();
3142 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
3143 window()->GetRestoredBounds().size()));
3144
[email protected]4e595682011-02-09 17:07:023145 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]47b309f2010-12-28 17:35:563146 // TabContents is invisible and won't size it.
3147 browser->window()->Show();
3148
3149 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:583150 browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK);
[email protected]47b309f2010-12-28 17:35:563151 }
3152
[email protected]92371eb2011-04-28 11:50:153153 SessionService* session_service =
3154 SessionServiceFactory::GetForProfileIfExisting(profile_);
3155 if (session_service)
[email protected]81898992011-06-14 22:15:003156 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:573157}
3158
[email protected]36b6dcb2008-11-12 01:19:573159void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:473160#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:573161 // This is scheduled to run after we return to the message loop because
3162 // otherwise the frame will think the drag session is still active and ignore
3163 // the request.
[email protected]d6a3c772009-01-27 19:41:203164 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:373165 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363166 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]d6a3c772009-01-27 19:41:203167#endif
initial.commit09911bf2008-07-26 23:55:293168}
3169
[email protected]3c9e1872010-11-18 16:17:493170void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:583171 // We don't create historical tabs for incognito windows or windows without
3172 // profiles.
[email protected]92371eb2011-04-28 11:50:153173 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:583174 return;
[email protected]92371eb2011-04-28 11:50:153175
[email protected]0d4ef7f2011-05-12 22:38:573176 // We don't create historical tabs for print preview tabs.
3177 if (contents->tab_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
3178 return;
3179
[email protected]92371eb2011-04-28 11:50:153180 TabRestoreService* service =
3181 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:583182
[email protected]fb5ff422010-05-03 20:46:103183 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:153184 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]10b833e2011-12-21 17:36:303185 service->CreateHistoricalTab(&contents->tab_contents()->controller(),
[email protected]fb7da4132011-03-15 15:51:003186 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:583187 }
3188}
3189
[email protected]3c9e1872010-11-18 16:17:493190bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
3191 return Browser::RunUnloadEventsHelper(contents->tab_contents());
[email protected]505323e22009-01-24 02:47:583192}
3193
[email protected]8e48e982009-12-25 11:22:463194bool Browser::CanReloadContents(TabContents* source) const {
[email protected]b35b26b32011-05-05 20:35:143195 return !is_devtools();
[email protected]8e48e982009-12-25 11:22:463196}
3197
[email protected]2db5a2042011-04-26 17:13:473198bool Browser::CanCloseContents(std::vector<int>* indices) {
3199 DCHECK(!indices->empty());
3200 TabCloseableStateWatcher* watcher =
3201 g_browser_process->tab_closeable_state_watcher();
3202 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
3203 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:043204 return false;
[email protected]2db5a2042011-04-26 17:13:473205 // Now, handle cases where at least one tab can be closed.
3206 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:103207 // in-progress downloads.
3208 // Note that the next call when it returns false will ask the user for
3209 // confirmation before closing the browser if the user decides so.
[email protected]2db5a2042011-04-26 17:13:473210 if (tab_handler_->GetTabStripModel()->count() ==
3211 static_cast<int>(indices->size()) &&
3212 !CanCloseWithInProgressDownloads()) {
3213 indices->clear();
3214 can_close_all = false;
3215 }
3216 return can_close_all;
[email protected]940ccb22009-04-30 17:11:103217}
[email protected]d6a3c772009-01-27 19:41:203218
[email protected]a206b442009-10-08 23:20:203219bool Browser::CanBookmarkAllTabs() const {
3220 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:583221 return (model && model->IsLoaded()) &&
3222 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:043223 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:203224}
3225
[email protected]b3ac5c82009-10-08 20:56:543226void Browser::BookmarkAllTabs() {
[email protected]9d603392011-11-18 05:45:283227 BookmarkEditor::ShowBookmarkAllTabsDialog(this);
[email protected]b3ac5c82009-10-08 20:56:543228}
3229
[email protected]0b4d3382010-07-14 16:13:043230bool Browser::CanCloseTab() const {
3231 TabCloseableStateWatcher* watcher =
3232 g_browser_process->tab_closeable_state_watcher();
3233 return !watcher || watcher->CanCloseTab(this);
3234}
3235
[email protected]b283a7532010-08-12 21:24:593236bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:443237 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
3238 // for those windows, we already have a big icon in the top-left outside any
3239 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:333240 return true;
[email protected]b283a7532010-08-12 21:24:593241}
3242
[email protected]2d46c842008-11-14 19:24:313243///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573244// Browser, TabStripModelObserver implementation:
3245
[email protected]3c9e1872010-11-18 16:17:493246void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573247 int index,
3248 bool foreground) {
[email protected]9219d262011-02-15 21:05:123249 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:003250 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:583251
[email protected]c37e3b62010-01-22 00:15:173252 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:573253
[email protected]159f7762008-12-19 14:58:273254 // Make sure the loading state is updated correctly, otherwise the throbber
3255 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:493256 LoadingStateChanged(contents->tab_contents());
[email protected]159f7762008-12-19 14:58:273257
[email protected]36b6dcb2008-11-12 01:19:573258 // If the tab crashes in the beforeunload or unload handler, it won't be
3259 // able to ack. But we know we can close it.
[email protected]432115822011-07-10 15:52:273260 registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED,
[email protected]6c2381d2011-10-19 02:52:533261 content::Source<TabContents>(contents->tab_contents()));
[email protected]93f230e02011-06-01 14:40:003262
[email protected]432115822011-07-10 15:52:273263 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]6c2381d2011-10-19 02:52:533264 content::Source<TabContents>(contents->tab_contents()));
[email protected]e397a4472011-12-21 21:47:503265
3266 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
3267 content::Source<TabContents>(contents->tab_contents()));
[email protected]36b6dcb2008-11-12 01:19:573268}
3269
[email protected]f2cc7382010-10-15 18:03:053270void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:493271 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:053272 int index) {
[email protected]01a5a762011-11-21 05:40:553273 fullscreen_controller_->OnTabClosing(contents->tab_contents());
[email protected]ad50def52011-10-19 23:17:073274 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273275 content::NOTIFICATION_TAB_CLOSING,
[email protected]4a63e242011-12-12 15:23:083276 content::Source<NavigationController>(
[email protected]10b833e2011-12-21 17:36:303277 &contents->tab_contents()->controller()),
[email protected]ad50def52011-10-19 23:17:073278 content::NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:573279
3280 // Sever the TabContents' connection back to us.
[email protected]9219d262011-02-15 21:05:123281 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:573282}
3283
[email protected]3c9e1872010-11-18 16:17:493284void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:173285 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:573286}
3287
[email protected]9ac8a242011-06-07 19:42:523288void Browser::TabDeactivated(TabContentsWrapper* contents) {
[email protected]01a5a762011-11-21 05:40:553289 fullscreen_controller_->OnTabDeactivated(contents);
[email protected]6b723f82010-10-05 20:14:273290 if (instant())
[email protected]3e481282011-10-15 15:39:503291 instant()->Hide();
[email protected]03bb953d2010-09-14 21:38:303292
[email protected]85ff2c42009-05-29 21:22:033293 // Save what the user's currently typing, so it can be restored when we
3294 // switch back to this tab.
[email protected]3c9e1872010-11-18 16:17:493295 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]85ff2c42009-05-29 21:22:033296}
3297
[email protected]3aca95d42011-05-24 22:06:543298void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
3299 TabContentsWrapper* new_contents,
3300 int index,
3301 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:163302 // On some platforms we want to automatically reload tabs that are
3303 // killed when the user selects them.
3304 if (user_gesture && new_contents->tab_contents()->crashed_status() ==
3305 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
3306 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:563307 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]a8f024392011-01-13 21:50:163308 Reload(CURRENT_TAB);
[email protected]f8a35772011-02-02 23:17:563309 return;
3310 }
[email protected]a8f024392011-01-13 21:50:163311 }
3312
[email protected]002efb042011-10-07 17:30:243313 // Discarded tabs always get reloaded.
3314 if (IsTabDiscarded(index)) {
3315 Reload(CURRENT_TAB);
3316 return;
3317 }
3318
[email protected]36b6dcb2008-11-12 01:19:573319 // If we have any update pending, do it now.
[email protected]24f1477532011-11-22 22:55:363320 if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
[email protected]36b6dcb2008-11-12 01:19:573321 ProcessPendingUIUpdates();
3322
[email protected]36b6dcb2008-11-12 01:19:573323 // Propagate the profile to the location bar.
3324 UpdateToolbar(true);
3325
[email protected]943d8122010-06-11 02:13:453326 // Update reload/stop state.
[email protected]f5d978c2011-07-21 14:43:513327 UpdateReloadStopState(new_contents->tab_contents()->IsLoading(), true);
[email protected]36b6dcb2008-11-12 01:19:573328
[email protected]84214982008-12-10 18:49:103329 // Update commands to reflect current state.
3330 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:573331
3332 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:103333 StatusBubble* status_bubble = GetStatusBubble();
3334 if (status_bubble) {
3335 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:573336
[email protected]be3877f2009-01-14 15:51:103337 // Show the loading state (if any).
[email protected]51d83bdf2011-12-09 16:09:293338 status_bubble->SetStatus(
3339 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:103340 }
[email protected]36b6dcb2008-11-12 01:19:573341
[email protected]24db8a072009-10-29 20:35:373342 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:243343 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:173344 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:583345 }
3346
[email protected]36b6dcb2008-11-12 01:19:573347 // Update sessions. Don't force creation of sessions. If sessions doesn't
3348 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:153349 SessionService* session_service =
3350 SessionServiceFactory::GetForProfileIfExisting(profile_);
3351 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
3352 session_service->SetSelectedTabInWindow(
3353 session_id(), tab_handler_->GetTabStripModel()->active_index());
[email protected]36b6dcb2008-11-12 01:19:573354 }
[email protected]09b29342011-06-24 19:18:483355
3356 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:573357}
3358
[email protected]3c9e1872010-11-18 16:17:493359void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573360 int from_index,
[email protected]1a242c32010-02-02 21:20:543361 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:573362 DCHECK(from_index >= 0 && to_index >= 0);
3363 // Notify the history service.
3364 SyncHistoryWithTabs(std::min(from_index, to_index));
3365}
3366
[email protected]da25dd52011-01-11 19:06:303367void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
3368 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:493369 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:433370 int index) {
[email protected]c37e3b62010-01-22 00:15:173371 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
3372 TabInsertedAt(new_contents, index,
[email protected]1ea49d52011-04-12 17:44:443373 (index == tab_handler_->GetTabStripModel()->active_index()));
[email protected]c37e3b62010-01-22 00:15:173374
[email protected]10b833e2011-12-21 17:36:303375 int entry_count = new_contents->tab_contents()->controller().entry_count();
[email protected]c37e3b62010-01-22 00:15:173376 if (entry_count > 0) {
3377 // Send out notification so that observers are updated appropriately.
[email protected]10b833e2011-12-21 17:36:303378 new_contents->tab_contents()->controller().NotifyEntryChanged(
3379 new_contents->tab_contents()->controller().GetEntryAtIndex(
[email protected]4a63e242011-12-12 15:23:083380 entry_count - 1),
[email protected]c37e3b62010-01-22 00:15:173381 entry_count - 1);
3382 }
[email protected]47e020a2010-10-15 14:43:373383
[email protected]92371eb2011-04-28 11:50:153384 SessionService* session_service =
3385 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:373386 if (session_service) {
3387 // The new_contents may end up with a different navigation stack. Force
3388 // the session service to update itself.
3389 session_service->TabRestored(
[email protected]81898992011-06-14 22:15:003390 new_contents, tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373391 }
[email protected]2914600d2011-01-31 23:25:143392
[email protected]0e12d7d2011-12-01 16:21:443393 content::DevToolsManager::GetInstance()->TabReplaced(
3394 old_contents->tab_contents(), new_contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:173395}
3396
[email protected]3c9e1872010-11-18 16:17:493397void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153398 SessionService* session_service =
3399 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093400 if (session_service) {
3401 session_service->SetPinnedState(
3402 session_id(),
[email protected]81898992011-06-14 22:15:003403 GetTabContentsWrapperAt(index)->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:403404 tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093405 }
3406}
3407
[email protected]36b6dcb2008-11-12 01:19:573408void Browser::TabStripEmpty() {
3409 // Close the frame after we return to the message loop (not immediately,
3410 // otherwise it will destroy this object before the stack has a chance to
3411 // cleanly unwind.)
3412 // Note: This will be called several times if TabStripEmpty is called several
3413 // times. This is because it does not close the window if tabs are
3414 // still present.
3415 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3416 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373417 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363418 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]36b6dcb2008-11-12 01:19:573419}
3420
3421///////////////////////////////////////////////////////////////////////////////
[email protected]674bc592011-12-20 23:00:423422// Browser, content::WebContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293423
[email protected]00c37fc2011-08-02 00:22:503424TabContents* Browser::OpenURLFromTab(TabContents* source,
3425 const OpenURLParams& params) {
3426 browser::NavigateParams nav_params(this, params.url, params.transition);
3427 nav_params.source_contents =
3428 tabstrip_model()->GetTabContentsAt(
3429 tabstrip_model()->GetWrapperIndex(source));
[email protected]cb8fb01a2011-12-05 21:01:143430 nav_params.referrer = params.referrer;
[email protected]00c37fc2011-08-02 00:22:503431 nav_params.disposition = params.disposition;
3432 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
3433 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
3434 nav_params.user_gesture = true;
3435 nav_params.override_encoding = params.override_encoding;
[email protected]e47ae9472011-10-13 19:48:343436 nav_params.is_renderer_initiated = params.is_renderer_initiated;
[email protected]4ad5d77d2011-12-03 02:00:483437 nav_params.transferred_global_request_id =
3438 params.transferred_global_request_id;
[email protected]00c37fc2011-08-02 00:22:503439 browser::Navigate(&nav_params);
3440
3441 return nav_params.target_contents ?
3442 nav_params.target_contents->tab_contents() : NULL;
initial.commit09911bf2008-07-26 23:55:293443}
3444
3445void Browser::NavigationStateChanged(const TabContents* source,
3446 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293447 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403448 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293449 ScheduleUIUpdate(source, changed_flags);
3450
[email protected]83c2e232011-10-07 21:36:463451 // We can synchronously update commands since they will only change once per
3452 // navigation, so we don't have to worry about flickering. We do, however,
3453 // need to update the command state early on load to always present usable
3454 // actions in the face of slow-to-commit pages.
3455 if (changed_flags & (TabContents::INVALIDATE_URL |
3456 TabContents::INVALIDATE_LOAD))
[email protected]84214982008-12-10 18:49:103457 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293458}
3459
initial.commit09911bf2008-07-26 23:55:293460void Browser::AddNewContents(TabContents* source,
3461 TabContents* new_contents,
3462 WindowOpenDisposition disposition,
3463 const gfx::Rect& initial_pos,
3464 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373465 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333466 DCHECK(disposition != SAVE_TO_DISK);
3467 // Can't create a new contents for the current tab - invalid case.
3468 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293469
[email protected]e7cfdbd2011-04-22 14:41:373470 TabContentsWrapper* source_wrapper = NULL;
3471 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453472 TabContentsWrapper* new_wrapper =
3473 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
3474 if (!new_wrapper)
3475 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]e7cfdbd2011-04-22 14:41:373476 if (source) {
3477 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3478 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3479 }
3480
3481 if (source_wrapper) {
3482 // Handle blocking of all contents.
3483 if (source_blocked_content->all_contents_blocked()) {
3484 source_blocked_content->AddTabContents(new_wrapper,
3485 disposition,
3486 initial_pos,
3487 user_gesture);
3488 return;
3489 }
3490
3491 // Handle blocking of popups.
3492 if ((disposition == NEW_POPUP) && !user_gesture &&
3493 !CommandLine::ForCurrentProcess()->HasSwitch(
3494 switches::kDisablePopupBlocking)) {
3495 // Unrequested popups from normal pages are constrained unless they're in
3496 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363497 GetConstrainingContentsWrapper(source_wrapper)->
3498 blocked_content_tab_helper()->
3499 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373500 return;
3501 }
3502
[email protected]151a63d2011-12-20 22:32:523503 new_contents->GetRenderViewHost()->DisassociateFromPopupCount();
[email protected]e7cfdbd2011-04-22 14:41:373504 }
3505
[email protected]e7cfdbd2011-04-22 14:41:373506 browser::NavigateParams params(this, new_wrapper);
[email protected]3c9e1872010-11-18 16:17:493507 params.source_contents =
[email protected]e7cfdbd2011-04-22 14:41:373508 source ? tabstrip_model()->GetTabContentsAt(
3509 tabstrip_model()->GetWrapperIndex(source))
3510 : NULL;
[email protected]3c9e1872010-11-18 16:17:493511 params.disposition = disposition;
3512 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353513 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3514 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493515 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293516}
3517
initial.commit09911bf2008-07-26 23:55:293518void Browser::ActivateContents(TabContents* contents) {
[email protected]eaca0ad12011-04-18 15:53:413519 tab_handler_->GetTabStripModel()->ActivateTabAt(
[email protected]3c9e1872010-11-18 16:17:493520 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393521 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293522}
3523
[email protected]ea42e7782010-08-23 23:58:123524void Browser::DeactivateContents(TabContents* contents) {
3525 window_->Deactivate();
3526}
3527
initial.commit09911bf2008-07-26 23:55:293528void Browser::LoadingStateChanged(TabContents* source) {
[email protected]ecc523f62010-09-28 22:45:403529 window_->UpdateLoadingAnimations(
3530 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393531 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293532
[email protected]3c9e1872010-11-18 16:17:493533 TabContents* selected_contents = GetSelectedTabContents();
3534 if (source == selected_contents) {
[email protected]f5d978c2011-07-21 14:43:513535 bool is_loading = source->IsLoading();
3536 UpdateReloadStopState(is_loading, false);
[email protected]43d259d2010-09-03 21:37:463537 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443538 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:293539 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463540 }
[email protected]eabfdae92009-12-11 06:13:513541
[email protected]f5d978c2011-07-21 14:43:513542 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333543 // Schedule a shortcut update when web application info is available if
3544 // last committed entry is not NULL. Last committed entry could be NULL
3545 // when an interstitial page is injected (e.g. bad https certificate,
3546 // malware site etc). When this happens, we abort the shortcut update.
[email protected]10b833e2011-12-21 17:36:303547 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
[email protected]eabfdae92009-12-11 06:13:513548 if (entry) {
[email protected]553602e12011-04-05 17:01:183549 TabContentsWrapper::GetCurrentWrapperForContents(source)->
3550 extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]eabfdae92009-12-11 06:13:513551 } else {
3552 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513553 }
3554 }
initial.commit09911bf2008-07-26 23:55:293555 }
3556}
3557
3558void Browser::CloseContents(TabContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473559 if (is_attempting_to_close_browser_) {
3560 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063561 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473562 // will go down the slow shutdown path instead of the fast path of killing
3563 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213564 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473565 return;
3566 }
3567
[email protected]3c9e1872010-11-18 16:17:493568 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293569 if (index == TabStripModel::kNoTab) {
3570 NOTREACHED() << "CloseContents called for tab not in our strip";
3571 return;
3572 }
[email protected]ecc523f62010-09-28 22:45:403573 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:393574 index,
3575 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293576}
3577
[email protected]15e8abe2008-08-20 22:40:403578void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143579 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293580 NOTREACHED() << "moving invalid browser type";
3581 return;
3582 }
[email protected]e561e202010-03-24 17:57:123583 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293584}
3585
[email protected]b6c874582009-05-08 19:38:313586void Browser::DetachContents(TabContents* source) {
[email protected]3c9e1872010-11-18 16:17:493587 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313588 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:403589 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313590}
3591
[email protected]b35b26b32011-05-05 20:35:143592bool Browser::IsPopupOrPanel(const TabContents* source) const {
initial.commit09911bf2008-07-26 23:55:293593 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143594 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293595}
3596
[email protected]b8595e92009-11-14 01:18:003597void Browser::ContentsMouseEvent(
3598 TabContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:103599 if (!GetStatusBubble())
3600 return;
3601
[email protected]36b6dcb2008-11-12 01:19:573602 if (source == GetSelectedTabContents()) {
[email protected]b8595e92009-11-14 01:18:003603 GetStatusBubble()->MouseMoved(location, !motion);
3604 if (!motion)
[email protected]65233052011-08-22 19:02:483605 GetStatusBubble()->SetURL(GURL(), std::string());
[email protected]36b6dcb2008-11-12 01:19:573606 }
3607}
3608
[email protected]d952a052011-09-06 18:42:453609void Browser::UpdateTargetURL(TabContents* source, int32 page_id,
3610 const GURL& url) {
3611 Browser::UpdateTargetURLHelper(source, page_id, url);
3612
[email protected]be3877f2009-01-14 15:51:103613 if (!GetStatusBubble())
3614 return;
3615
[email protected]36b6dcb2008-11-12 01:19:573616 if (source == GetSelectedTabContents()) {
3617 PrefService* prefs = profile_->GetPrefs();
[email protected]65233052011-08-22 19:02:483618 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
[email protected]36b6dcb2008-11-12 01:19:573619 }
3620}
3621
[email protected]3a6a3b62009-05-27 21:36:203622void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:233623 if (GetStatusBubble())
3624 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:203625}
3626
[email protected]36b6dcb2008-11-12 01:19:573627void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253628 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573629}
3630
[email protected]7e383692009-06-12 19:14:543631void Browser::TabContentsFocused(TabContents* tab_content) {
3632 window_->TabContentsFocused(tab_content);
3633}
3634
[email protected]130efb02009-09-18 18:54:353635bool Browser::TakeFocus(bool reverse) {
[email protected]ad50def52011-10-19 23:17:073636 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273637 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
[email protected]6c2381d2011-10-19 02:52:533638 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:073639 content::NotificationService::NoDetails());
[email protected]130efb02009-09-18 18:54:353640 return false;
3641}
3642
[email protected]36b6dcb2008-11-12 01:19:573643bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143644 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573645}
3646
3647void Browser::ConvertContentsToApplication(TabContents* contents) {
[email protected]10b833e2011-12-21 17:36:303648 const GURL& url = contents->controller().GetActiveEntry()->url();
[email protected]57ecc4b2010-08-11 03:02:513649 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573650
[email protected]b6c874582009-05-08 19:38:313651 DetachContents(contents);
[email protected]94ce7252010-12-20 21:46:333652 Browser* app_browser = Browser::CreateForApp(
[email protected]5c209242011-06-06 20:36:173653 TYPE_POPUP, app_name, gfx::Rect(), profile_);
[email protected]ae2f2a772011-05-04 16:30:273654 TabContentsWrapper* wrapper =
3655 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3656 if (!wrapper)
3657 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323658 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3659
3660 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:523661 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]75aef122010-12-06 21:48:323662 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573663}
3664
[email protected]36b6dcb2008-11-12 01:19:573665void Browser::BeforeUnloadFired(TabContents* tab,
3666 bool proceed,
3667 bool* proceed_to_fire_unload) {
3668 if (!is_attempting_to_close_browser_) {
3669 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393670 if (!proceed)
3671 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573672 return;
3673 }
3674
3675 if (!proceed) {
3676 CancelWindowClose();
3677 *proceed_to_fire_unload = false;
[email protected]0cce15f2010-05-21 16:58:393678 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573679 return;
3680 }
3681
[email protected]06b42f032008-12-03 18:43:053682 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313683 // Now that beforeunload has fired, put the tab on the queue to fire
3684 // unload.
[email protected]06b42f032008-12-03 18:43:053685 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573686 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063687 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573688 // fire all the beforeunload events before attempting to fire the unload
3689 // events should the user cancel closing the browser.
3690 *proceed_to_fire_unload = false;
3691 return;
3692 }
3693
3694 *proceed_to_fire_unload = true;
3695}
3696
[email protected]a26dc362010-04-23 01:48:583697void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133698 // Two differences between this and FocusLocationBar():
3699 // (1) This doesn't get recorded in user metrics, since it's called
3700 // internally.
3701 // (2) This checks whether the location bar can be focused, and if not, clears
3702 // the focus. FocusLocationBar() is only reached when the location bar is
3703 // focusable, but this may be reached at other times, e.g. while in
3704 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583705 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573706}
3707
[email protected]7d5925a2009-03-03 02:59:123708void Browser::RenderWidgetShowing() {
3709 window_->DisableInactiveFrame();
3710}
[email protected]a239c3f2009-02-17 22:13:193711
[email protected]0a2aeb82009-05-15 21:52:483712int Browser::GetExtraRenderViewHeight() const {
3713 return window_->GetExtraRenderViewHeight();
3714}
3715
[email protected]a0e4b072011-08-17 01:47:073716namespace {
3717
3718bool DisplayOldDownloadsUI() {
3719 return !CommandLine::ForCurrentProcess()->HasSwitch(
3720 switches::kDownloadsNewUI);
3721}
3722
3723} // anonymous namespace
3724
[email protected]e582fdd2011-12-20 16:48:173725void Browser::OnStartDownload(TabContents* source,
3726 content::DownloadItem* download) {
[email protected]686493142011-07-15 21:47:223727 TabContentsWrapper* wrapper =
3728 TabContentsWrapper::GetCurrentWrapperForContents(source);
3729 TabContentsWrapper* constrained = GetConstrainingContentsWrapper(wrapper);
3730 if (constrained != wrapper) {
3731 // Download in a constrained popup is shown in the tab that opened it.
3732 TabContents* constrained_tab = constrained->tab_contents();
[email protected]6934a702011-12-20 00:04:513733 constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download);
[email protected]686493142011-07-15 21:47:223734 return;
3735 }
3736
3737 if (!window())
3738 return;
3739
[email protected]a0e4b072011-08-17 01:47:073740 if (DisplayOldDownloadsUI()) {
[email protected]eab8c0f2011-11-18 22:33:503741#if defined(OS_CHROMEOS) && !defined(USE_AURA)
[email protected]603a502a2011-12-15 20:18:173742 if (ActiveDownloadsUI::ShouldShowPopup(profile_, download))
[email protected]a0e4b072011-08-17 01:47:073743 ActiveDownloadsUI::OpenPopup(profile_);
[email protected]eab8c0f2011-11-18 22:33:503744#else
[email protected]a0e4b072011-08-17 01:47:073745 // GetDownloadShelf creates the download shelf if it was not yet created.
3746 DownloadShelf* shelf = window()->GetDownloadShelf();
3747 shelf->AddDownload(new DownloadItemModel(download));
3748 // Don't show the animation for "Save file" downloads.
3749 // For non-theme extensions, we don't show the download animation.
3750 // Show animation in same window as the download shelf. Download shelf
3751 // may not be in the same window that initiated the download, e.g.
3752 // Panels.
3753 // Don't show the animation if the selected tab is not visible (i.e. the
3754 // window is minimized, we're in a unit test, etc.).
3755 TabContents* shelf_tab = shelf->browser()->GetSelectedTabContents();
[email protected]c09a8fd2011-11-21 19:54:503756 if ((download->GetTotalBytes() > 0) &&
[email protected]b0cfcee2011-10-27 03:55:373757 !ChromeDownloadManagerDelegate::IsExtensionDownload(download) &&
[email protected]a0e4b072011-08-17 01:47:073758 platform_util::IsVisible(shelf_tab->GetNativeView()) &&
3759 ui::Animation::ShouldRenderRichAnimation()) {
3760 DownloadStartedAnimation::Show(shelf_tab);
3761 }
[email protected]686493142011-07-15 21:47:223762#endif
[email protected]a0e4b072011-08-17 01:47:073763 }
[email protected]686493142011-07-15 21:47:223764
3765 // If the download occurs in a new tab, close it.
[email protected]10b833e2011-12-21 17:36:303766 if (source->controller().IsInitialNavigation() && tab_count() > 1)
[email protected]686493142011-07-15 21:47:223767 CloseContents(source);
3768}
3769
[email protected]3d7474ff2011-07-27 17:47:373770void Browser::ShowPageInfo(content::BrowserContext* browser_context,
[email protected]4d677202009-07-19 07:37:123771 const GURL& url,
3772 const NavigationEntry::SSLStatus& ssl,
3773 bool show_history) {
[email protected]3d7474ff2011-07-27 17:47:373774 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]bb678332009-07-21 00:15:503775 window()->ShowPageInfo(profile, url, ssl, show_history);
[email protected]4d677202009-07-19 07:37:123776}
3777
[email protected]1788e772010-12-15 16:40:503778void Browser::ViewSourceForTab(TabContents* source, const GURL& page_url) {
3779 DCHECK(source);
3780 int index = tabstrip_model()->GetWrapperIndex(source);
[email protected]77d8d622010-12-15 10:30:123781 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3782 ViewSource(wrapper);
3783}
3784
[email protected]932b7a12011-03-09 12:50:273785void Browser::ViewSourceForFrame(TabContents* source,
3786 const GURL& frame_url,
3787 const std::string& frame_content_state) {
3788 DCHECK(source);
3789 int index = tabstrip_model()->GetWrapperIndex(source);
3790 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3791 ViewSource(wrapper, frame_url, frame_content_state);
3792}
3793
[email protected]867125a02009-12-10 06:01:483794bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3795 bool* is_keyboard_shortcut) {
[email protected]85804b52011-10-15 06:56:273796 // Escape exits tabbed fullscreen mode.
3797 // TODO(koz): Write a test for this http://crbug.com/100441.
[email protected]01a5a762011-11-21 05:40:553798 if (event.windowsKeyCode == 27 &&
3799 fullscreen_controller_->HandleUserPressedEscape()) {
[email protected]85804b52011-10-15 06:56:273800 return true;
3801 }
[email protected]867125a02009-12-10 06:01:483802 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3803}
[email protected]97df4b332009-10-02 01:25:413804
[email protected]867125a02009-12-10 06:01:483805void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3806 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413807}
3808
[email protected]14f3408a2009-08-31 20:53:533809void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
[email protected]67baffc82011-12-19 18:03:073810 browser::ShowTabModalConfirmDialog(
3811 new RepostFormWarningController(tab_contents),
3812 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents));
[email protected]14f3408a2009-08-31 20:53:533813}
3814
[email protected]579e3192011-03-11 22:37:453815void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
[email protected]445177652011-03-09 02:04:053816 ShowOptionsTab(
3817 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
3818 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
[email protected]63543142010-02-09 23:22:203819}
3820
[email protected]a3627e62011-09-07 00:04:573821void Browser::ShowCollectedCookiesDialog(TabContentsWrapper* wrapper) {
3822 window()->ShowCollectedCookiesDialog(wrapper);
[email protected]a503c97c2010-07-16 13:05:483823}
3824
[email protected]ec0b6c42010-08-26 03:16:583825bool Browser::ShouldAddNavigationToHistory(
3826 const history::HistoryAddPageArgs& add_page_args,
[email protected]610cbb82011-10-18 16:35:083827 content::NavigationType navigation_type) {
[email protected]2e29d922009-10-22 22:13:353828 // Don't update history if running as app.
3829 return !IsApplication();
3830}
3831
[email protected]80c7b802011-10-28 19:59:083832void Browser::TabContentsCreated(TabContents* new_contents) {
3833 // Create a TabContentsWrapper now, so all observers are in place, as the
3834 // network requests for its initial navigation will start immediately. The
3835 // TabContents will later be inserted into this browser using
3836 // Browser::Navigate via AddNewContents. The latter will retrieve the newly
3837 // created TabContentsWrapper from TabContents object.
3838 new TabContentsWrapper(new_contents);
3839}
3840
[email protected]9e823662010-10-13 23:36:003841void Browser::ContentRestrictionsChanged(TabContents* source) {
3842 UpdateCommandsForContentRestrictionState();
3843}
3844
[email protected]55452902011-06-01 21:57:473845void Browser::RendererUnresponsive(TabContents* source) {
[email protected]c19d9542011-11-15 22:26:423846 // Ignore hangs if print preview is open.
3847 TabContentsWrapper* source_wrapper =
3848 TabContentsWrapper::GetCurrentWrapperForContents(source);
3849 if (source_wrapper) {
3850 printing::PrintPreviewTabController* controller =
3851 printing::PrintPreviewTabController::GetInstance();
3852 if (controller) {
3853 TabContentsWrapper* preview_tab =
3854 controller->GetPrintPreviewForTab(source_wrapper);
3855 if (preview_tab && preview_tab != source_wrapper) {
3856 return;
3857 }
3858 }
3859 }
3860
[email protected]55452902011-06-01 21:57:473861 browser::ShowHungRendererDialog(source);
3862}
3863
3864void Browser::RendererResponsive(TabContents* source) {
3865 browser::HideHungRendererDialog(source);
3866}
3867
3868void Browser::WorkerCrashed(TabContents* source) {
3869 TabContentsWrapper* wrapper =
3870 TabContentsWrapper::GetCurrentWrapperForContents(source);
[email protected]95a33ed62011-09-30 15:07:083871 InfoBarTabHelper* infobar_helper = wrapper->infobar_tab_helper();
3872 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3873 infobar_helper,
3874 NULL,
3875 l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
[email protected]55452902011-06-01 21:57:473876 true));
[email protected]0dd3a0ab2011-02-18 08:17:443877}
3878
[email protected]09b29342011-06-24 19:18:483879void Browser::DidNavigateMainFramePostCommit(TabContents* tab) {
3880 if (tab == GetSelectedTabContents())
3881 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003882}
3883
[email protected]09b29342011-06-24 19:18:483884void Browser::DidNavigateToPendingEntry(TabContents* tab) {
3885 if (tab == GetSelectedTabContents())
3886 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003887}
3888
[email protected]3ab9cb82011-06-03 18:02:073889content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
3890 return GetJavaScriptDialogCreatorInstance();
3891}
3892
[email protected]3a29a6e2011-08-24 18:26:213893void Browser::RunFileChooser(TabContents* tab,
[email protected]8caadeb2011-11-22 02:45:233894 const content::FileChooserParams& params) {
[email protected]b888919c2011-09-02 00:32:163895 RunFileChooserHelper(tab, params);
[email protected]3a29a6e2011-08-24 18:26:213896}
3897
3898void Browser::EnumerateDirectory(TabContents* tab, int request_id,
3899 const FilePath& path) {
[email protected]b888919c2011-09-02 00:32:163900 EnumerateDirectoryHelper(tab, request_id, path);
[email protected]3a29a6e2011-08-24 18:26:213901}
3902
[email protected]8a5e0ca2011-08-25 06:30:473903void Browser::ToggleFullscreenModeForTab(TabContents* tab,
[email protected]01a5a762011-11-21 05:40:553904 bool enter_fullscreen) {
3905 fullscreen_controller_->ToggleFullscreenModeForTab(tab, enter_fullscreen);
[email protected]8a5e0ca2011-08-25 06:30:473906}
3907
[email protected]5d5f7af2011-10-01 01:38:123908bool Browser::IsFullscreenForTab(const TabContents* tab) const {
[email protected]01a5a762011-11-21 05:40:553909 return fullscreen_controller_->IsFullscreenForTab(tab);
[email protected]5d5f7af2011-10-01 01:38:123910}
3911
[email protected]7d189022011-08-25 22:54:203912void Browser::JSOutOfMemory(TabContents* tab) {
[email protected]b888919c2011-09-02 00:32:163913 JSOutOfMemoryHelper(tab);
[email protected]7d189022011-08-25 22:54:203914}
3915
3916void Browser::RegisterProtocolHandler(TabContents* tab,
3917 const std::string& protocol,
3918 const GURL& url,
3919 const string16& title) {
[email protected]b888919c2011-09-02 00:32:163920 RegisterProtocolHandlerHelper(tab, protocol, url, title);
[email protected]7d189022011-08-25 22:54:203921}
3922
3923void Browser::RegisterIntentHandler(TabContents* tab,
3924 const string16& action,
3925 const string16& type,
3926 const string16& href,
[email protected]63c239322011-10-31 23:56:303927 const string16& title,
3928 const string16& disposition) {
3929 RegisterIntentHandlerHelper(tab, action, type, href, title, disposition);
[email protected]7d189022011-08-25 22:54:203930}
3931
[email protected]0d9989d2011-12-21 20:26:003932void Browser::WebIntentDispatch(
3933 TabContents* tab, content::WebIntentsDispatcher* intents_dispatcher) {
[email protected]828e61af2011-09-14 19:45:063934 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents))
3935 return;
3936
3937 TabContentsWrapper* tcw =
3938 TabContentsWrapper::GetCurrentWrapperForContents(tab);
[email protected]0d9989d2011-12-21 20:26:003939 tcw->web_intent_picker_controller()->SetIntentsDispatcher(intents_dispatcher);
[email protected]ada02b312011-12-01 21:54:533940 tcw->web_intent_picker_controller()->ShowDialog(
[email protected]0d9989d2011-12-21 20:26:003941 this,
3942 intents_dispatcher->GetIntent().action,
3943 intents_dispatcher->GetIntent().type);
[email protected]b888919c2011-09-02 00:32:163944}
3945
3946void Browser::FindReply(TabContents* tab,
3947 int request_id,
3948 int number_of_matches,
3949 const gfx::Rect& selection_rect,
3950 int active_match_ordinal,
3951 bool final_update) {
3952 FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
3953 active_match_ordinal, final_update);
[email protected]7d189022011-08-25 22:54:203954}
3955
[email protected]d952a052011-09-06 18:42:453956void Browser::CrashedPlugin(TabContents* tab, const FilePath& plugin_path) {
3957 CrashedPluginHelper(tab, plugin_path);
3958}
3959
[email protected]0548c5352011-09-07 00:33:333960void Browser::UpdatePreferredSize(TabContents* source,
3961 const gfx::Size& pref_size) {
3962 window_->UpdatePreferredSize(source, pref_size);
3963}
3964
[email protected]5ef8e372011-10-18 04:25:553965void Browser::RequestToLockMouse(TabContents* tab) {
[email protected]01a5a762011-11-21 05:40:553966 fullscreen_controller_->RequestToLockMouse(tab);
[email protected]55c87fa2011-10-15 07:28:283967}
3968
[email protected]5ef8e372011-10-18 04:25:553969void Browser::LostMouseLock() {
[email protected]01a5a762011-11-21 05:40:553970 fullscreen_controller_->LostMouseLock();
[email protected]5ef8e372011-10-18 04:25:553971}
3972
3973void Browser::OnAcceptFullscreenPermission(
3974 const GURL& url,
3975 FullscreenExitBubbleType bubble_type) {
[email protected]01a5a762011-11-21 05:40:553976 fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type);
[email protected]5ef8e372011-10-18 04:25:553977}
3978
3979void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) {
[email protected]01a5a762011-11-21 05:40:553980 fullscreen_controller_->OnDenyFullscreenPermission(bubble_type);
[email protected]55c87fa2011-10-15 07:28:283981}
3982
[email protected]fc9bf18f2011-10-22 00:41:173983
[email protected]36b6dcb2008-11-12 01:19:573984///////////////////////////////////////////////////////////////////////////////
[email protected]51d83bdf2011-12-09 16:09:293985// Browser, CoreTabHelperDelegate implementation:
[email protected]a0366a52011-02-04 20:04:213986
[email protected]553602e12011-04-05 17:01:183987void Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
3988 int32 page_id) {
3989 if (GetSelectedTabContentsWrapper() != source)
3990 return;
3991
[email protected]4a63e242011-12-12 15:23:083992 NavigationEntry* entry =
[email protected]10b833e2011-12-21 17:36:303993 source->tab_contents()->controller().GetLastCommittedEntry();
[email protected]553602e12011-04-05 17:01:183994 if (!entry || (entry->page_id() != page_id))
3995 return;
3996
3997 switch (pending_web_app_action_) {
3998 case CREATE_SHORTCUT: {
3999 window()->ShowCreateWebAppShortcutsDialog(source);
4000 break;
4001 }
4002 case UPDATE_SHORTCUT: {
4003 web_app::UpdateShortcutForTabContents(source);
4004 break;
4005 }
4006 default:
4007 NOTREACHED();
4008 break;
4009 }
4010
4011 pending_web_app_action_ = NONE;
4012}
4013
4014void Browser::OnInstallApplication(TabContentsWrapper* source,
4015 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:364016 ExtensionService* extension_service = profile()->GetExtensionService();
4017 if (!extension_service)
[email protected]553602e12011-04-05 17:01:184018 return;
4019
[email protected]d8c8f25f2011-11-02 18:18:014020 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(
4021 extension_service,
[email protected]14908b72011-04-20 06:54:364022 extension_service->show_extensions_prompts() ?
4023 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:184024 installer->InstallWebApp(web_app);
4025}
4026
[email protected]c90c6ca2011-02-16 20:11:384027///////////////////////////////////////////////////////////////////////////////
4028// Browser, SearchEngineTabHelperDelegate implementation:
4029
[email protected]9b0e63e52011-10-12 23:08:104030void Browser::ConfirmSetDefaultSearchProvider(TabContents* tab_contents,
4031 TemplateURL* template_url,
4032 Profile* profile) {
[email protected]9219d262011-02-15 21:05:124033 window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
[email protected]9b0e63e52011-10-12 23:08:104034 profile);
[email protected]9219d262011-02-15 21:05:124035}
4036
4037void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
4038 Profile* profile) {
[email protected]8f23e2b2011-11-03 17:30:414039#if defined(OS_CHROMEOS) || defined(USE_AURA)
4040 // Use a WebUI implementation of the dialog.
4041 browser::ConfirmAddSearchProvider(template_url, profile);
4042#else
4043 // TODO(rbyers): Remove the IsMoreWebUI check and (ideally) all #ifdefs once
4044 // we can select exactly one version of this dialog to use for each platform
4045 // at build time.
4046 if (ChromeWebUI::IsMoreWebUI())
[email protected]02b075972011-10-19 18:39:004047 browser::ConfirmAddSearchProvider(template_url, profile);
[email protected]8f23e2b2011-11-03 17:30:414048 else
4049 // Platform-specific implementation of the dialog.
[email protected]02b075972011-10-19 18:39:004050 window()->ConfirmAddSearchProvider(template_url, profile);
[email protected]8f23e2b2011-11-03 17:30:414051#endif
[email protected]9219d262011-02-15 21:05:124052}
4053
[email protected]a0366a52011-02-04 20:04:214054///////////////////////////////////////////////////////////////////////////////
[email protected]e7cfdbd2011-04-22 14:41:374055// Browser, BlockedContentTabHelperDelegate implementation:
4056
[email protected]393c0ed02011-04-22 14:55:364057TabContentsWrapper* Browser::GetConstrainingContentsWrapper(
[email protected]e7cfdbd2011-04-22 14:41:374058 TabContentsWrapper* source) {
4059 return source;
4060}
4061
4062///////////////////////////////////////////////////////////////////////////////
[email protected]35699d572011-05-11 19:46:144063// Browser, BookmarkTabHelperDelegate implementation:
[email protected]52cc59b2011-05-06 14:42:384064
4065void Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
4066 if (source == GetSelectedTabContentsWrapper())
4067 window_->SetStarredState(starred);
4068}
4069
4070///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574071// Browser, SelectFileDialog::Listener implementation:
4072
[email protected]561abe62009-04-06 18:08:344073void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:514074 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:124075 GURL file_url = net::FilePathToFileURL(path);
[email protected]36b6dcb2008-11-12 01:19:574076 if (!file_url.is_empty())
[email protected]2905f742011-10-13 03:51:584077 OpenURL(file_url, GURL(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED);
[email protected]36b6dcb2008-11-12 01:19:574078}
4079
4080///////////////////////////////////////////////////////////////////////////////
[email protected]6c2381d2011-10-19 02:52:534081// Browser, content::NotificationObserver implementation:
[email protected]36b6dcb2008-11-12 01:19:574082
[email protected]432115822011-07-10 15:52:274083void Browser::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:534084 const content::NotificationSource& source,
4085 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:274086 switch (type) {
4087 case content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:404088 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:214089 // Pass in false so that we delay processing. We need to delay the
4090 // processing as it may close the tab, which is currently on the call
4091 // stack above us.
[email protected]6c2381d2011-10-19 02:52:534092 ClearUnloadState(content::Source<TabContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:404093 }
4094 break;
4095
[email protected]432115822011-07-10 15:52:274096 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:404097 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:324098 // bar to reflect the new state. Note that it's possible for the selected
4099 // tab contents to be NULL. This is because we listen for all sources
4100 // (NavigationControllers) for convenience, so the notification could
4101 // actually be for a different window while we're doing asynchronous
4102 // closing of this one.
4103 if (GetSelectedTabContents() &&
[email protected]10b833e2011-12-21 17:36:304104 &GetSelectedTabContents()->controller() ==
[email protected]6c2381d2011-10-19 02:52:534105 content::Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:574106 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:404107 break;
4108
[email protected]432115822011-07-10 15:52:274109 case chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED: {
[email protected]e6090e42010-03-23 22:44:084110 // Show the UI if the extension was disabled for escalated permissions.
[email protected]6c2381d2011-10-19 02:52:534111 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]bc535ee52010-08-31 18:40:324112 if (profile_->IsSameProfile(profile)) {
[email protected]eaa7dd182010-12-14 11:09:004113 ExtensionService* service = profile->GetExtensionService();
[email protected]bc535ee52010-08-31 18:40:324114 DCHECK(service);
[email protected]6c2381d2011-10-19 02:52:534115 const Extension* extension =
4116 content::Details<const Extension>(details).ptr();
[email protected]bc535ee52010-08-31 18:40:324117 if (service->extension_prefs()->DidExtensionEscalatePermissions(
4118 extension->id()))
4119 ShowExtensionDisabledUI(service, profile_, extension);
4120 }
[email protected]0c6da502009-08-14 22:32:394121 break;
4122 }
4123
[email protected]432115822011-07-10 15:52:274124 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:364125 if (window()->GetLocationBar())
4126 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:384127
[email protected]b3f7fe22011-11-11 19:27:564128 // Close any tabs from the unloaded extension, unless it's terminated,
4129 // in which case let the sad tabs remain.
4130 if (content::Details<UnloadedExtensionInfo>(details)->reason !=
4131 extension_misc::UNLOAD_REASON_TERMINATE) {
4132 const Extension* extension =
4133 content::Details<UnloadedExtensionInfo>(details)->extension;
4134 TabStripModel* model = tab_handler_->GetTabStripModel();
4135 for (int i = model->count() - 1; i >= 0; --i) {
4136 TabContents* tc = model->GetTabContentsAt(i)->tab_contents();
4137 bool close_tab_contents =
4138 tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
4139 tc->GetURL().host() == extension->id();
4140 // We want to close all panels originated by the unloaded extension.
4141 close_tab_contents = close_tab_contents ||
4142 (type_ == TYPE_PANEL &&
4143 (web_app::GetExtensionIdFromApplicationName(app_name_) ==
[email protected]f9e82d92011-10-29 00:50:454144 extension->id()));
[email protected]b3f7fe22011-11-11 19:27:564145 if (close_tab_contents) {
4146 CloseTabContents(tc);
4147 }
[email protected]894bb502009-05-21 22:39:574148 }
4149 }
4150 break;
4151 }
4152
[email protected]432115822011-07-10 15:52:274153 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
[email protected]6c2381d2011-10-19 02:52:534154 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]fe8944f2011-08-30 17:47:324155 if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364156 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:464157 break;
4158 }
4159
[email protected]432115822011-07-10 15:52:274160 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
4161 case chrome::NOTIFICATION_EXTENSION_LOADED:
[email protected]1797f4a2011-08-30 18:00:284162 // During window creation on Windows we may end up calling into
4163 // SHAppBarMessage, which internally spawns a nested message loop. This
4164 // makes it possible for us to end up here before window creation has
4165 // completed,at which point window_ is NULL. See 94752 for details.
4166 if (window() && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364167 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:364168 break;
[email protected]ad0c2e1b2010-01-30 00:00:104169
[email protected]432115822011-07-10 15:52:274170 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
[email protected]e001d412009-06-26 20:53:254171 window()->UserChangedTheme();
4172 break;
4173
[email protected]432115822011-07-10 15:52:274174 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]6c2381d2011-10-19 02:52:534175 const std::string& pref_name =
4176 *content::Details<std::string>(details).ptr();
[email protected]3cf345b2011-10-06 17:51:254177 if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:374178 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]3819f2ee2011-08-21 09:44:384179 } else if (pref_name == prefs::kInstantEnabled ||
4180 pref_name == prefs::kMetricsReportingEnabled ||
4181 pref_name == prefs::kSearchSuggestEnabled) {
[email protected]73de26a2010-10-17 03:23:254182 if (!InstantController::IsEnabled(profile())) {
4183 if (instant()) {
4184 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:294185 instant_.reset();
4186 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:254187 }
4188 } else {
4189 CreateInstantIfNecessary();
4190 }
[email protected]4e94ab32011-08-05 05:28:274191 } else if (pref_name == prefs::kIncognitoModeAvailability) {
[email protected]93ad8e1c2011-11-08 21:34:054192 UpdateCommandsForIncognitoAvailability();
[email protected]543432ee2010-10-22 16:32:134193 } else if (pref_name == prefs::kDevToolsDisabled) {
4194 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:044195 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]0e12d7d2011-12-01 16:21:444196 content::DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:584197 } else if (pref_name == prefs::kEditBookmarksEnabled) {
4198 UpdateCommandsForBookmarkEditing();
[email protected]3710d0002011-10-11 00:35:004199 } else if (pref_name == prefs::kShowBookmarkBar) {
[email protected]a007e732011-08-05 13:32:194200 UpdateCommandsForBookmarkBar();
[email protected]3710d0002011-10-11 00:35:004201 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]6c6b02d2011-09-02 03:36:474202 } else if (pref_name == prefs::kHomePage) {
[email protected]6c2381d2011-10-19 02:52:534203 PrefService* pref_service = content::Source<PrefService>(source).ptr();
[email protected]6c6b02d2011-09-02 03:36:474204 MarkHomePageAsChanged(pref_service);
[email protected]97b46382011-05-02 13:23:044205 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
4206 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
4207 UpdateOpenFileState();
[email protected]2a7e7c152010-10-01 20:12:094208 } else {
[email protected]b9c505b2010-04-30 15:05:104209 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:094210 }
[email protected]b9c505b2010-04-30 15:05:104211 break;
4212 }
4213
[email protected]432115822011-07-10 15:52:274214 case chrome::NOTIFICATION_TAB_CONTENT_SETTINGS_CHANGED: {
[email protected]6c2381d2011-10-19 02:52:534215 TabContents* tab_contents = content::Source<TabContents>(source).ptr();
[email protected]9a9a9e22011-05-13 22:20:354216 if (tab_contents == GetSelectedTabContents()) {
4217 LocationBar* location_bar = window()->GetLocationBar();
4218 if (location_bar)
4219 location_bar->UpdateContentSettingsIcons();
4220 }
4221 break;
4222 }
4223
[email protected]432115822011-07-10 15:52:274224 case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:484225 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]e397a4472011-12-21 21:47:504226 UpdateCommandsForTabState();
4227 break;
4228
4229 case content::NOTIFICATION_INTERSTITIAL_DETACHED:
4230 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
4231 UpdateCommandsForTabState();
[email protected]09b29342011-06-24 19:18:484232 break;
4233
[email protected]e83f1682008-09-07 23:57:404234 default:
4235 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:294236 }
4237}
4238
[email protected]d3b98c82010-07-14 07:45:594239///////////////////////////////////////////////////////////////////////////////
4240// Browser, ProfileSyncServiceObserver implementation:
4241
4242void Browser::OnStateChanged() {
4243 DCHECK(profile_->GetProfileSyncService());
4244
[email protected]93ad8e1c2011-11-08 21:34:054245 const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen());
[email protected]d3b98c82010-07-14 07:45:594246 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
[email protected]49385da692011-08-05 04:03:394247 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]d3b98c82010-07-14 07:45:594248}
[email protected]88d74942009-01-21 22:04:444249
[email protected]36b6dcb2008-11-12 01:19:574250///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:274251// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:304252
[email protected]3c9e1872010-11-18 16:17:494253void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
4254 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:144255 window_->ShowInstant(preview_contents);
[email protected]42f027fb2011-10-27 16:37:484256
4257 GetSelectedTabContents()->HideContents();
4258 preview_contents->tab_contents()->ShowContents();
[email protected]03bb953d2010-09-14 21:38:304259}
4260
[email protected]6b723f82010-10-05 20:14:274261void Browser::HideInstant() {
[email protected]3e481282011-10-15 15:39:504262 window_->HideInstant();
[email protected]42f027fb2011-10-27 16:37:484263 if (GetSelectedTabContents())
4264 GetSelectedTabContents()->ShowContents();
4265 if (instant_->GetPreviewContents())
4266 instant_->GetPreviewContents()->tab_contents()->HideContents();
[email protected]03bb953d2010-09-14 21:38:304267}
4268
[email protected]3c9e1872010-11-18 16:17:494269void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
4270 TabContentsWrapper* tab_contents = instant_->tab_contents();
4271 int index =
4272 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
4273 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:304274 // TabStripModel takes ownership of preview_contents.
[email protected]43032342011-03-21 14:10:314275 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
4276 index, preview_contents);
4277 // InstantUnloadHandler takes ownership of tab_contents.
4278 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:334279
4280 GURL url = preview_contents->tab_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:524281 DCHECK(profile_->GetExtensionService());
4282 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:334283 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
4284 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
4285 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
4286 }
[email protected]03bb953d2010-09-14 21:38:304287}
4288
[email protected]c98fd5d82011-05-04 15:20:094289void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
4290 TabContentsWrapper* new_tab_contents) {
4291 int index =
4292 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(old_tab_contents);
[email protected]71b5d242011-04-30 02:27:204293 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]c98fd5d82011-05-04 15:20:094294 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(index,
4295 new_tab_contents);
[email protected]71b5d242011-04-30 02:27:204296}
4297
[email protected]31145092011-09-30 01:49:444298void Browser::SetTabContentBlocked(TabContentsWrapper* wrapper, bool blocked) {
4299 int index = tabstrip_model()->GetIndexOfTabContents(wrapper);
4300 if (index == TabStripModel::kNoTab) {
4301 NOTREACHED();
4302 return;
4303 }
4304 tabstrip_model()->SetTabBlocked(index, blocked);
[email protected]43401bc02011-10-13 20:43:434305 UpdatePrintingState(wrapper->tab_contents()->content_restrictions());
[email protected]31145092011-09-30 01:49:444306}
4307
[email protected]33b8b8e2011-03-15 14:51:554308void Browser::SetSuggestedText(const string16& text,
4309 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:364310 if (window()->GetLocationBar())
4311 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:304312}
4313
[email protected]6b723f82010-10-05 20:14:274314gfx::Rect Browser::GetInstantBounds() {
4315 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:474316}
4317
[email protected]03bb953d2010-09-14 21:38:304318///////////////////////////////////////////////////////////////////////////////
[email protected]9800de5e2011-03-11 18:19:494319// Browser, protected:
4320
4321BrowserWindow* Browser::CreateBrowserWindow() {
[email protected]517d5742011-11-14 16:50:214322#if !defined(OS_CHROMEOS) || defined(USE_AURA)
[email protected]d5c14062011-10-27 00:02:134323 if (type_ == TYPE_PANEL) {
[email protected]011396a2011-04-13 23:35:284324 return PanelManager::GetInstance()->CreatePanel(this);
[email protected]d5c14062011-10-27 00:02:134325 }
4326#endif
[email protected]011396a2011-04-13 23:35:284327
[email protected]9800de5e2011-03-11 18:19:494328 return BrowserWindow::CreateBrowserWindow(this);
4329}
4330
4331
4332///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574333// Browser, Command and state updating (private):
4334
4335void Browser::InitCommandState() {
4336 // All browser commands whose state isn't set automagically some other way
4337 // (like Back & Forward with initial page load) must have their state
4338 // initialized here, otherwise they will be forever disabled.
4339
[email protected]84214982008-12-10 18:49:104340 // Navigation commands
[email protected]1fc025202009-01-20 23:03:144341 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:164342 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:104343
4344 // Window management commands
[email protected]1fc025202009-01-20 23:03:144345 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
4346 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
4347 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
4348 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:134349 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:144350 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]cdc05ec2011-05-18 15:15:594351 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:104352
4353 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:514354 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:144355 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
4356 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
4357 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
4358 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
4359 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
4360 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
4361 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
4362 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
4363 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
4364 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
4365 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
4366 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
4367 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
4368 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
4369 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
4370 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
4371 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
4372 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
4373 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
4374 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
4375 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
4376 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
4377 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
4378 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
4379 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
4380 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
4381 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
4382 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
4383 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
4384 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
4385 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
4386 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
4387 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
4388 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
4389 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:004390 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:144391 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
4392 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:104393
[email protected]63b02932009-06-05 09:40:514394 // Zoom
4395 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
4396 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
4397 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
4398 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
4399
[email protected]84214982008-12-10 18:49:104400 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:044401 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:144402 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:134403 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:144404 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:144405 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]1fc025202009-01-20 23:03:144406 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
4407 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]d6852fd2011-05-20 17:19:124408 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:294409
[email protected]96e34672010-02-09 21:40:294410#if defined(OS_CHROMEOS)
[email protected]05a44b6e2011-12-01 07:52:324411 command_updater_.UpdateCommandEnabled(IDC_LOCK_SCREEN, true);
[email protected]2166c432011-12-07 20:18:284412 command_updater_.UpdateCommandEnabled(IDC_SHUTDOWN, true);
[email protected]ec2fd5a2011-04-30 06:16:054413 command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
[email protected]f97d7f632010-06-01 21:08:334414 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:504415 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:474416 command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
4417 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:294418#endif
[email protected]a038159b2011-08-18 02:55:364419 command_updater_.UpdateCommandEnabled(
4420 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]c8b59f92010-05-28 21:45:474421
[email protected]64ff7942008-12-17 18:11:234422 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:144423 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:234424
[email protected]11f4857282009-11-13 19:56:174425 // Navigation commands
4426 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:234427
[email protected]11f4857282009-11-13 19:56:174428 // Window management commands
[email protected]d3766932011-08-04 22:18:234429 // TODO(rohitrao): Disable fullscreen on non-Lion?
[email protected]cf299bc2010-08-12 20:27:094430 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:144431 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:174432 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
4433 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
4434 normal_window);
4435 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
4436 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
4437 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
4438 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
4439 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
4440 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
4441 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
4442 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
4443 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
4444 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
4445 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:554446#if defined(OS_MACOSX)
4447 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
[email protected]d3766932011-08-04 22:18:234448 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
4449 !(is_type_panel() && is_app()));
[email protected]c1d0d812010-07-27 20:21:554450#endif
[email protected]e662ade2009-06-08 18:20:144451
[email protected]fc33e9992010-04-08 19:40:134452 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:144453 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134454
4455 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:144456 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
4457 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
4458 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134459
[email protected]11f4857282009-11-13 19:56:174460 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:134461 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:004462
[email protected]c1bbaa82010-11-08 11:17:054463 // The upgrade entry and the view incompatibility entry should always be
4464 // enabled. Whether they are visible is a separate matter determined on menu
4465 // show.
[email protected]b21d6912010-08-31 19:22:414466 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:054467 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:414468
[email protected]b569c112010-11-22 20:53:444469 // View Background Pages entry is always enabled, but is hidden if there are
4470 // no background pages.
4471 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
4472
[email protected]afcb43562011-09-02 23:33:384473 // Toggle speech input
4474 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
4475
[email protected]9282cea2009-02-18 18:49:004476 // Initialize other commands whose state changes based on fullscreen mode.
4477 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:004478
4479 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584480
4481 UpdateCommandsForBookmarkEditing();
[email protected]93ad8e1c2011-11-08 21:34:054482
4483 UpdateCommandsForIncognitoAvailability();
4484}
4485
4486bool Browser::IsShowingMainUI(bool is_fullscreen) {
4487#if !defined(OS_MACOSX)
4488 return is_type_tabbed() && !is_fullscreen;
4489#else
4490 return is_type_tabbed();
4491#endif
4492}
4493
4494void Browser::UpdateCommandsForIncognitoAvailability() {
4495 IncognitoModePrefs::Availability incognito_availability =
4496 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
4497 command_updater_.UpdateCommandEnabled(
4498 IDC_NEW_WINDOW,
4499 incognito_availability != IncognitoModePrefs::FORCED);
4500 command_updater_.UpdateCommandEnabled(
4501 IDC_NEW_INCOGNITO_WINDOW,
4502 incognito_availability != IncognitoModePrefs::DISABLED);
4503
4504 // Bookmark manager and settings page/subpages are forced to open in normal
4505 // mode. For this reason we disable these commands when incognito is forced.
4506 const bool command_enabled =
4507 incognito_availability != IncognitoModePrefs::FORCED;
4508 command_updater_.UpdateCommandEnabled(
4509 IDC_SHOW_BOOKMARK_MANAGER,
4510 browser_defaults::bookmarks_enabled && command_enabled);
4511 ExtensionService* extension_service = profile()->GetExtensionService();
4512 bool enable_extensions =
4513 extension_service && extension_service->extensions_enabled();
4514 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
4515 enable_extensions && command_enabled);
4516
4517 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4518 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
4519 show_main_ui && command_enabled);
4520 command_updater_.UpdateCommandEnabled(IDC_OPTIONS,
4521 show_main_ui && command_enabled);
[email protected]36b6dcb2008-11-12 01:19:574522}
4523
[email protected]227393e2011-06-29 21:28:394524void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
[email protected]93ad8e1c2011-11-08 21:34:054525 const bool show_main_ui = IsShowingMainUI(is_fullscreen);
[email protected]227393e2011-06-29 21:28:394526 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
4527
4528 // Navigation commands
4529 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
4530
4531 // Window management commands
4532 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
4533 type_ != TYPE_TABBED && !is_fullscreen);
4534
4535 // Focus various bits of UI
4536 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
4537 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
4538 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
4539 command_updater_.UpdateCommandEnabled(
4540 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
4541 command_updater_.UpdateCommandEnabled(
4542 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
4543 command_updater_.UpdateCommandEnabled(
4544 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
4545 command_updater_.UpdateCommandEnabled(
4546 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
4547 command_updater_.UpdateCommandEnabled(
4548 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
4549
4550 // Show various bits of UI
4551 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
4552 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]227393e2011-06-29 21:28:394553 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
[email protected]49385da692011-08-05 04:03:394554 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]227393e2011-06-29 21:28:394555
[email protected]93ad8e1c2011-11-08 21:34:054556 // Settings page/subpages are forced to open in normal mode. We disable these
4557 // commands when incognito is forced.
4558 const bool options_enabled = show_main_ui &&
4559 IncognitoModePrefs::GetAvailability(
4560 profile_->GetPrefs()) != IncognitoModePrefs::FORCED;
4561 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
4562 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
4563
[email protected]227393e2011-06-29 21:28:394564 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
4565 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
4566 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
4567 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]7d2d08152011-10-25 22:58:474568 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
4569 show_main_ui && !profile()->IsOffTheRecord());
[email protected]227393e2011-06-29 21:28:394570#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
4571 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
4572#endif
[email protected]a007e732011-08-05 13:32:194573
4574 UpdateCommandsForBookmarkBar();
[email protected]227393e2011-06-29 21:28:394575}
4576
[email protected]84214982008-12-10 18:49:104577void Browser::UpdateCommandsForTabState() {
[email protected]c7c42332008-11-15 01:10:544578 TabContents* current_tab = GetSelectedTabContents();
[email protected]a0366a52011-02-04 20:04:214579 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
4580 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:394581 return;
[email protected]d8375fd2008-11-25 22:45:394582
[email protected]84214982008-12-10 18:49:104583 // Navigation commands
[email protected]10b833e2011-12-21 17:36:304584 NavigationController& nc = current_tab->controller();
[email protected]ce3fa3c2009-04-20 19:55:574585 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
4586 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:134587 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
4588 CanReloadContents(current_tab));
4589 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
4590 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:294591
[email protected]84214982008-12-10 18:49:104592 // Window management commands
[email protected]1fc025202009-01-20 23:03:144593 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:144594 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:104595
[email protected]57c6a652009-05-04 07:58:344596 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:384597 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:144598 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:344599 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]10b833e2011-12-21 17:36:304600 current_tab->controller().CanViewSource());
[email protected]151666e2010-10-21 17:05:254601 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
[email protected]cd8d90db2011-10-06 19:31:274602 toolbar_model_.ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:404603 if (is_devtools())
4604 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:254605
4606 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]e397a4472011-12-21 21:47:504607 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
4608 current_tab->showing_interstitial_page();
[email protected]c0f82ec52010-07-27 14:22:144609 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
4610 !is_chrome_internal && SavePackage::IsSavableContents(
4611 current_tab->contents_mime_type()));
4612
[email protected]57c6a652009-05-04 07:58:344613 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254614 // TODO(pinkerton): Disable app-mode in the model until we implement it
4615 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4616#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344617 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234618 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:254619#endif
[email protected]9e823662010-10-13 23:36:004620
4621 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584622 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004623}
4624
4625void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374626 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004627
4628 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184629 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
[email protected]9e823662010-10-13 23:36:004630 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184631 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
[email protected]9e823662010-10-13 23:36:004632 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184633 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044634 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004635 UpdatePrintingState(restrictions);
4636}
4637
4638void Browser::UpdatePrintingState(int content_restrictions) {
[email protected]43401bc02011-10-13 20:43:434639 bool print_enabled = true;
4640 bool advanced_print_enabled = true;
4641 if (g_browser_process->local_state()) {
4642 print_enabled =
4643 g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled);
4644 advanced_print_enabled = print_enabled;
[email protected]9e823662010-10-13 23:36:004645 }
[email protected]43401bc02011-10-13 20:43:434646 if (print_enabled) {
4647 // Do not print when a constrained window is showing. It's confusing.
4648 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
4649 bool has_constrained_window = (wrapper &&
4650 wrapper->constrained_window_tab_helper()->constrained_window_count());
4651 if (has_constrained_window ||
[email protected]4573fbd2011-10-31 20:25:184652 content_restrictions & content::CONTENT_RESTRICTION_PRINT) {
[email protected]43401bc02011-10-13 20:43:434653 print_enabled = false;
4654 advanced_print_enabled = false;
4655 }
4656
4657 // The exception is print preview,
4658 // where advanced printing is always enabled.
4659 printing::PrintPreviewTabController* controller =
4660 printing::PrintPreviewTabController::GetInstance();
[email protected]c19d9542011-11-15 22:26:424661 if (controller && (controller->GetPrintPreviewForTab(wrapper) ||
4662 controller->is_creating_print_preview_tab())) {
[email protected]43401bc02011-10-13 20:43:434663 advanced_print_enabled = true;
4664 }
4665 }
4666 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
[email protected]0996e9b2011-08-26 17:59:014667 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
[email protected]43401bc02011-10-13 20:43:434668 advanced_print_enabled);
initial.commit09911bf2008-07-26 23:55:294669}
4670
[email protected]943d8122010-06-11 02:13:454671void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4672 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:144673 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:234674}
4675
[email protected]543432ee2010-10-22 16:32:134676void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044677 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424678 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134679 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4680 dev_tools_enabled);
4681 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4682 dev_tools_enabled);
4683 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4684 dev_tools_enabled);
4685}
4686
[email protected]a13f47d12011-04-14 11:41:584687void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044688 bool enabled =
4689 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4690 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584691
4692 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144693 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584694 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4695 enabled && CanBookmarkAllTabs());
4696}
4697
[email protected]a007e732011-08-05 13:32:194698void Browser::UpdateCommandsForBookmarkBar() {
[email protected]93ad8e1c2011-11-08 21:34:054699 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
[email protected]a007e732011-08-05 13:32:194700 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
4701 browser_defaults::bookmarks_enabled &&
[email protected]3710d0002011-10-11 00:35:004702 !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
[email protected]a007e732011-08-05 13:32:194703 show_main_ui);
4704}
4705
[email protected]6c6b02d2011-09-02 03:36:474706void Browser::MarkHomePageAsChanged(PrefService* pref_service) {
4707 pref_service->SetBoolean(prefs::kHomePageChanged, true);
4708 pref_service->ScheduleSavePersistentPrefs();
4709}
4710
[email protected]97b46382011-05-02 13:23:044711void Browser::UpdateSaveAsState(int content_restrictions) {
[email protected]4573fbd2011-10-31 20:25:184712 bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE);
[email protected]97b46382011-05-02 13:23:044713 PrefService* state = g_browser_process->local_state();
4714 if (state)
4715 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4716
4717 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4718}
4719
4720void Browser::UpdateOpenFileState() {
4721 bool enabled = true;
4722 PrefService* local_state = g_browser_process->local_state();
4723 if (local_state)
4724 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4725
4726 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4727}
4728
[email protected]36b6dcb2008-11-12 01:19:574729///////////////////////////////////////////////////////////////////////////////
4730// Browser, UI update coalescing and handling (private):
4731
4732void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:494733 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294734}
4735
[email protected]36b6dcb2008-11-12 01:19:574736void Browser::ScheduleUIUpdate(const TabContents* source,
4737 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004738 if (!source)
4739 return;
4740
[email protected]2b4355c2009-04-04 17:55:464741 // Do some synchronous updates.
[email protected]36b6dcb2008-11-12 01:19:574742 if (changed_flags & TabContents::INVALIDATE_URL &&
4743 source == GetSelectedTabContents()) {
4744 // Only update the URL for the current tab. Note that we do not update
4745 // the navigation commands since those would have already been updated
4746 // synchronously by NavigationStateChanged.
4747 UpdateToolbar(false);
[email protected]8030f012009-09-25 18:09:374748 changed_flags &= ~TabContents::INVALIDATE_URL;
[email protected]36b6dcb2008-11-12 01:19:574749 }
[email protected]a5231662009-09-26 00:56:004750 if (changed_flags & TabContents::INVALIDATE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574751 // Update the loading state synchronously. This is so the throbber will
4752 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004753 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:404754 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4755 tab_handler_->GetTabStripModel()->GetIndexOfController(
[email protected]10b833e2011-12-21 17:36:304756 &source->controller()),
[email protected]6ebdc9b2010-09-27 16:55:574757 TabStripModelObserver::LOADING_ONLY);
4758 // The status bubble needs to be updated during INVALIDATE_LOAD too, but
4759 // we do that asynchronously by not stripping INVALIDATE_LOAD from
4760 // changed_flags.
[email protected]8030f012009-09-25 18:09:374761 }
4762
[email protected]f5d978c2011-07-21 14:43:514763 if (changed_flags & TabContents::INVALIDATE_TITLE && !source->IsLoading()) {
[email protected]f1cd5e82009-10-23 17:19:034764 // To correctly calculate whether the title changed while not loading
4765 // we need to process the update synchronously. This state only matters for
4766 // the TabStripModel, so we notify the TabStripModel now and notify others
4767 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:404768 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4769 tab_handler_->GetTabStripModel()->GetIndexOfController(
[email protected]10b833e2011-12-21 17:36:304770 &source->controller()),
[email protected]f1cd5e82009-10-23 17:19:034771 TabStripModelObserver::TITLE_NOT_LOADING);
4772 }
4773
[email protected]2b4355c2009-04-04 17:55:464774 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374775 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464776 return;
[email protected]36b6dcb2008-11-12 01:19:574777
4778 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404779 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574780
[email protected]24f1477532011-11-22 22:55:364781 if (!chrome_updater_factory_.HasWeakPtrs()) {
[email protected]36b6dcb2008-11-12 01:19:574782 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374783 MessageLoop::current()->PostDelayedTask(
4784 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:364785 base::Bind(&Browser::ProcessPendingUIUpdates,
4786 chrome_updater_factory_.GetWeakPtr()),
4787 kUIUpdateCoalescingTimeMS);
[email protected]36b6dcb2008-11-12 01:19:574788 }
4789}
4790
4791void Browser::ProcessPendingUIUpdates() {
4792#ifndef NDEBUG
4793 // Validate that all tabs we have pending updates for exist. This is scary
4794 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004795 // deleted tabs.
[email protected]85354982009-09-25 19:58:404796 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4797 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574798 bool found = false;
4799 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]a5231662009-09-26 00:56:004800 if (GetTabContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574801 found = true;
4802 break;
4803 }
4804 }
4805 DCHECK(found);
4806 }
4807#endif
4808
[email protected]24f1477532011-11-22 22:55:364809 chrome_updater_factory_.InvalidateWeakPtrs();
[email protected]36b6dcb2008-11-12 01:19:574810
[email protected]85354982009-09-25 19:58:404811 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4812 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574813 // Do not dereference |contents|, it may be out-of-date!
[email protected]85354982009-09-25 19:58:404814 const TabContents* contents = i->first;
4815 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574816
[email protected]a5231662009-09-26 00:56:004817 if (contents == GetSelectedTabContents()) {
4818 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344819
[email protected]9800de5e2011-03-11 18:19:494820 if (flags & TabContents::INVALIDATE_PAGE_ACTIONS) {
4821 LocationBar* location_bar = window()->GetLocationBar();
4822 if (location_bar)
4823 location_bar->UpdatePageActions();
4824 }
[email protected]6ebdc9b2010-09-27 16:55:574825 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]0dd3a0ab2011-02-18 08:17:444826 if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) {
4827 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:294828 GetSelectedTabContentsWrapper()->
4829 core_tab_helper()->GetStatusText());
[email protected]0dd3a0ab2011-02-18 08:17:444830 }
[email protected]a5231662009-09-26 00:56:004831
[email protected]f1cd5e82009-10-23 17:19:034832 if (flags & (TabContents::INVALIDATE_TAB |
4833 TabContents::INVALIDATE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254834// TODO(pinkerton): Disable app-mode in the model until we implement it
4835// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4836#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004837 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234838 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254839#endif
[email protected]a5231662009-09-26 00:56:004840 window_->UpdateTitleBar();
4841 }
[email protected]4d34e2e2009-05-26 22:55:284842 }
[email protected]36b6dcb2008-11-12 01:19:574843
[email protected]a5231662009-09-26 00:56:004844 // Updates that don't depend upon the selected state go here.
[email protected]f1cd5e82009-10-23 17:19:034845 if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:404846 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:494847 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034848 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574849 }
4850
4851 // We don't need to process INVALIDATE_STATE, since that's not visible.
4852 }
4853
4854 scheduled_updates_.clear();
4855}
4856
4857void Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
4858 if (!contents)
4859 return;
4860
[email protected]85354982009-09-25 19:58:404861 UpdateMap::iterator i = scheduled_updates_.find(contents);
4862 if (i != scheduled_updates_.end())
4863 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294864}
4865
[email protected]d938aed92009-01-22 19:49:334866
[email protected]36b6dcb2008-11-12 01:19:574867///////////////////////////////////////////////////////////////////////////////
4868// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294869
[email protected]36b6dcb2008-11-12 01:19:574870StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094871#if !defined(OS_MACOSX)
4872 // In kiosk mode, we want to always hide the status bubble.
4873 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4874 return NULL;
4875#endif
[email protected]9b032bf2009-07-21 17:34:234876 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294877}
4878
[email protected]36b6dcb2008-11-12 01:19:574879///////////////////////////////////////////////////////////////////////////////
4880// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294881
4882void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154883 SessionService* session_service =
4884 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294885 if (session_service) {
4886 for (int i = index; i < tab_count(); ++i) {
[email protected]81898992011-06-14 22:15:004887 TabContentsWrapper* tab = GetTabContentsWrapperAt(i);
4888 if (tab) {
initial.commit09911bf2008-07-26 23:55:294889 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:004890 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404891 session_service->SetPinnedState(
4892 session_id(),
[email protected]81898992011-06-14 22:15:004893 tab->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:404894 tab_handler_->GetTabStripModel()->IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294895 }
4896 }
4897 }
4898}
4899
[email protected]36b6dcb2008-11-12 01:19:574900///////////////////////////////////////////////////////////////////////////////
4901// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294902
[email protected]04b4a6c2008-08-02 00:44:474903void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214904 if (!is_attempting_to_close_browser_) {
4905 // Because we might invoke this after a delay it's possible for the value of
4906 // is_attempting_to_close_browser_ to have changed since we scheduled the
4907 // task.
4908 return;
4909 }
initial.commit09911bf2008-07-26 23:55:294910
[email protected]04b4a6c2008-08-02 00:44:474911 if (HasCompletedUnloadProcessing()) {
4912 // We've finished all the unload events and can proceed to close the
4913 // browser.
4914 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294915 return;
4916 }
4917
[email protected]04b4a6c2008-08-02 00:44:474918 // Process beforeunload tabs first. When that queue is empty, process
4919 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474920 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]06b42f032008-12-03 18:43:054921 TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244922 // Null check render_view_host here as this gets called on a PostTask and
4923 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524924 if (tab->GetRenderViewHost()) {
4925 tab->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244926 } else {
[email protected]08f0d612011-01-13 23:58:214927 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244928 }
[email protected]04b4a6c2008-08-02 00:44:474929 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294930 // We've finished firing all beforeunload events and can proceed with unload
4931 // events.
4932 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4933 // somewhere around here so that we have accurate measurements of shutdown
4934 // time.
[email protected]04b4a6c2008-08-02 00:44:474935 // TODO(ojan): We can probably fire all the unload events in parallel and
4936 // get a perf benefit from that in the cases where the tab hangs in it's
4937 // unload handler or takes a long time to page in.
[email protected]06b42f032008-12-03 18:43:054938 TabContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244939 // Null check render_view_host here as this gets called on a PostTask and
4940 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524941 if (tab->GetRenderViewHost()) {
4942 tab->GetRenderViewHost()->ClosePage();
[email protected]22484622009-06-10 21:17:244943 } else {
[email protected]08f0d612011-01-13 23:58:214944 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244945 }
initial.commit09911bf2008-07-26 23:55:294946 } else {
[email protected]04b4a6c2008-08-02 00:44:474947 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294948 }
4949}
4950
[email protected]d043c2cc2009-03-25 18:30:454951bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474952 return is_attempting_to_close_browser_ &&
4953 tabs_needing_before_unload_fired_.empty() &&
4954 tabs_needing_unload_fired_.empty();
4955}
4956
4957void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044958 // Closing of window can be canceled from:
4959 // - canceling beforeunload
4960 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474961 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284962 tabs_needing_before_unload_fired_.clear();
4963 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474964 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044965
4966 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4967 TabCloseableStateWatcher* watcher =
4968 g_browser_process->tab_closeable_state_watcher();
4969 if (watcher)
4970 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474971}
4972
[email protected]06b42f032008-12-03 18:43:054973bool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474974 DCHECK(is_attempting_to_close_browser_);
4975
[email protected]06b42f032008-12-03 18:43:054976 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4977 if (iter != set->end()) {
4978 set->erase(iter);
4979 return true;
[email protected]04b4a6c2008-08-02 00:44:474980 }
4981 return false;
4982}
initial.commit09911bf2008-07-26 23:55:294983
[email protected]08f0d612011-01-13 23:58:214984void Browser::ClearUnloadState(TabContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044985 // Closing of browser could be canceled (via IsClosingPermitted) between the
4986 // time when request was initiated and when this method is called, so check
4987 // for is_attempting_to_close_browser_ flag before proceeding.
4988 if (is_attempting_to_close_browser_) {
4989 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4990 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:214991 if (process_now) {
4992 ProcessPendingTabs();
4993 } else {
4994 MessageLoop::current()->PostTask(
4995 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:364996 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr()));
[email protected]08f0d612011-01-13 23:58:214997 }
[email protected]0b4d3382010-07-14 16:13:044998 }
initial.commit09911bf2008-07-26 23:55:294999}
5000
[email protected]36b6dcb2008-11-12 01:19:575001///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:065002// Browser, In-progress download termination handling (private):
5003
[email protected]b6a4ac2b2011-10-17 20:05:485004bool Browser::CanCloseWithInProgressDownloads() {
[email protected]5a17d492011-10-24 19:37:035005 // If we've prompted, we need to hear from the user before we
5006 // can close.
5007 if (cancel_download_confirmation_state_ != NOT_PROMPTED)
5008 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
5009
5010 int num_downloads_blocking;
5011 if (DOWNLOAD_CLOSE_OK ==
5012 OkToCloseWithInProgressDownloads(&num_downloads_blocking))
[email protected]446295a2010-04-19 23:43:005013 return true;
5014
[email protected]5a17d492011-10-24 19:37:035015 // Closing this window will kill some downloads; prompt to make sure
5016 // that's ok.
[email protected]69444cc2009-04-09 20:40:065017 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
5018 window_->ConfirmBrowserCloseWithPendingDownloads();
5019
5020 // Return false so the browser does not close. We'll close if the user
5021 // confirms in the dialog.
5022 return false;
5023}
5024
5025///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:575026// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:295027
[email protected]1a6b30a2009-08-19 03:52:115028// static
[email protected]de4e7632010-09-01 06:24:045029Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
[email protected]b35b26b32011-05-05 20:35:145030 return BrowserList::FindTabbedBrowser(profile, match_incognito);
[email protected]de4e7632010-09-01 06:24:045031}
5032
5033// static
[email protected]1a6b30a2009-08-19 03:52:115034Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:045035 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:055036 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:115037 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:295038 return browser;
5039}
5040
[email protected]9219d262011-02-15 21:05:125041void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]e7cfdbd2011-04-22 14:41:375042 // TabContents...
[email protected]6934a702011-12-20 00:04:515043 tab->tab_contents()->SetDelegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:375044
5045 // ...and all the helpers.
5046 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:145047 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]31145092011-09-30 01:49:445048 tab->constrained_window_tab_helper()->set_delegate(delegate);
[email protected]51d83bdf2011-12-09 16:09:295049 tab->core_tab_helper()->set_delegate(delegate);
[email protected]1739e57d2011-11-30 21:18:255050 tab->extension_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:125051 tab->search_engine_tab_helper()->set_delegate(delegate);
5052}
5053
[email protected]4f3dc372009-02-24 00:10:295054void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:585055 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:295056 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:005057 string16 find_text;
5058#if defined(OS_MACOSX)
5059 // We always want to search for the contents of the find pasteboard on OS X.
5060 find_text = GetFindPboardText();
5061#endif
[email protected]9c318862011-02-01 22:27:245062 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:385063 find_tab_helper()->StartFinding(find_text,
5064 forward_direction,
5065 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:295066 }
[email protected]fbd77592008-11-12 20:50:275067}
[email protected]cb17f7f2009-02-06 18:14:485068
[email protected]36b6dcb2008-11-12 01:19:575069void Browser::CloseFrame() {
5070 window_->Close();
initial.commit09911bf2008-07-26 23:55:295071}
5072
[email protected]3c9e1872010-11-18 16:17:495073void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:175074 DetachType type) {
5075 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:155076 // Save the current location bar state, but only if the tab being detached
5077 // is the selected tab. Because saving state can conditionally revert the
5078 // location bar, saving the current tab's location bar state to a
5079 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:495080 if (contents == GetSelectedTabContentsWrapper()) {
5081 LocationBar* location_bar = window()->GetLocationBar();
5082 if (location_bar)
5083 location_bar->SaveStateToContents(contents->tab_contents());
5084 }
[email protected]c37e3b62010-01-22 00:15:175085
[email protected]ecc523f62010-09-28 22:45:405086 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:175087 SyncHistoryWithTabs(0);
5088 }
5089
[email protected]9219d262011-02-15 21:05:125090 SetAsDelegate(contents, NULL);
[email protected]3c9e1872010-11-18 16:17:495091 RemoveScheduledUpdatesFor(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:175092
[email protected]ecc523f62010-09-28 22:45:405093 if (find_bar_controller_.get() &&
[email protected]1ea49d52011-04-12 17:44:445094 index == tab_handler_->GetTabStripModel()->active_index()) {
[email protected]c37e3b62010-01-22 00:15:175095 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:405096 }
[email protected]c37e3b62010-01-22 00:15:175097
[email protected]08f0d612011-01-13 23:58:215098 if (is_attempting_to_close_browser_) {
5099 // If this is the last tab with unload handlers, then ProcessPendingTabs
5100 // would call back into the TabStripModel (which is invoking this method on
5101 // us). Avoid that by passing in false so that the call to
5102 // ProcessPendingTabs is delayed.
5103 ClearUnloadState(contents->tab_contents(), false);
5104 }
5105
[email protected]432115822011-07-10 15:52:275106 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]6c2381d2011-10-19 02:52:535107 content::Source<TabContents>(contents->tab_contents()));
[email protected]e397a4472011-12-21 21:47:505108 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
5109 content::Source<TabContents>(contents->tab_contents()));
[email protected]432115822011-07-10 15:52:275110 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED,
[email protected]6c2381d2011-10-19 02:52:535111 content::Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:175112}
5113
initial.commit09911bf2008-07-26 23:55:295114// static
[email protected]f87919d72011-02-02 18:46:165115void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:295116 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:515117 std::string window_pref(prefs::kBrowserWindowPlacement);
5118 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:295119 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:145120 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:165121 if (!prefs->FindPreference(window_pref.c_str())) {
5122 prefs->RegisterDictionaryPref(window_pref.c_str(),
5123 PrefService::UNSYNCABLE_PREF);
5124 }
initial.commit09911bf2008-07-26 23:55:295125}
[email protected]5c238752009-06-13 10:29:075126
[email protected]281918912010-05-27 22:05:135127void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
5128 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
5129 !service->entries().empty());
5130}
5131
5132void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
5133 if (!tab_restore_service_)
5134 return;
5135
5136 DCHECK_EQ(tab_restore_service_, service);
5137 tab_restore_service_->RemoveObserver(this);
5138 tab_restore_service_ = NULL;
5139}
[email protected]97b6c4f2010-09-27 19:31:265140
[email protected]3c9e1872010-11-18 16:17:495141// Centralized method for creating a TabContents, configuring and installing
5142// all its supporting objects and observers.
5143TabContentsWrapper* Browser::TabContentsFactory(
5144 Profile* profile,
5145 SiteInstance* site_instance,
5146 int routing_id,
5147 const TabContents* base_tab_contents,
5148 SessionStorageNamespace* session_storage_namespace) {
5149 TabContents* new_contents = new TabContents(profile, site_instance,
5150 routing_id, base_tab_contents,
5151 session_storage_namespace);
5152 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
5153 return wrapper;
5154}
5155
[email protected]6b723f82010-10-05 20:14:275156bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]3e481282011-10-15 15:39:505157 if (!instant() || !instant()->PrepareForCommit() ||
[email protected]35242602011-01-06 16:38:535158 disposition == NEW_BACKGROUND_TAB) {
5159 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
5160 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:265161 return false;
[email protected]35242602011-01-06 16:38:535162 }
[email protected]97b6c4f2010-09-27 19:31:265163
5164 if (disposition == CURRENT_TAB) {
[email protected]ad50def52011-10-19 23:17:075165 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275166 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535167 content::Source<TabContentsWrapper>(instant()->CommitCurrentPreview(
[email protected]094b0522011-10-06 00:55:275168 INSTANT_COMMIT_PRESSED_ENTER)),
[email protected]ad50def52011-10-19 23:17:075169 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265170 return true;
5171 }
[email protected]35242602011-01-06 16:38:535172 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:495173 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]6b723f82010-10-05 20:14:275174 INSTANT_COMMIT_PRESSED_ENTER);
[email protected]a0df03c122011-01-05 00:22:555175 // HideInstant is invoked after release so that InstantController is not
5176 // active when HideInstant asks it for its state.
5177 HideInstant();
[email protected]10b833e2011-12-21 17:36:305178 preview_contents->tab_contents()->controller().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:405179 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:265180 preview_contents,
5181 -1,
[email protected]6b723f82010-10-05 20:14:275182 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:415183 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:375184 instant()->CompleteRelease(preview_contents);
[email protected]ad50def52011-10-19 23:17:075185 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275186 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535187 content::Source<TabContentsWrapper>(preview_contents),
[email protected]ad50def52011-10-19 23:17:075188 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265189 return true;
5190 }
5191 // The omnibox currently doesn't use other dispositions, so we don't attempt
5192 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
5193 // support for the new disposition.
5194 NOTREACHED();
5195 return false;
5196}
[email protected]2031cf9d2010-10-12 05:05:375197
5198void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:145199 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:375200 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:195201 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:295202 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:375203 }
5204}
[email protected]77d8d622010-12-15 10:30:125205
5206void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:275207 DCHECK(contents);
5208
[email protected]4a63e242011-12-12 15:23:085209 NavigationEntry* active_entry =
[email protected]10b833e2011-12-21 17:36:305210 contents->tab_contents()->controller().GetActiveEntry();
[email protected]932b7a12011-03-09 12:50:275211 if (!active_entry)
5212 return;
5213
5214 ViewSource(contents, active_entry->url(), active_entry->content_state());
5215}
5216
5217void Browser::ViewSource(TabContentsWrapper* contents,
5218 const GURL& url,
5219 const std::string& content_state) {
[email protected]7f6f44c2011-12-14 13:23:385220 content::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:125221 DCHECK(contents);
5222
5223 TabContentsWrapper* view_source_contents = contents->Clone();
[email protected]10b833e2011-12-21 17:36:305224 view_source_contents->tab_contents()->controller().PruneAllButActive();
[email protected]77d8d622010-12-15 10:30:125225 NavigationEntry* active_entry =
[email protected]10b833e2011-12-21 17:36:305226 view_source_contents->tab_contents()->controller().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:505227 if (!active_entry)
5228 return;
5229
[email protected]932b7a12011-03-09 12:50:275230 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
5231 url.spec());
5232 active_entry->set_virtual_url(view_source_url);
[email protected]1436beff2010-12-16 19:47:045233
[email protected]932b7a12011-03-09 12:50:275234 // Do not restore scroller position.
5235 active_entry->set_content_state(
5236 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
5237
[email protected]cd3d50d2010-12-18 21:03:295238 // Do not restore title, derive it from the url.
[email protected]6b2f7a82011-04-25 19:30:515239 active_entry->set_title(string16());
[email protected]77d8d622010-12-15 10:30:125240
[email protected]47b309f2010-12-28 17:35:565241 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:125242 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
5243 // If this is a tabbed browser, just create a duplicate tab inside the same
5244 // window next to the tab being duplicated.
5245 int index = tab_handler_->GetTabStripModel()->
5246 GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:415247 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:565248 TabStripModel::ADD_INHERIT_GROUP;
[email protected]77d8d622010-12-15 10:30:125249 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]47b309f2010-12-28 17:35:565250 view_source_contents,
[email protected]77d8d622010-12-15 10:30:125251 add_types);
5252 } else {
[email protected]b35b26b32011-05-05 20:35:145253 Browser* browser = Browser::CreateForType(TYPE_TABBED, profile_);
[email protected]77d8d622010-12-15 10:30:125254
5255 // Preserve the size of the original window. The new window has already
5256 // been given an offset by the OS, so we shouldn't copy the old bounds.
5257 BrowserWindow* new_window = browser->window();
5258 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
5259 window()->GetRestoredBounds().size()));
5260
5261 // We need to show the browser now. Otherwise ContainerWin assumes the
5262 // TabContents is invisible and won't size it.
5263 browser->window()->Show();
5264
5265 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:585266 browser->AddTab(view_source_contents, content::PAGE_TRANSITION_LINK);
[email protected]77d8d622010-12-15 10:30:125267 }
5268
[email protected]92371eb2011-04-28 11:50:155269 SessionService* session_service =
5270 SessionServiceFactory::GetForProfileIfExisting(profile_);
5271 if (session_service)
[email protected]81898992011-06-14 22:15:005272 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:125273}
[email protected]b9163e02011-04-20 16:03:375274
5275int Browser::GetContentRestrictionsForSelectedTab() {
5276 int content_restrictions = 0;
5277 TabContents* current_tab = GetSelectedTabContents();
5278 if (current_tab) {
5279 content_restrictions = current_tab->content_restrictions();
[email protected]10b833e2011-12-21 17:36:305280 NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
[email protected]b9163e02011-04-20 16:03:375281 // See comment in UpdateCommandsForTabState about why we call url().
[email protected]e397a4472011-12-21 21:47:505282 if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL())
5283 || current_tab->showing_interstitial_page())
[email protected]4573fbd2011-10-31 20:25:185284 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
[email protected]e397a4472011-12-21 21:47:505285 if (current_tab->showing_interstitial_page())
5286 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
[email protected]b9163e02011-04-20 16:03:375287 }
5288 return content_restrictions;
5289}
[email protected]09b29342011-06-24 19:18:485290
5291void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
5292 BookmarkBar::State state;
[email protected]227393e2011-06-29 21:28:395293 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
[email protected]3710d0002011-10-11 00:35:005294 if (browser_defaults::bookmarks_enabled &&
5295 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
[email protected]227393e2011-06-29 21:28:395296 (!window_ || !window_->IsFullscreen())) {
[email protected]09b29342011-06-24 19:18:485297 state = BookmarkBar::SHOW;
5298 } else {
5299 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
5300 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
5301 state = BookmarkBar::DETACHED;
5302 else
5303 state = BookmarkBar::HIDDEN;
5304 }
5305 if (state == bookmark_bar_state_)
5306 return;
5307
5308 bookmark_bar_state_ = state;
5309
5310 if (!window_)
5311 return; // This is called from the constructor when window_ is NULL.
5312
5313 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
5314 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
5315 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
5316 // end up querying state once they process the tab switch.
5317 return;
5318 }
5319
5320 BookmarkBar::AnimateChangeType animate_type =
5321 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
5322 BookmarkBar::ANIMATE_STATE_CHANGE :
5323 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
5324 window_->BookmarkBarStateChanged(animate_type);
5325}
[email protected]2e2cacc2011-07-12 21:54:265326
5327void Browser::ShowSyncSetup() {
[email protected]e0dc2cb2011-08-04 03:22:575328 ProfileSyncService* service =
5329 profile()->GetOriginalProfile()->GetProfileSyncService();
[email protected]2e2cacc2011-07-12 21:54:265330 if (service->HasSyncSetupCompleted())
[email protected]a981fd62011-10-08 03:09:045331 ShowOptionsTab(chrome::kPersonalOptionsSubPage);
[email protected]2e2cacc2011-07-12 21:54:265332 else
[email protected]e0dc2cb2011-08-04 03:22:575333 service->ShowLoginDialog();
[email protected]2e2cacc2011-07-12 21:54:265334}
[email protected]afcb43562011-09-02 23:33:385335
5336void Browser::ToggleSpeechInput() {
[email protected]151a63d2011-12-20 22:32:525337 GetSelectedTabContentsWrapper()->tab_contents()->GetRenderViewHost()->
[email protected]4a63e242011-12-12 15:23:085338 ToggleSpeechInput();
[email protected]afcb43562011-09-02 23:33:385339}
[email protected]2f516c792011-09-19 22:22:095340
5341void Browser::OnWindowDidShow() {
5342 if (window_has_shown_)
5343 return;
5344 window_has_shown_ = true;
5345
[email protected]7ffe7e12011-11-22 03:05:565346 // Nothing to do for non-tabbed windows.
5347 if (!is_type_tabbed())
5348 return;
5349
[email protected]4e72ebb2011-10-18 05:02:185350 // Suppress the first run bubble if we're showing the sync promo.
5351 TabContents* contents = GetSelectedTabContents();
[email protected]bba4ec5d2011-10-31 20:35:395352 bool is_showing_promo = contents &&
5353 contents->GetURL().SchemeIs(chrome::kChromeUIScheme) &&
5354 contents->GetURL().host() == chrome::kChromeUISyncPromoHost;
[email protected]4e72ebb2011-10-18 05:02:185355
[email protected]2f516c792011-09-19 22:22:095356 // Show the First Run information bubble if we've been told to.
5357 PrefService* local_state = g_browser_process->local_state();
[email protected]4e72ebb2011-10-18 05:02:185358 if (!is_showing_promo && local_state &&
[email protected]2f516c792011-09-19 22:22:095359 local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
[email protected]327f0da2011-11-08 22:52:435360 FirstRun::BubbleType bubble_type = FirstRun::MINIMAL_BUBBLE;
[email protected]2f516c792011-09-19 22:22:095361 if (local_state->
5362 FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
5363 local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
5364 bubble_type = FirstRun::OEM_BUBBLE;
5365 } else if (local_state->
5366 FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
5367 local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
5368 bubble_type = FirstRun::MINIMAL_BUBBLE;
5369 }
[email protected]4e72ebb2011-10-18 05:02:185370 // Reset the preference so we don't show the bubble for subsequent
5371 // windows.
5372 local_state->SetBoolean(prefs::kShouldShowFirstRunBubble, false);
[email protected]2f516c792011-09-19 22:22:095373 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
[email protected]7ffe7e12011-11-22 03:05:565374 } else {
[email protected]2f516c792011-09-19 22:22:095375 GlobalErrorService* service =
5376 GlobalErrorServiceFactory::GetForProfile(profile());
5377 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
5378 if (error) {
5379 error->ShowBubbleView(this);
[email protected]2f516c792011-09-19 22:22:095380 }
5381 }
[email protected]2f516c792011-09-19 22:22:095382}