blob: 6f34e7421bd448bd1b189349cdb516055ba17b5e [file] [log] [blame]
[email protected]daa9e382012-01-06 00:30:341// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]7b5dc002010-11-16 23:08:105#include "chrome/browser/ui/browser.h"
[email protected]c61db1d2009-02-06 03:39:186
[email protected]aca02cf2010-05-03 18:56:017#if defined(OS_WIN)
[email protected]541434c2011-06-25 01:38:598#include <windows.h>
[email protected]dcd57762011-06-25 12:18:519#include <shellapi.h>
[email protected]aca02cf2010-05-03 18:56:0110#endif // OS_WIN
11
[email protected]5dcbc02f2010-01-26 22:32:0612#include <algorithm>
13#include <string>
14
[email protected]b02d0382009-11-30 21:19:5015#include "base/base_paths.h"
[email protected]24f1477532011-11-22 22:55:3616#include "base/bind.h"
[email protected]8a53ee042009-01-21 16:41:3317#include "base/command_line.h"
[email protected]8a53ee042009-01-21 16:41:3318#include "base/logging.h"
[email protected]49098f702011-10-13 03:47:1819#include "base/metrics/field_trial.h"
[email protected]835d7c82010-10-14 04:38:3820#include "base/metrics/histogram.h"
[email protected]b02d0382009-11-30 21:19:5021#include "base/path_service.h"
[email protected]0af8f132011-07-16 01:37:0222#include "base/string_number_conversions.h"
[email protected]b6a4ac2b2011-10-17 20:05:4823#include "base/string_util.h"
[email protected]5a17d492011-10-24 19:37:0324#include "base/stringprintf.h"
[email protected]34b99632011-01-01 01:01:0625#include "base/threading/thread.h"
26#include "base/threading/thread_restrictions.h"
[email protected]7f070d42011-03-09 20:25:3227#include "base/time.h"
[email protected]6524385ef2010-08-18 06:34:1328#include "base/utf_string_conversions.h"
[email protected]1a3aba82010-11-08 23:52:5429#include "chrome/app/chrome_command_ids.h"
[email protected]ea9edcb02011-09-23 22:05:0430#include "chrome/browser/autofill/personal_data_manager_factory.h"
[email protected]a07676b22011-06-17 16:36:5331#include "chrome/browser/background/background_contents_service.h"
[email protected]4fdf6742012-01-10 20:14:3632#include "chrome/browser/background/background_contents_service_factory.h"
[email protected]a9afddb2009-02-12 17:49:4233#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5434#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]5c238752009-06-13 10:29:0735#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1836#include "chrome/browser/browser_shutdown.h"
[email protected]40d59ce52009-03-06 23:20:1437#include "chrome/browser/character_encoding.h"
[email protected]0f083402011-11-22 02:59:0138#include "chrome/browser/chrome_page_zoom.h"
[email protected]55c87fa2011-10-15 07:28:2839#include "chrome/browser/content_settings/host_content_settings_map.h"
[email protected]7d189022011-08-25 22:54:2040#include "chrome/browser/custom_handlers/protocol_handler_registry.h"
41#include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
[email protected]dce502762011-07-20 08:53:4942#include "chrome/browser/debugger/devtools_toggle_action.h"
43#include "chrome/browser/debugger/devtools_window.h"
[email protected]8a282712011-08-23 19:28:0044#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]59560e0b2009-06-04 03:30:2245#include "chrome/browser/download/download_item_model.h"
[email protected]9bb54ee2011-10-12 17:43:3546#include "chrome/browser/download/download_service.h"
47#include "chrome/browser/download/download_service_factory.h"
[email protected]a1bc3b82012-04-19 19:32:2048#include "chrome/browser/download/download_shelf.h"
[email protected]59560e0b2009-06-04 03:30:2249#include "chrome/browser/download/download_started_animation.h"
[email protected]a53209b2012-01-20 16:48:1650#include "chrome/browser/download/download_util.h"
[email protected]60fd60e2012-04-26 17:58:3351#include "chrome/browser/extensions/api/app/app_api.h"
[email protected]9c1662b2012-03-06 15:44:3352#include "chrome/browser/extensions/browser_extension_window_controller.h"
[email protected]bb461532010-11-26 21:50:2353#include "chrome/browser/extensions/crx_installer.h"
[email protected]49098f702011-10-13 03:47:1854#include "chrome/browser/extensions/default_apps_trial.h"
[email protected]10abd192010-09-30 02:03:4955#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0056#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0857#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5958#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0459#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]3a29a6e2011-08-24 18:26:2160#include "chrome/browser/file_select_helper.h"
[email protected]820735792010-07-29 23:40:0161#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4962#include "chrome/browser/google/google_url_tracker.h"
[email protected]7e204122011-09-01 18:56:2163#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]6b723f82010-10-05 20:14:2764#include "chrome/browser/instant/instant_controller.h"
[email protected]5aab5e22010-12-08 22:13:2965#include "chrome/browser/instant/instant_unload_handler.h"
[email protected]7d189022011-08-25 22:54:2066#include "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
[email protected]8f0bbd62012-02-22 03:37:1867#include "chrome/browser/intents/web_intents_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]4fdf6742012-01-10 20:14:3673#include "chrome/browser/prerender/prerender_manager.h"
74#include "chrome/browser/prerender/prerender_manager_factory.h"
[email protected]d952a052011-09-06 18:42:4575#include "chrome/browser/prerender/prerender_tab_helper.h"
[email protected]02337592010-09-27 18:38:2576#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]0996e9b2011-08-26 17:59:0177#include "chrome/browser/printing/print_preview_tab_controller.h"
[email protected]68761472011-08-31 18:55:1478#include "chrome/browser/printing/print_view_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3379#include "chrome/browser/profiles/profile.h"
[email protected]5e919242012-02-13 23:59:3580#include "chrome/browser/profiles/profile_destroyer.h"
[email protected]5a17d492011-10-24 19:37:0381#include "chrome/browser/profiles/profile_manager.h"
[email protected]a7be6982011-12-12 21:53:5782#include "chrome/browser/profiles/profile_metrics.h"
[email protected]67baffc82011-12-19 18:03:0783#include "chrome/browser/repost_form_warning_controller.h"
[email protected]81898992011-06-14 22:15:0084#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4485#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1586#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1887#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0688#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1589#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1390#include "chrome/browser/sync/profile_sync_service.h"
[email protected]5e61afb92012-01-27 20:09:1391#include "chrome/browser/sync/profile_sync_service_factory.h"
[email protected]40f047972009-11-25 03:54:4092#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0493#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2994#include "chrome/browser/tab_contents/background_contents.h"
[email protected]4fdf6742012-01-10 20:14:3695#include "chrome/browser/tab_contents/retargeting_details.h"
[email protected]7cceebac2011-03-03 00:32:2196#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]1ab4ddf2011-07-21 04:48:0497#include "chrome/browser/tab_contents/tab_util.h"
[email protected]ffa6f592011-06-24 22:03:5798#include "chrome/browser/themes/theme_service.h"
99#include "chrome/browser/themes/theme_service_factory.h"
[email protected]3ab9cb82011-06-03 18:02:07100#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:37101#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:14102#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]ef557022012-03-16 10:05:33103#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h"
[email protected]55452902011-06-01 21:57:47104#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:04105#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:37106#include "chrome/browser/ui/browser_navigator.h"
[email protected]fb7da4132011-03-15 15:51:00107#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]ef557022012-03-16 10:05:33108#include "chrome/browser/ui/browser_toolbar_model_delegate.h"
[email protected]00070c732011-04-09 15:31:33109#include "chrome/browser/ui/browser_window.h"
[email protected]31145092011-09-30 01:49:44110#include "chrome/browser/ui/constrained_window_tab_helper.h"
[email protected]a44657202012-01-09 05:48:31111#include "chrome/browser/ui/extensions/shell_window.h"
[email protected]45300ad42010-12-02 15:51:14112#include "chrome/browser/ui/find_bar/find_bar.h"
113#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:38114#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]bf8708692011-12-20 21:24:28115#include "chrome/browser/ui/fullscreen_controller.h"
[email protected]2f516c792011-09-19 22:22:09116#include "chrome/browser/ui/global_error.h"
117#include "chrome/browser/ui/global_error_service.h"
118#include "chrome/browser/ui/global_error_service_factory.h"
[email protected]8be45842012-04-13 19:49:29119#include "chrome/browser/ui/hung_plugin_tab_helper.h"
[email protected]943b8612011-08-31 21:07:13120#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
[email protected]6a3ec2312010-12-02 19:30:19121#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:43122#include "chrome/browser/ui/panels/panel.h"
123#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:12124#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19125#include "chrome/browser/ui/status_bubble.h"
[email protected]3da95a102011-11-30 21:47:45126#include "chrome/browser/ui/sync/browser_synced_window_delegate.h"
[email protected]51d83bdf2011-12-09 16:09:29127#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:19128#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:44129#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]b56e2e32012-05-11 21:18:04130#include "chrome/browser/ui/tabs/tab_finder.h"
[email protected]6a3ec2312010-12-02 19:30:19131#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]b56e2e32012-05-11 21:18:04132#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]f847e6082011-03-24 00:08:26133#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]daa9e382012-01-06 00:30:34134#include "chrome/browser/ui/webui/feedback_ui.h"
[email protected]a9acdff2012-03-08 04:04:52135#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
[email protected]6a1622a2011-09-20 22:37:45136#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
[email protected]a048ad22012-03-23 04:26:56137#include "chrome/browser/ui/webui/options2/content_settings_handler2.h"
[email protected]65549182012-02-25 00:45:40138#include "chrome/browser/ui/webui/signin/login_ui_service.h"
139#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
[email protected]9a800652010-12-02 17:08:44140#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54141#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50142#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33143#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:27144#include "chrome/common/chrome_notification_types.h"
[email protected]d938aed92009-01-22 19:49:33145#include "chrome/common/chrome_switches.h"
[email protected]7d189022011-08-25 22:54:20146#include "chrome/common/custom_handlers/protocol_handler.h"
[email protected]5b1a0e22009-05-26 19:00:58147#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33148#include "chrome/common/extensions/extension_constants.h"
[email protected]06305962012-05-09 22:34:36149#include "chrome/common/net/url_util.h"
[email protected]8a53ee042009-01-21 16:41:33150#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25151#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34152#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23153#include "chrome/common/web_apps.h"
[email protected]da8543762012-03-20 08:52:20154#include "content/public/browser/color_chooser.h"
[email protected]0e12d7d2011-12-01 16:21:44155#include "content/public/browser/devtools_manager.h"
[email protected]e582fdd2011-12-20 16:48:17156#include "content/public/browser/download_item.h"
157#include "content/public/browser/download_manager.h"
[email protected]cadaec52012-02-08 21:53:13158#include "content/public/browser/interstitial_page.h"
[email protected]d9083482012-01-06 00:38:46159#include "content/public/browser/invalidate_type.h"
[email protected]cdcb1dee2012-01-04 00:46:20160#include "content/public/browser/navigation_controller.h"
[email protected]022af742011-12-28 18:37:25161#include "content/public/browser/navigation_entry.h"
[email protected]7f6f44c2011-12-14 13:23:38162#include "content/public/browser/notification_details.h"
163#include "content/public/browser/notification_service.h"
[email protected]3a5180ae2011-12-21 02:39:38164#include "content/public/browser/plugin_service.h"
[email protected]9c1662b2012-03-06 15:44:33165#include "content/public/browser/render_process_host.h"
166#include "content/public/browser/render_view_host.h"
[email protected]b6583592012-01-25 19:52:33167#include "content/public/browser/site_instance.h"
[email protected]7f6f44c2011-12-14 13:23:38168#include "content/public/browser/user_metrics.h"
[email protected]d9083482012-01-06 00:38:46169#include "content/public/browser/web_contents.h"
[email protected]8643e6d2012-01-18 20:26:10170#include "content/public/browser/web_contents_view.h"
[email protected]0d9989d2011-12-21 20:26:00171#include "content/public/browser/web_intents_dispatcher.h"
[email protected]4573fbd2011-10-31 20:25:18172#include "content/public/common/content_restriction.h"
[email protected]c08950d22011-10-13 22:20:29173#include "content/public/common/content_switches.h"
[email protected]0f083402011-11-22 02:59:01174#include "content/public/common/page_zoom.h"
[email protected]cadaec52012-02-08 21:53:13175#include "content/public/common/renderer_preferences.h"
[email protected]a3e18c42009-03-04 23:36:05176#include "grit/chromium_strings.h"
177#include "grit/generated_resources.h"
178#include "grit/locale_settings.h"
[email protected]d952a052011-09-06 18:42:45179#include "grit/theme_resources_standard.h"
[email protected]8a53ee042009-01-21 16:41:33180#include "net/base/net_util.h"
181#include "net/base/registry_controlled_domain.h"
[email protected]4d7c4ef2012-03-16 01:47:12182#include "net/cookies/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33183#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39184#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17185#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38186#include "ui/gfx/point.h"
[email protected]ce9751942011-09-21 01:57:24187#include "webkit/glue/web_intent_data.h"
[email protected]4a19be92011-09-22 14:25:02188#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33189#include "webkit/glue/window_open_disposition.h"
[email protected]3a5180ae2011-12-21 02:39:38190#include "webkit/plugins/webplugininfo.h"
[email protected]8a53ee042009-01-21 16:41:33191
192#if defined(OS_WIN)
[email protected]36d5e5592010-11-15 20:45:59193#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15194#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59195#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12196#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19197#include "chrome/browser/ui/view_ids.h"
198#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]dcd57762011-06-25 12:18:51199#include "ui/base/win/shell.h"
[email protected]8a53ee042009-01-21 16:41:33200#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33201
[email protected]6a4f5af22009-09-23 22:43:00202#if defined(OS_MACOSX)
[email protected]feb72832012-03-08 00:38:24203#include "ui/base/cocoa/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00204#endif
205
[email protected]b7969202010-05-14 21:29:26206#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35207#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]b7813a22012-04-04 18:41:02208#include "chrome/browser/chromeos/gdata/gdata_util.h"
[email protected]eab8c0f2011-11-18 22:33:50209#endif
210
[email protected]dc04be7c2012-03-15 23:57:49211#if defined(USE_ASH)
[email protected]bafda132012-02-16 19:32:51212#include "ash/ash_switches.h"
[email protected]c2f0a892012-01-24 22:19:21213#include "ash/shell.h"
[email protected]5408983162012-03-02 22:40:55214#include "chrome/browser/ui/views/ash/panel_view_aura.h"
[email protected]c2f0a892012-01-24 22:19:21215#endif
216
[email protected]8a53ee042009-01-21 16:41:33217using base::TimeDelta;
[email protected]c5eed492012-01-04 17:07:50218using content::NavigationController;
[email protected]10f417c52011-12-28 21:04:23219using content::NavigationEntry;
[email protected]e5d549d2011-12-28 01:29:20220using content::OpenURLParams;
[email protected]3a5180ae2011-12-21 02:39:38221using content::PluginService;
[email protected]e5d549d2011-12-28 01:29:20222using content::Referrer;
[email protected]b6583592012-01-25 19:52:33223using content::SiteInstance;
[email protected]d583e3f22011-12-27 21:38:17224using content::SSLStatus;
[email protected]7f6f44c2011-12-14 13:23:38225using content::UserMetricsAction;
[email protected]ea049a02011-12-25 21:37:09226using content::WebContents;
initial.commit09911bf2008-07-26 23:55:29227
[email protected]36b6dcb2008-11-12 01:19:57228///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29229
[email protected]505323e22009-01-24 02:47:58230namespace {
231
[email protected]91a79232010-11-10 18:15:08232// The URL to be loaded to display the "Report a broken page" form.
233const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20234 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08235 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
236
237// The URL for the privacy dashboard.
238const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
239
240// How long we wait before updating the browser chrome while loading a page.
241const int kUIUpdateCoalescingTimeMS = 200;
242
243const char kHashMark[] = "#";
244
[email protected]50dc3deb2011-07-07 01:07:19245// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
[email protected]10f417c52011-12-28 21:04:23246bool HasInternalURL(const NavigationEntry* entry) {
[email protected]50dc3deb2011-07-07 01:07:19247 if (!entry)
248 return false;
249
250 // Check the |virtual_url()| first. This catches regular chrome:// URLs
251 // including URLs that were rewritten (such as chrome://bookmarks).
[email protected]36fc0392011-12-25 03:59:51252 if (entry->GetVirtualURL().SchemeIs(chrome::kChromeUIScheme))
[email protected]50dc3deb2011-07-07 01:07:19253 return true;
254
255 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
256 // view-source: of a chrome:// URL.
[email protected]36fc0392011-12-25 03:59:51257 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme))
258 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme);
[email protected]50dc3deb2011-07-07 01:07:19259
260 return false;
261}
262
[email protected]b6cb7702011-11-15 05:33:11263// Get the launch URL for a given extension, with optional override/fallback.
264// |override_url|, if non-empty, will be preferred over the extension's
265// launch url.
266GURL UrlForExtension(const Extension* extension, const GURL& override_url) {
267 if (!extension)
268 return override_url;
269
270 GURL url;
271 if (!override_url.is_empty()) {
272 DCHECK(extension->web_extent().MatchesURL(override_url));
273 url = override_url;
274 } else {
275 url = extension->GetFullLaunchURL();
276 }
277
278 // For extensions lacking launch urls, determine a reasonable fallback.
279 if (!url.is_valid()) {
280 url = extension->options_url();
[email protected]55a66012012-03-31 00:56:02281 if (!url.is_valid())
282 url = GURL(chrome::kChromeUIExtensionsURL);
[email protected]b6cb7702011-11-15 05:33:11283 }
284
285 return url;
286}
287
[email protected]113baf92012-02-14 02:21:06288// Parse two comma-separated integers from str. Return true on success.
289bool ParseCommaSeparatedIntegers(const std::string& str,
290 int* ret_num1,
291 int* ret_num2) {
292 size_t num1_size = str.find_first_of(',');
293 if (num1_size == std::string::npos)
294 return false;
295
296 size_t num2_pos = num1_size + 1;
297 size_t num2_size = str.size() - num2_pos;
298 int num1, num2;
299 if (!base::StringToInt(str.substr(0, num1_size), &num1) ||
300 !base::StringToInt(str.substr(num2_pos, num2_size), &num2))
301 return false;
302
303 *ret_num1 = num1;
304 *ret_num2 = num2;
305 return true;
306}
307
[email protected]0da58292012-03-22 20:37:21308bool AllowPanels(const std::string& app_name) {
[email protected]cae97652012-04-20 03:12:12309 return PanelManager::ShouldUsePanels(
310 web_app::GetExtensionIdFromApplicationName(app_name));
[email protected]0da58292012-03-22 20:37:21311}
312
[email protected]92655362012-04-20 21:33:17313bool DisplayOldDownloadsUI() {
314 return !CommandLine::ForCurrentProcess()->HasSwitch(
315 switches::kDownloadsNewUI);
316}
317
[email protected]505323e22009-01-24 02:47:58318} // namespace
319
[email protected]b35b26b32011-05-05 20:35:14320////////////////////////////////////////////////////////////////////////////////
321// Browser, CreateParams:
322
[email protected]da22aa62012-04-04 18:54:35323Browser::CreateParams::CreateParams()
324 : type(TYPE_TABBED),
325 profile(NULL),
326 initial_show_state(ui::SHOW_STATE_DEFAULT),
327 is_session_restore(false) {
328}
329
[email protected]b35b26b32011-05-05 20:35:14330Browser::CreateParams::CreateParams(Type type, Profile* profile)
331 : type(type),
[email protected]a636d8e52012-02-28 15:40:41332 profile(profile),
[email protected]0da58292012-03-22 20:37:21333 app_type(APP_TYPE_HOST),
[email protected]a636d8e52012-02-28 15:40:41334 initial_show_state(ui::SHOW_STATE_DEFAULT),
335 is_session_restore(false) {
[email protected]b35b26b32011-05-05 20:35:14336}
337
[email protected]da22aa62012-04-04 18:54:35338// static
339Browser::CreateParams Browser::CreateParams::CreateForApp(
340 Type type,
341 const std::string& app_name,
342 const gfx::Rect& window_bounds,
343 Profile* profile) {
344 DCHECK(type != TYPE_TABBED);
345 DCHECK(!app_name.empty());
346
347 if (type == TYPE_PANEL && !AllowPanels(app_name))
348 type = TYPE_POPUP;
349
350 CreateParams params(type, profile);
351 params.app_name = app_name;
352 params.app_type = APP_TYPE_CHILD;
353 params.initial_bounds = window_bounds;
354
355 return params;
356}
357
358// static
359Browser::CreateParams Browser::CreateParams::CreateForDevTools(
360 Profile* profile) {
361 CreateParams params(TYPE_POPUP, profile);
362 params.app_name = DevToolsWindow::kDevToolsApp;
363 return params;
364}
365
[email protected]36b6dcb2008-11-12 01:19:57366///////////////////////////////////////////////////////////////////////////////
367// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29368
[email protected]299dabd2008-11-19 02:27:16369Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05370 : type_(type),
371 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39372 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40373 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]2fc15ae2012-05-06 00:01:37374 tab_strip_model_(new TabStripModel(this, profile))),
[email protected]1fc025202009-01-20 23:03:14375 command_updater_(this),
[email protected]0da58292012-03-22 20:37:21376 app_type_(APP_TYPE_HOST),
[email protected]15952e462008-11-14 00:29:05377 chrome_updater_factory_(this),
378 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06379 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]400eaf82011-08-22 15:47:39380 show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]8bc061f2011-08-31 22:46:23381 is_session_restore_(false),
[email protected]24f1477532011-11-22 22:55:36382 weak_factory_(this),
[email protected]867125a02009-12-10 06:01:48383 block_command_execution_(false),
384 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51385 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00386 pending_web_app_action_(NONE),
387 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]ef557022012-03-16 10:05:33388 content_setting_bubble_model_delegate_(
389 new BrowserContentSettingBubbleModelDelegate(this))),
390 ALLOW_THIS_IN_INITIALIZER_LIST(
391 toolbar_model_delegate_(
392 new BrowserToolbarModelDelegate(this))),
393 ALLOW_THIS_IN_INITIALIZER_LIST(
[email protected]fb7da4132011-03-15 15:51:00394 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48395 new BrowserTabRestoreServiceDelegate(this))),
[email protected]afefa74e2011-07-26 05:04:23396 ALLOW_THIS_IN_INITIALIZER_LIST(
397 synced_window_delegate_(
398 new BrowserSyncedWindowDelegate(this))),
[email protected]8a5e0ca2011-08-25 06:30:47399 bookmark_bar_state_(BookmarkBar::HIDDEN),
[email protected]2f516c792011-09-19 22:22:09400 window_has_shown_(false) {
[email protected]2fc15ae2012-05-06 00:01:37401 tab_strip_model_->AddObserver(this);
402
[email protected]ef557022012-03-16 10:05:33403 toolbar_model_.reset(new ToolbarModel(toolbar_model_delegate_.get()));
404
[email protected]432115822011-07-10 15:52:27405 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
[email protected]ad50def52011-10-19 23:17:07406 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27407 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]a93089b12011-11-22 20:47:38408 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27409 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]a93089b12011-11-22 20:47:38410 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27411 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
[email protected]a93089b12011-11-22 20:47:38412 content::Source<Profile>(profile_->GetOriginalProfile()));
[email protected]432115822011-07-10 15:52:27413 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
[email protected]ad50def52011-10-19 23:17:07414 content::NotificationService::AllSources());
[email protected]6b40bb582012-03-15 20:50:38415#if defined(ENABLE_THEMES)
[email protected]ffa6f592011-06-24 22:03:57416 registrar_.Add(
[email protected]432115822011-07-10 15:52:27417 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
[email protected]6c2381d2011-10-19 02:52:53418 content::Source<ThemeService>(
419 ThemeServiceFactory::GetForProfile(profile_)));
[email protected]6b40bb582012-03-15 20:50:38420#endif
[email protected]ea049a02011-12-25 21:37:09421 registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED,
[email protected]ad50def52011-10-19 23:17:07422 content::NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29423
[email protected]9e823662010-10-13 23:36:00424 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04425 if (local_state) {
426 local_pref_registrar_.Init(local_state);
427 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
428 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
[email protected]3819f2ee2011-08-21 09:44:38429 local_pref_registrar_.Add(prefs::kMetricsReportingEnabled, this);
[email protected]623294c42012-04-27 18:27:14430 local_pref_registrar_.Add(prefs::kInManagedMode, this);
[email protected]97b46382011-05-02 13:23:04431 }
432
433 profile_pref_registrar_.Init(profile_->GetPrefs());
434 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
435 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
[email protected]3710d0002011-10-11 00:35:00436 profile_pref_registrar_.Add(prefs::kShowBookmarkBar, this);
[email protected]6c6b02d2011-09-02 03:36:47437 profile_pref_registrar_.Add(prefs::kHomePage, this);
[email protected]97b46382011-05-02 13:23:04438 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]4e94ab32011-08-05 05:28:27439 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
[email protected]3819f2ee2011-08-21 09:44:38440 profile_pref_registrar_.Add(prefs::kSearchSuggestEnabled, this);
[email protected]9e823662010-10-13 23:36:00441
initial.commit09911bf2008-07-26 23:55:29442 InitCommandState();
443 BrowserList::AddBrowser(this);
444
[email protected]97b46382011-05-02 13:23:04445 // NOTE: These prefs all need to be explicitly destroyed in the destructor
446 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29447 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
448 profile_->GetPrefs(), NULL);
[email protected]281918912010-05-27 22:05:13449
[email protected]92371eb2011-04-28 11:50:15450 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13451 if (tab_restore_service_) {
452 tab_restore_service_->AddObserver(this);
453 TabRestoreServiceChanged(tab_restore_service_);
454 }
[email protected]d3b98c82010-07-14 07:45:59455
[email protected]5e61afb92012-01-27 20:09:13456 ProfileSyncService* service =
457 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
458 if (service)
459 service->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30460
[email protected]2031cf9d2010-10-12 05:05:37461 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26462
463 // Make sure TabFinder has been created. This does nothing if TabFinder is
464 // not enabled.
465 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48466
467 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
[email protected]a7be6982011-12-12 21:53:57468
469 FilePath profile_path = profile->GetPath();
470 ProfileMetrics::LogProfileLaunch(profile_path);
initial.commit09911bf2008-07-26 23:55:29471}
472
473Browser::~Browser() {
[email protected]5e61afb92012-01-27 20:09:13474 ProfileSyncService* service =
475 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile_);
476 if (service)
477 service->RemoveObserver(this);
[email protected]d3b98c82010-07-14 07:45:59478
[email protected]2fc15ae2012-05-06 00:01:37479 // The tab strip should not have any tabs at this point.
480 if (!browser_shutdown::ShuttingDownWithoutClosingBrowsers())
481 DCHECK(tab_strip_model_->empty());
482 tab_strip_model_->RemoveObserver(this);
483
initial.commit09911bf2008-07-26 23:55:29484 BrowserList::RemoveBrowser(this);
485
[email protected]bdc6ccd12012-03-20 22:06:13486 SessionService* session_service =
487 SessionServiceFactory::GetForProfile(profile_);
488 if (session_service)
489 session_service->WindowClosed(session_id_);
490
491 TabRestoreService* tab_restore_service =
492 TabRestoreServiceFactory::GetForProfile(profile());
493 if (tab_restore_service)
494 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
495
[email protected]7be64502011-05-03 17:51:47496#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29497 if (!BrowserList::HasBrowserWithProfile(profile_)) {
498 // We're the last browser window with this profile. We need to nuke the
499 // TabRestoreService, which will start the shutdown of the
500 // NavigationControllers and allow for proper shutdown. If we don't do this
501 // chrome won't shutdown cleanly, and may end up crashing when some
502 // thread tries to use the IO thread (or another thread) that is no longer
503 // valid.
[email protected]fbc947b2009-06-19 13:28:24504 // This isn't a valid assumption for Mac OS, as it stays running after
505 // the last browser has closed. The Mac equivalent is in its app
506 // controller.
[email protected]92371eb2011-04-28 11:50:15507 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29508 }
[email protected]fbc947b2009-06-19 13:28:24509#endif
initial.commit09911bf2008-07-26 23:55:29510
[email protected]97b46382011-05-02 13:23:04511 profile_pref_registrar_.RemoveAll();
512 local_pref_registrar_.RemoveAll();
513
[email protected]9a8c4022011-01-25 14:25:33514 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33515
initial.commit09911bf2008-07-26 23:55:29516 if (profile_->IsOffTheRecord() &&
[email protected]474e5db2011-08-12 13:02:23517 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
[email protected]5e919242012-02-13 23:59:35518 // An incognito profile is no longer needed, this indirectly frees
519 // its cache and cookies once it gets destroyed at the appropriate time.
[email protected]f7227502012-02-22 21:54:32520 ProfileDestroyer::DestroyOffTheRecordProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29521 }
522
523 // There may be pending file dialogs, we need to tell them that we've gone
524 // away so they don't try and call back to us.
525 if (select_file_dialog_.get())
526 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13527
528 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29529}
530
[email protected]15952e462008-11-14 00:29:05531// static
532Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14533 Browser* browser = new Browser(TYPE_TABBED, profile);
534 browser->InitBrowserWindow();
535 return browser;
536}
537
538// static
539Browser* Browser::CreateWithParams(const CreateParams& params) {
[email protected]a636d8e52012-02-28 15:40:41540 if (!params.app_name.empty())
541 RegisterAppPrefs(params.app_name, params.profile);
542
[email protected]b35b26b32011-05-05 20:35:14543 Browser* browser = new Browser(params.type, params.profile);
544 browser->app_name_ = params.app_name;
[email protected]0da58292012-03-22 20:37:21545 browser->app_type_ = params.app_type;
[email protected]81b2b0ac2011-11-23 01:54:48546 browser->set_override_bounds(params.initial_bounds);
[email protected]a636d8e52012-02-28 15:40:41547 browser->set_show_state(params.initial_show_state);
548 browser->set_is_session_restore(params.is_session_restore);
549
[email protected]9800de5e2011-03-11 18:19:49550 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05551 return browser;
552}
[email protected]6104acf2008-11-11 22:27:34553
[email protected]9800de5e2011-03-11 18:19:49554void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05555 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43556
[email protected]9800de5e2011-03-11 18:19:49557 window_ = CreateBrowserWindow();
[email protected]01a5a762011-11-21 05:40:55558 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
[email protected]15952e462008-11-14 00:29:05559
[email protected]5e37c452011-09-06 19:31:39560#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]6a34951a2012-01-17 18:10:40561 // Set the app user model id for this application to that of the application
562 // name. See http://crbug.com/7028.
563 ui::win::SetAppIdForWindow(
564 is_app() && !is_type_panel() ?
565 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
566 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
567 window()->GetNativeHandle());
[email protected]45446a52010-11-04 17:41:00568
[email protected]6a34951a2012-01-17 18:10:40569 if (is_type_panel()) {
570 ui::win::SetAppIconForWindow(ShellIntegration::GetChromiumIconPath(),
571 window()->GetNativeHandle());
[email protected]45446a52010-11-04 17:41:00572 }
[email protected]80cf3562009-11-17 08:17:24573#endif
574
[email protected]41d9faf2012-02-28 23:46:02575 // Create the extension window controller before sending notifications.
576 extension_window_controller_.reset(
577 new BrowserExtensionWindowController(this));
578
[email protected]ad50def52011-10-19 23:17:07579 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27580 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
[email protected]6c2381d2011-10-19 02:52:53581 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:07582 content::NotificationService::NoDetails());
[email protected]14d8c66e2009-09-22 00:32:52583
[email protected]15952e462008-11-14 00:29:05584 PrefService* local_state = g_browser_process->local_state();
[email protected]2f516c792011-09-19 22:22:09585 if (local_state && local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01586 prefs::kAutofillPersonalDataManagerFirstRun) &&
587 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46588 // Notify PDM that this is a first run.
589#if defined(OS_WIN)
[email protected]ea9edcb02011-09-23 22:05:04590 ImportAutofillDataWin(PersonalDataManagerFactory::GetForProfile(profile_));
[email protected]f69c8852010-10-12 02:36:46591#endif // defined(OS_WIN)
592 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01593 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46594 }
[email protected]6a1622a2011-09-20 22:37:45595
596 // Permanently dismiss ntp4 bubble for new users.
[email protected]dfa08b042011-12-28 23:07:21597 if (first_run::IsChromeFirstRun())
[email protected]27e96a972011-10-20 20:06:55598 NewTabPageHandler::DismissIntroMessage(local_state);
initial.commit09911bf2008-07-26 23:55:29599}
600
[email protected]bf8708692011-12-20 21:24:28601void Browser::SetWindowForTesting(BrowserWindow* window) {
602 DCHECK(!window_);
603 window_ = window;
604 fullscreen_controller_ = new FullscreenController(window_, profile_, this);
605}
606
[email protected]36b6dcb2008-11-12 01:19:57607///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07608// Getters & Setters
609
[email protected]b77cb302009-10-29 04:09:17610FindBarController* Browser::GetFindBarController() {
611 if (!find_bar_controller_.get()) {
[email protected]632983f2011-08-08 22:51:24612 FindBar* find_bar = window_->CreateFindBar();
[email protected]b77cb302009-10-29 04:09:17613 find_bar_controller_.reset(new FindBarController(find_bar));
614 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24615 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17616 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
617 }
618 return find_bar_controller_.get();
619}
620
[email protected]24db8a072009-10-29 20:35:37621bool Browser::HasFindBarController() const {
622 return find_bar_controller_.get() != NULL;
623}
624
[email protected]b35b26b32011-05-05 20:35:14625bool Browser::is_app() const {
626 return !app_name_.empty();
627}
628
629bool Browser::is_devtools() const {
630 return app_name_ == DevToolsWindow::kDevToolsApp;
631}
632
[email protected]5c238752009-06-13 10:29:07633///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57634// Browser, Creation Helpers:
635
636// static
[email protected]4aa3f7722012-03-23 19:09:16637void Browser::NewEmptyWindow(Profile* profile) {
[email protected]eddcf7502012-02-09 22:43:48638 bool incognito = profile->IsOffTheRecord();
639 PrefService* prefs = profile->GetPrefs();
640 if (incognito) {
641 if (IncognitoModePrefs::GetAvailability(prefs) ==
642 IncognitoModePrefs::DISABLED) {
643 incognito = false;
644 }
645 } else {
646 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
647 IncognitoModePrefs::ShouldLaunchIncognito(
648 *CommandLine::ForCurrentProcess(), prefs)) {
649 incognito = true;
650 }
651 }
652
653 if (incognito) {
654 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]4aa3f7722012-03-23 19:09:16655 OpenEmptyWindow(profile->GetOffTheRecordProfile());
[email protected]eddcf7502012-02-09 22:43:48656 } else {
657 content::RecordAction(UserMetricsAction("NewWindow"));
658 SessionService* session_service =
659 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
660 if (!session_service ||
661 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
[email protected]4aa3f7722012-03-23 19:09:16662 OpenEmptyWindow(profile->GetOriginalProfile());
[email protected]eddcf7502012-02-09 22:43:48663 }
664 }
665}
666
667// static
[email protected]2e0f8e92012-03-14 21:31:35668Browser* Browser::OpenEmptyWindow(Profile* profile) {
[email protected]15952e462008-11-14 00:29:05669 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57670 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05671 browser->window()->Show();
[email protected]2e0f8e92012-03-14 21:31:35672 return browser;
initial.commit09911bf2008-07-26 23:55:29673}
674
[email protected]36b6dcb2008-11-12 01:19:57675// static
[email protected]fbc947b2009-06-19 13:28:24676void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15677 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24678 if (service)
679 service->RestoreMostRecentEntry(NULL);
680}
681
682// static
[email protected]36b6dcb2008-11-12 01:19:57683void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55684 Browser* browser = GetOrCreateTabbedBrowser(
685 profile->GetOffTheRecordProfile());
[email protected]2905f742011-10-13 03:51:58686 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK);
[email protected]15952e462008-11-14 00:29:05687 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17688}
689
[email protected]36b6dcb2008-11-12 01:19:57690// static
[email protected]bb81f382012-01-03 22:45:44691WebContents* Browser::OpenApplication(
[email protected]d83a5602010-09-16 00:22:48692 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02693 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39694 extension_misc::LaunchContainer container,
[email protected]b6cb7702011-11-15 05:33:11695 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16696 WindowOpenDisposition disposition) {
[email protected]bb81f382012-01-03 22:45:44697 WebContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04698 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
699 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37700
[email protected]9b217652010-10-08 22:04:23701 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
702
[email protected]dc37b002012-04-23 23:02:26703 if (extension->is_platform_app()) {
704 extensions::AppEventRouter::DispatchOnLaunchedEvent(profile, extension);
705 return NULL;
706 }
707
[email protected]bbadaa782010-04-28 21:21:53708 switch (container) {
[email protected]dc37b002012-04-23 23:02:26709 case extension_misc::LAUNCH_NONE: {
710 NOTREACHED();
[email protected]a44657202012-01-09 05:48:31711 break;
712 }
[email protected]d83a5602010-09-16 00:22:48713 case extension_misc::LAUNCH_PANEL:
[email protected]dc04be7c2012-03-15 23:57:49714#if defined(USE_ASH)
[email protected]bafda132012-02-16 19:32:51715 if (extension &&
716 CommandLine::ForCurrentProcess()->HasSwitch(
717 ash::switches::kAuraPanelManager)) {
718 tab = OpenApplicationPanel(profile, extension, override_url);
719 break;
720 }
721 // else fall through to LAUNCH_WINDOW
722#endif
723 case extension_misc::LAUNCH_WINDOW:
[email protected]bbadaa782010-04-28 21:21:53724 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]b6cb7702011-11-15 05:33:11725 override_url, NULL);
[email protected]c28071ad2010-03-12 17:28:56726 break;
[email protected]d83a5602010-09-16 00:22:48727 case extension_misc::LAUNCH_TAB: {
[email protected]b6cb7702011-11-15 05:33:11728 tab = Browser::OpenApplicationTab(profile, extension, override_url,
729 disposition);
[email protected]c28071ad2010-03-12 17:28:56730 break;
731 }
732 default:
733 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53734 break;
[email protected]c28071ad2010-03-12 17:28:56735 }
[email protected]bbadaa782010-04-28 21:21:53736 return tab;
[email protected]c28071ad2010-03-12 17:28:56737}
738
[email protected]dc04be7c2012-03-15 23:57:49739#if defined(USE_ASH)
[email protected]bafda132012-02-16 19:32:51740// static
741WebContents* Browser::OpenApplicationPanel(
742 Profile* profile,
743 const Extension* extension,
744 const GURL& url_input) {
745 GURL url = UrlForExtension(extension, url_input);
746 std::string app_name =
747 web_app::GenerateApplicationNameFromExtensionId(extension->id());
748 gfx::Rect panel_bounds;
749 panel_bounds.set_width(extension->launch_width());
750 panel_bounds.set_height(extension->launch_height());
751 PanelViewAura* panel_view = new PanelViewAura(app_name);
752 panel_view->Init(profile, url, panel_bounds);
753 return panel_view->WebContents();
754}
755#endif
756
[email protected]c28071ad2010-03-12 17:28:56757// static
[email protected]bb81f382012-01-03 22:45:44758WebContents* Browser::OpenApplicationWindow(
[email protected]bbadaa782010-04-28 21:21:53759 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02760 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48761 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26762 const GURL& url_input,
763 Browser** app_browser) {
[email protected]b6cb7702011-11-15 05:33:11764 DCHECK(!url_input.is_empty() || extension);
765 GURL url = UrlForExtension(extension, url_input);
[email protected]f381dfa2010-04-29 04:41:37766
[email protected]2f1c09d2011-01-14 14:58:14767 std::string app_name;
[email protected]b6cb7702011-11-15 05:33:11768 app_name = extension ?
769 web_app::GenerateApplicationNameFromExtensionId(extension->id()) :
770 web_app::GenerateApplicationNameFromURL(url);
[email protected]2f1c09d2011-01-14 14:58:14771
[email protected]0da58292012-03-22 20:37:21772 Type type = TYPE_POPUP;
773 if (extension &&
774 container == extension_misc::LAUNCH_PANEL &&
775 AllowPanels(app_name)) {
776 type = TYPE_PANEL;
777 }
[email protected]94ce7252010-12-20 21:46:33778
[email protected]5c209242011-06-06 20:36:17779 gfx::Rect window_bounds;
780 if (extension) {
781 window_bounds.set_width(extension->launch_width());
782 window_bounds.set_height(extension->launch_height());
783 }
[email protected]94ce7252010-12-20 21:46:33784
[email protected]0da58292012-03-22 20:37:21785 CreateParams params(type, profile);
786 params.app_name = app_name;
787 params.initial_bounds = window_bounds;
[email protected]ac2c63e2012-04-24 01:50:46788
789#if defined(USE_ASH)
790 if (extension &&
791 container == extension_misc::LAUNCH_WINDOW) {
792 // In ash, LAUNCH_FULLSCREEN launches in a maximized app window and
793 // LAUNCH_WINDOW launches in a normal app window.
794 ExtensionPrefs::LaunchType launch_type =
795 profile->GetExtensionService()->extension_prefs()->GetLaunchType(
796 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
797 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN)
798 params.initial_show_state = ui::SHOW_STATE_MAXIMIZED;
799 else if (launch_type == ExtensionPrefs::LAUNCH_WINDOW)
800 params.initial_show_state = ui::SHOW_STATE_NORMAL;
801 }
802#endif
803
[email protected]0da58292012-03-22 20:37:21804 Browser* browser = Browser::CreateWithParams(params);
[email protected]011396a2011-04-13 23:35:28805
[email protected]0e71e4152010-12-07 04:16:26806 if (app_browser)
807 *app_browser = browser;
808
[email protected]3c9e1872010-11-18 16:17:49809 TabContentsWrapper* wrapper =
[email protected]2905f742011-10-13 03:51:58810 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_START_PAGE);
[email protected]bb81f382012-01-03 22:45:44811 WebContents* contents = wrapper->web_contents();
[email protected]cecc93a2010-10-05 15:58:55812 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:52813 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]3a8f9d52012-03-16 18:41:23814 // TODO(stevenjb): Find the right centralized place to do this. Currently it
815 // is only done for app tabs in normal browsers through SetExtensionAppById.
816 if (extension && type == TYPE_PANEL)
817 wrapper->extension_tab_helper()->SetExtensionAppIconById(extension->id());
[email protected]b1682ff2012-03-29 03:36:35818
[email protected]cecc93a2010-10-05 15:58:55819 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53820
[email protected]68f009f2009-02-26 19:43:35821 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
822 // focus explicitly.
[email protected]d487beefe2011-12-21 05:41:21823 contents->GetView()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26824 return contents;
825}
[email protected]eabfdae92009-12-11 06:13:51826
[email protected]bb81f382012-01-03 22:45:44827WebContents* Browser::OpenAppShortcutWindow(Profile* profile,
[email protected]0e71e4152010-12-07 04:16:26828 const GURL& url,
829 bool update_shortcut) {
830 Browser* app_browser;
[email protected]bb81f382012-01-03 22:45:44831 WebContents* tab = OpenApplicationWindow(
[email protected]0e71e4152010-12-07 04:16:26832 profile,
833 NULL, // this is a URL app. No extension.
834 extension_misc::LAUNCH_WINDOW,
835 url,
836 &app_browser);
837
838 if (!tab)
839 return NULL;
840
841 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35842 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
843 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
[email protected]075969d2012-04-17 20:05:55844 // the web app info is available, ExtensionTabHelper notifies Browser via
[email protected]867a73e12010-03-19 20:45:46845 // OnDidGetApplicationInfo, which calls
846 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
847 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26848 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35849 }
[email protected]0e71e4152010-12-07 04:16:26850 return tab;
[email protected]c28071ad2010-03-12 17:28:56851}
852
853// static
[email protected]bb81f382012-01-03 22:45:44854WebContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02855 const Extension* extension,
[email protected]b6cb7702011-11-15 05:33:11856 const GURL& override_url,
[email protected]7e41c2b2011-05-06 10:31:16857 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14858 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]bb81f382012-01-03 22:45:44859 WebContents* contents = NULL;
[email protected]78d78a62011-09-29 18:24:33860 if (!browser) {
861 // No browser for this profile, need to open a new one.
862 browser = Browser::Create(profile);
863 browser->window()->Show();
864 // There's no current tab in this browser window, so add a new one.
865 disposition = NEW_FOREGROUND_TAB;
[email protected]5f439e52012-03-28 04:02:07866 } else {
867 // For existing browser, ensure its window is activated.
868 browser->window()->Activate();
[email protected]78d78a62011-09-29 18:24:33869 }
[email protected]c28071ad2010-03-12 17:28:56870
[email protected]10abd192010-09-30 02:03:49871 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36872 ExtensionService* extension_service = profile->GetExtensionService();
873 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59874
[email protected]10abd192010-09-30 02:03:49875 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36876 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02877 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23878 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]333b1de2011-09-12 18:28:50879
[email protected]49098f702011-10-13 03:47:18880 static bool default_apps_trial_exists =
[email protected]568c3312011-12-06 15:36:04881 base::FieldTrialList::TrialExists(kDefaultAppsTrialName);
[email protected]49098f702011-10-13 03:47:18882 if (default_apps_trial_exists) {
883 UMA_HISTOGRAM_ENUMERATION(
884 base::FieldTrial::MakeName("Extensions.AppTabLaunchType",
[email protected]568c3312011-12-06 15:36:04885 kDefaultAppsTrialName),
[email protected]49098f702011-10-13 03:47:18886 launch_type, 100);
887 }
[email protected]333b1de2011-09-12 18:28:50888
[email protected]eaca0ad12011-04-18 15:53:41889 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49890 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
891 add_type |= TabStripModel::ADD_PINNED;
892
[email protected]b6cb7702011-11-15 05:33:11893 GURL extension_url = UrlForExtension(extension, override_url);
[email protected]10abd192010-09-30 02:03:49894 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
895 // cases.
[email protected]37fcf262011-01-26 19:39:15896 browser::NavigateParams params(browser, extension_url,
[email protected]2905f742011-10-13 03:51:58897 content::PAGE_TRANSITION_START_PAGE);
[email protected]616381f02010-11-02 15:15:33898 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16899 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39900
[email protected]7e41c2b2011-05-06 10:31:16901 if (disposition == CURRENT_TAB) {
[email protected]bb81f382012-01-03 22:45:44902 WebContents* existing_tab = browser->GetSelectedWebContents();
[email protected]24bf2022010-10-14 16:34:39903 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49904 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39905
[email protected]bce1f1c2011-12-05 15:11:58906 existing_tab->OpenURL(OpenURLParams(
907 extension_url,
908 content::Referrer(existing_tab->GetURL(),
909 WebKit::WebReferrerPolicyDefault),
910 disposition, content::PAGE_TRANSITION_LINK, false));
[email protected]a787b4352012-05-02 20:42:16911 // Reset existing_tab as OpenURL() may have clobbered it.
912 existing_tab = browser->GetSelectedWebContents();
[email protected]616381f02010-11-02 15:15:33913 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39914 model->SetTabPinned(tab_index, true);
[email protected]a787b4352012-05-02 20:42:16915 // Pinning may have moved the tab.
[email protected]3c9e1872010-11-18 16:17:49916 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26917 }
[email protected]eaca0ad12011-04-18 15:53:41918 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
919 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39920
921 contents = existing_tab;
922 } else {
[email protected]616381f02010-11-02 15:15:33923 browser::Navigate(&params);
[email protected]bb81f382012-01-03 22:45:44924 contents = params.target_contents->web_contents();
[email protected]24bf2022010-10-14 16:34:39925 }
926
[email protected]b1682ff2012-03-29 03:36:35927#if defined(USE_ASH)
928 // In ash, LAUNCH_FULLSCREEN launches in a maximized app window and it should
929 // not reach here.
930 DCHECK(launch_type != ExtensionPrefs::LAUNCH_FULLSCREEN);
931#else
[email protected]7bd42fc2011-02-09 17:32:42932 // TODO(skerner): If we are already in full screen mode, and the user
933 // set the app to open as a regular or pinned tab, what should happen?
934 // Today we open the tab, but stay in full screen mode. Should we leave
935 // full screen mode in this case?
936 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
[email protected]b6cb7702011-11-15 05:33:11937 !browser->window()->IsFullscreen()) {
[email protected]184717d52012-02-22 04:46:16938 browser->ToggleFullscreenMode();
[email protected]b6cb7702011-11-15 05:33:11939 }
[email protected]b1682ff2012-03-29 03:36:35940#endif
[email protected]10abd192010-09-30 02:03:49941
[email protected]cecc93a2010-10-05 15:58:55942 return contents;
[email protected]c28071ad2010-03-12 17:28:56943}
944
945// static
[email protected]90a8bf252010-03-12 00:09:47946void Browser::OpenBookmarkManagerWindow(Profile* profile) {
947 Browser* browser = Browser::Create(profile);
[email protected]0af8f132011-07-16 01:37:02948 browser->OpenBookmarkManager();
[email protected]90a8bf252010-03-12 00:09:47949 browser->window()->Show();
950}
951
[email protected]057d959a2010-03-12 02:56:20952#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47953// static
[email protected]a9fbb0962012-03-21 23:25:13954void Browser::OpenAboutWindow(Profile* profile) {
955 Browser* browser = Browser::Create(profile);
956 browser->OpenAboutChromeDialog();
957 browser->window()->Show();
958}
959
960// static
[email protected]91a5b3e2009-10-30 19:32:22961void Browser::OpenHistoryWindow(Profile* profile) {
962 Browser* browser = Browser::Create(profile);
963 browser->ShowHistoryTab();
964 browser->window()->Show();
965}
966
967// static
968void Browser::OpenDownloadsWindow(Profile* profile) {
969 Browser* browser = Browser::Create(profile);
970 browser->ShowDownloadsTab();
971 browser->window()->Show();
972}
973
974// static
[email protected]1fdff702009-10-22 00:36:18975void Browser::OpenHelpWindow(Profile* profile) {
976 Browser* browser = Browser::Create(profile);
[email protected]202802e42011-07-06 11:40:46977 browser->ShowHelpTab();
[email protected]1fdff702009-10-22 00:36:18978 browser->window()->Show();
979}
[email protected]4a42d272010-06-18 01:29:42980
[email protected]eca258132010-11-15 23:33:08981// static
[email protected]4a42d272010-06-18 01:29:42982void Browser::OpenOptionsWindow(Profile* profile) {
983 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49984 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42985 browser->window()->Show();
986}
[email protected]c8de64a2011-01-25 17:10:23987
988// static
[email protected]713d01b2012-03-24 05:58:20989void Browser::OpenSyncSetupWindow(Profile* profile,
990 SyncPromoUI::Source source) {
[email protected]65549182012-02-25 00:45:40991 Browser* browser = Browser::Create(profile);
[email protected]713d01b2012-03-24 05:58:20992 browser->ShowSyncSetup(source);
[email protected]65549182012-02-25 00:45:40993 browser->window()->Show();
994}
995
996// static
[email protected]ddddfda2011-07-14 23:19:39997void Browser::OpenClearBrowsingDataDialogWindow(Profile* profile) {
[email protected]c8de64a2011-01-25 17:10:23998 Browser* browser = Browser::Create(profile);
999 browser->OpenClearBrowsingDataDialog();
1000 browser->window()->Show();
1001}
1002
1003// static
1004void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
1005 Browser* browser = Browser::Create(profile);
1006 browser->OpenImportSettingsDialog();
1007 browser->window()->Show();
1008}
[email protected]b99081b2011-03-10 17:43:471009
1010// static
1011void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
1012 Browser* browser = Browser::Create(profile);
1013 browser->OpenInstantConfirmDialog();
1014 browser->window()->Show();
1015}
[email protected]1fdff702009-10-22 00:36:181016#endif
1017
[email protected]ccb55cf52010-03-06 22:02:041018// static
1019void Browser::OpenExtensionsWindow(Profile* profile) {
1020 Browser* browser = Browser::Create(profile);
1021 browser->ShowExtensionsTab();
1022 browser->window()->Show();
1023}
1024
[email protected]36b6dcb2008-11-12 01:19:571025///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571026// Browser, State Storage and Retrieval for UI:
1027
[email protected]57ecc4b2010-08-11 03:02:511028std::string Browser::GetWindowPlacementKey() const {
1029 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:571030 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:511031 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:571032 name.append(app_name_);
1033 }
[email protected]bc9a5152008-11-15 00:32:041034 return name;
1035}
[email protected]36b6dcb2008-11-12 01:19:571036
[email protected]bc9a5152008-11-15 00:32:041037bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:141038 switch (type_) {
1039 case TYPE_TABBED:
1040 return true;
1041 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:511042 // Only save the window placement of popups if they are restored,
1043 // or the window belongs to DevTools.
[email protected]a636d8e52012-02-28 15:40:411044#if defined USE_AURA
1045 if (is_app())
1046 return true;
1047#endif
[email protected]bd6cdf22011-06-21 08:11:511048 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:141049 case TYPE_PANEL:
1050 // Do not save the window placement of panels.
1051 return false;
1052 default:
1053 return false;
1054 }
[email protected]bc9a5152008-11-15 00:32:041055}
[email protected]36b6dcb2008-11-12 01:19:571056
[email protected]400eaf82011-08-22 15:47:391057void Browser::SaveWindowPlacement(const gfx::Rect& bounds,
1058 ui::WindowShowState show_state) {
[email protected]bc9a5152008-11-15 00:32:041059 // Save to the session storage service, used when reloading a past session.
1060 // Note that we don't want to be the ones who cause lazy initialization of
1061 // the session service. This function gets called during initial window
1062 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:151063 SessionService* session_service =
1064 SessionServiceFactory::GetForProfileIfExisting(profile());
1065 if (session_service)
[email protected]400eaf82011-08-22 15:47:391066 session_service->SetWindowBounds(session_id_, bounds, show_state);
[email protected]36b6dcb2008-11-12 01:19:571067}
1068
[email protected]15952e462008-11-14 00:29:051069gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]113baf92012-02-14 02:21:061070 gfx::Rect restored_bounds = override_bounds_;
1071 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
1072 &restored_bounds);
1073
[email protected]bb975362009-01-21 01:00:221074 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:051075 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
1076 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
1077 if (record_mode || playback_mode) {
1078 // In playback/record mode we always fix the size of the browser and
1079 // move it to (0,0). The reason for this is two reasons: First we want
1080 // resize/moves in the playback to still work, and Second we want
1081 // playbacks to work (as much as possible) on machines w/ different
1082 // screen sizes.
[email protected]113baf92012-02-14 02:21:061083 restored_bounds = gfx::Rect(0, 0, 800, 600);
[email protected]15952e462008-11-14 00:29:051084 }
1085
[email protected]113baf92012-02-14 02:21:061086 // The following options override playback/record.
1087 if (parsed_command_line.HasSwitch(switches::kWindowSize)) {
1088 std::string str =
1089 parsed_command_line.GetSwitchValueASCII(switches::kWindowSize);
1090 int width, height;
1091 if (ParseCommaSeparatedIntegers(str, &width, &height))
1092 restored_bounds.set_size(gfx::Size(width, height));
1093 }
1094 if (parsed_command_line.HasSwitch(switches::kWindowPosition)) {
1095 std::string str =
1096 parsed_command_line.GetSwitchValueASCII(switches::kWindowPosition);
1097 int x, y;
1098 if (ParseCommaSeparatedIntegers(str, &x, &y))
1099 restored_bounds.set_origin(gfx::Point(x, y));
1100 }
1101
[email protected]15952e462008-11-14 00:29:051102 return restored_bounds;
1103}
1104
[email protected]400eaf82011-08-22 15:47:391105ui::WindowShowState Browser::GetSavedWindowShowState() const {
[email protected]76d8a4f2012-02-27 19:25:101106 // Only tabbed browsers use the command line or preference state, with the
1107 // exception of devtools.
[email protected]f523da82012-03-30 11:54:341108 bool show_state = !is_type_tabbed() && !is_devtools();
[email protected]a636d8e52012-02-28 15:40:411109
1110#if defined(USE_AURA)
1111 // Apps save state on aura.
1112 show_state &= !is_app();
1113#endif
1114
1115 if (show_state)
[email protected]3c627ff2012-01-27 17:04:071116 return show_state_;
[email protected]dfca0c32012-01-18 22:32:251117
[email protected]bb975362009-01-21 01:00:221118 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]400eaf82011-08-22 15:47:391119 return ui::SHOW_STATE_MAXIMIZED;
[email protected]15952e462008-11-14 00:29:051120
[email protected]400eaf82011-08-22 15:47:391121 if (show_state_ != ui::SHOW_STATE_DEFAULT)
1122 return show_state_;
[email protected]2e716622009-03-09 21:11:011123
[email protected]96f20102011-11-16 17:20:321124 const DictionaryValue* window_pref =
1125 profile()->GetPrefs()->GetDictionary(GetWindowPlacementKey().c_str());
[email protected]2e716622009-03-09 21:11:011126 bool maximized = false;
[email protected]96f20102011-11-16 17:20:321127 window_pref->GetBoolean("maximized", &maximized);
1128
[email protected]3c627ff2012-01-27 17:04:071129 return maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_DEFAULT;
[email protected]36b6dcb2008-11-12 01:19:571130}
1131
1132SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:041133 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:231134 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
1135 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:041136 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:571137}
1138
[email protected]731f8a42009-07-20 22:07:321139string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]4ca15302012-01-03 05:53:201140 WebContents* contents = GetSelectedWebContents();
[email protected]dda5dfa32009-07-10 00:33:291141 string16 title;
[email protected]c7c42332008-11-15 01:10:541142
[email protected]731f8a42009-07-20 22:07:321143 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
1144 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:571145 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:291146 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:571147 FormatTitleForDisplay(&title);
1148 }
1149 if (title.empty())
[email protected]51d83bdf2011-12-09 16:09:291150 title = CoreTabHelper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:571151
[email protected]cae97652012-04-20 03:12:121152#if defined(OS_MACOSX) || defined(USE_ASH)
1153 // On Mac or Ash, we don't want to suffix the page title with
[email protected]22a3daa2009-11-09 22:03:331154 // the application name.
[email protected]d904bc82009-07-07 00:41:041155 return title;
[email protected]7be64502011-05-03 17:51:471156#else
[email protected]edb5e6a2009-04-08 23:46:171157 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:551158 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:141159 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:171160 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:291161 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:501162#endif
[email protected]36b6dcb2008-11-12 01:19:571163}
1164
1165// static
[email protected]dda5dfa32009-07-10 00:33:291166void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:571167 size_t current_index = 0;
1168 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:511169 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:151170 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:571171 current_index = match_index;
1172 }
1173}
1174
1175///////////////////////////////////////////////////////////////////////////////
1176// Browser, OnBeforeUnload handling:
1177
1178bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:061179 if (!CanCloseWithInProgressDownloads())
1180 return false;
1181
1182 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:041183 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:061184
[email protected]36b6dcb2008-11-12 01:19:571185 is_attempting_to_close_browser_ = true;
1186
[email protected]460a2942010-12-15 19:43:151187 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:041188 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:571189
1190 ProcessPendingTabs();
1191 return false;
1192}
1193
1194void Browser::OnWindowClosing() {
1195 if (!ShouldCloseWindow())
1196 return;
1197
[email protected]911f8152010-03-18 16:46:401198 bool exiting = false;
1199
[email protected]c984d9f2010-07-20 20:52:201200 // Application should shutdown on last window close if the user is explicitly
1201 // trying to quit, or if there is nothing keeping the browser alive (such as
1202 // AppController on the Mac, or BackgroundContentsService for background
1203 // pages).
1204 bool should_quit_if_last_browser =
1205 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:501206
1207 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:571208 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:401209 exiting = true;
1210 }
[email protected]36b6dcb2008-11-12 01:19:571211
[email protected]92371eb2011-04-28 11:50:151212 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:571213 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:151214 SessionService* session_service =
1215 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:571216 if (session_service)
1217 session_service->WindowClosing(session_id());
1218
[email protected]92371eb2011-04-28 11:50:151219 TabRestoreService* tab_restore_service =
1220 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]a636d8e52012-02-28 15:40:411221
1222#if defined(USE_AURA)
1223 if (tab_restore_service && is_app())
1224 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
1225#endif
1226
[email protected]b35b26b32011-05-05 20:35:141227 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:001228 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:391229
[email protected]911f8152010-03-18 16:46:401230 // TODO(sky): convert session/tab restore to use notification.
[email protected]ad50def52011-10-19 23:17:071231 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:271232 chrome::NOTIFICATION_BROWSER_CLOSING,
[email protected]6c2381d2011-10-19 02:52:531233 content::Source<Browser>(this),
1234 content::Details<bool>(&exiting));
[email protected]911f8152010-03-18 16:46:401235
[email protected]36b6dcb2008-11-12 01:19:571236 CloseAllTabs();
1237}
1238
[email protected]28788c7d2011-05-20 23:03:451239void Browser::OnWindowActivated() {
1240 // On some platforms we want to automatically reload tabs that are
1241 // killed when the user selects them.
[email protected]4ca15302012-01-03 05:53:201242 WebContents* contents = GetSelectedWebContents();
[email protected]be1f56ab2011-12-22 06:55:311243 if (contents && contents->GetCrashedStatus() ==
[email protected]28788c7d2011-05-20 23:03:451244 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
1245 if (CommandLine::ForCurrentProcess()->HasSwitch(
1246 switches::kReloadKilledTabs)) {
1247 Reload(CURRENT_TAB);
1248 }
1249 }
1250}
1251
[email protected]69444cc2009-04-09 20:40:061252////////////////////////////////////////////////////////////////////////////////
1253// In-progress download termination handling:
1254
1255void Browser::InProgressDownloadResponse(bool cancel_downloads) {
1256 if (cancel_downloads) {
1257 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1258 CloseWindow();
1259 return;
1260 }
1261
1262 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1263 // close again we'll show the warning again.
1264 cancel_download_confirmation_state_ = NOT_PROMPTED;
1265
1266 // Show the download page so the user can figure-out what downloads are still
1267 // in-progress.
1268 ShowDownloadsTab();
1269}
1270
[email protected]5a17d492011-10-24 19:37:031271Browser::DownloadClosePreventionType Browser::OkToCloseWithInProgressDownloads(
1272 int* num_downloads_blocking) const {
1273 DCHECK(num_downloads_blocking);
1274 *num_downloads_blocking = 0;
1275
1276 if (is_attempting_to_close_browser_)
1277 return DOWNLOAD_CLOSE_OK;
1278
1279 // If we're not running a full browser process with a profile manager
1280 // (testing), it's ok to close the browser.
1281 if (!g_browser_process->profile_manager())
1282 return DOWNLOAD_CLOSE_OK;
1283
1284 int total_download_count = DownloadService::DownloadCountAllProfiles();
1285 if (total_download_count == 0)
1286 return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close.
1287
1288 // Figure out how many windows are open total, and associated with this
1289 // profile, that are relevant for the ok-to-close decision.
1290 int profile_window_count = 0;
1291 int total_window_count = 0;
1292 for (BrowserList::const_iterator iter = BrowserList::begin();
1293 iter != BrowserList::end(); ++iter) {
1294 // Don't count this browser window or any other in the process of closing.
1295 Browser* const browser = *iter;
1296 // Check is_attempting_to_close_browser_ as window closing may be
1297 // delayed, and windows that are in the process of closing don't
1298 // count against our totals.
1299 if (browser == this || browser->is_attempting_to_close_browser_)
1300 continue;
1301
1302 if ((*iter)->profile() == profile())
1303 profile_window_count++;
1304 total_window_count++;
1305 }
1306
1307 // If there aren't any other windows, we're at browser shutdown,
1308 // which would cancel all current downloads.
1309 if (total_window_count == 0) {
1310 *num_downloads_blocking = total_download_count;
1311 return DOWNLOAD_CLOSE_BROWSER_SHUTDOWN;
1312 }
1313
1314 // If there aren't any other windows on our profile, and we're an incognito
1315 // profile, and there are downloads associated with that profile,
1316 // those downloads would be cancelled by our window (-> profile) close.
1317 DownloadService* download_service =
1318 DownloadServiceFactory::GetForProfile(profile());
1319 if (profile_window_count == 0 && download_service->DownloadCount() > 0 &&
1320 profile()->IsOffTheRecord()) {
1321 *num_downloads_blocking = download_service->DownloadCount();
1322 return DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE;
1323 }
1324
1325 // Those are the only conditions under which we will block shutdown.
1326 return DOWNLOAD_CLOSE_OK;
1327}
1328
[email protected]69444cc2009-04-09 20:40:061329////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451330// Browser, TabStripModel pass-thrus:
1331
1332int Browser::tab_count() const {
[email protected]2fc15ae2012-05-06 00:01:371333 return tab_strip_model_->count();
[email protected]c848d3d92010-09-16 21:57:451334}
1335
[email protected]1ea49d52011-04-12 17:44:441336int Browser::active_index() const {
[email protected]2fc15ae2012-05-06 00:01:371337 return tab_strip_model_->active_index();
[email protected]c848d3d92010-09-16 21:57:451338}
1339
1340int Browser::GetIndexOfController(
[email protected]c5eed492012-01-04 17:07:501341 const NavigationController* controller) const {
[email protected]2fc15ae2012-05-06 00:01:371342 return tab_strip_model_->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451343}
1344
[email protected]3c9e1872010-11-18 16:17:491345TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
[email protected]2fc15ae2012-05-06 00:01:371346 return tab_strip_model_->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491347}
[email protected]b375c5d2011-05-03 21:15:041348
[email protected]4ca15302012-01-03 05:53:201349WebContents* Browser::GetSelectedWebContents() const {
1350 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1351 return wrapper ? wrapper->web_contents() : NULL;
1352}
1353
[email protected]3c9e1872010-11-18 16:17:491354TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371355 return tab_strip_model_->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451356}
1357
[email protected]6acde6352012-01-04 16:52:201358WebContents* Browser::GetWebContentsAt(int index) const {
[email protected]41f022e2012-01-31 05:56:401359 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(index);
[email protected]3c9e1872010-11-18 16:17:491360 if (wrapper)
[email protected]6acde6352012-01-04 16:52:201361 return wrapper->web_contents();
[email protected]3c9e1872010-11-18 16:17:491362 return NULL;
[email protected]c848d3d92010-09-16 21:57:451363}
1364
[email protected]eaca0ad12011-04-18 15:53:411365void Browser::ActivateTabAt(int index, bool user_gesture) {
[email protected]2fc15ae2012-05-06 00:01:371366 tab_strip_model_->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451367}
1368
[email protected]fb7da4132011-03-15 15:51:001369bool Browser::IsTabPinned(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371370 return tab_strip_model_->IsTabPinned(index);
[email protected]fb7da4132011-03-15 15:51:001371}
1372
[email protected]002efb042011-10-07 17:30:241373bool Browser::IsTabDiscarded(int index) const {
[email protected]2fc15ae2012-05-06 00:01:371374 return tab_strip_model_->IsTabDiscarded(index);
[email protected]002efb042011-10-07 17:30:241375}
1376
[email protected]c848d3d92010-09-16 21:57:451377void Browser::CloseAllTabs() {
[email protected]2fc15ae2012-05-06 00:01:371378 tab_strip_model_->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451379}
1380
1381////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571382// Browser, Tab adding/showing functions:
1383
[email protected]95bf8a5b2010-12-22 16:04:071384bool Browser::IsTabStripEditable() const {
1385 return window()->IsTabStripEditable();
1386}
1387
[email protected]b3344872010-05-03 15:52:291388int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]2fc15ae2012-05-06 00:01:371389 return (tab_strip_model_->insertion_policy() == TabStripModel::INSERT_AFTER) ?
1390 tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291391}
1392
[email protected]dad09ce42011-08-25 23:11:301393TabContentsWrapper* Browser::AddSelectedTabWithURL(
1394 const GURL& url,
[email protected]2905f742011-10-13 03:51:581395 content::PageTransition transition) {
[email protected]616381f02010-11-02 15:15:331396 browser::NavigateParams params(this, url, transition);
1397 params.disposition = NEW_FOREGROUND_TAB;
1398 browser::Navigate(&params);
1399 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571400}
1401
[email protected]d9083482012-01-06 00:38:461402WebContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]2905f742011-10-13 03:51:581403 content::PageTransition type) {
[email protected]2fc15ae2012-05-06 00:01:371404 tab_strip_model_->AddTabContents(tab_contents, -1, type,
1405 TabStripModel::ADD_ACTIVE);
[email protected]d9083482012-01-06 00:38:461406 return tab_contents->web_contents();
[email protected]36b6dcb2008-11-12 01:19:571407}
1408
[email protected]6acde6352012-01-04 16:52:201409WebContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571410 const std::vector<TabNavigation>& navigations,
1411 int tab_index,
1412 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081413 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091414 bool select,
[email protected]5e369672009-11-03 23:48:301415 bool pin,
[email protected]6ee12c42010-09-14 09:36:071416 bool from_last_session,
[email protected]adbfb8df2012-02-24 01:19:431417 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041418 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1419 TabContentsWrapper* wrapper = TabContentsFactory(
1420 profile(),
[email protected]3123d2092012-04-27 19:35:481421 tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
[email protected]3c9e1872010-11-18 16:17:491422 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:441423 GetSelectedWebContents(),
[email protected]ecc523f62010-09-28 22:45:401424 session_storage_namespace);
[email protected]6acde6352012-01-04 16:52:201425 WebContents* new_tab = wrapper->web_contents();
[email protected]36fb2c7c2011-04-04 15:49:081426 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]10f417c52011-12-28 21:04:231427 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141428 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1429 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561430 new_tab->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141431 selected_navigation, from_last_session, &entries);
1432 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571433
[email protected]eaca0ad12011-04-18 15:53:411434 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211435 TabStripModel::ADD_NONE;
1436 if (pin) {
[email protected]2fc15ae2012-05-06 00:01:371437 int first_mini_tab_idx = tab_strip_model_->IndexOfFirstNonMiniTab();
[email protected]41f022e2012-01-31 05:56:401438 tab_index = std::min(tab_index, first_mini_tab_idx);
[email protected]981b992e2011-03-28 21:05:211439 add_types |= TabStripModel::ADD_PINNED;
1440 }
[email protected]2fc15ae2012-05-06 00:01:371441 tab_strip_model_->InsertTabContentsAt(tab_index, wrapper, add_types);
[email protected]c93a9dd2010-04-22 20:25:181442 if (select) {
[email protected]77bc6732009-04-20 22:01:031443 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181444 } else {
1445 // We set the size of the view here, before WebKit does its initial
1446 // layout. If we don't, the initial layout of background tabs will be
1447 // performed with a view width of 0, which may cause script outputs and
1448 // anchor link location calculations to be incorrect even after a new
1449 // layout with proper view dimensions. TabStripModel::AddTabContents()
1450 // contains similar logic.
[email protected]d487beefe2011-12-21 05:41:211451 new_tab->GetView()->SizeContents(window_->GetRestoredBounds().size());
[email protected]c93a9dd2010-04-22 20:25:181452 new_tab->HideContents();
1453 }
[email protected]92371eb2011-04-28 11:50:151454 SessionService* session_service =
1455 SessionServiceFactory::GetForProfileIfExisting(profile_);
1456 if (session_service)
[email protected]81898992011-06-14 22:15:001457 session_service->TabRestored(wrapper, pin);
[email protected]ce3fa3c2009-04-20 19:55:571458 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571459}
1460
[email protected]92655362012-04-20 21:33:171461void Browser::AddWebContents(WebContents* new_contents,
1462 WindowOpenDisposition disposition,
1463 const gfx::Rect& initial_pos,
1464 bool user_gesture) {
1465 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1466}
1467
1468void Browser::CloseTabContents(WebContents* contents) {
1469 CloseContents(contents);
1470}
1471
[email protected]5835871a2012-04-25 21:56:551472gfx::NativeWindow Browser::BrowserShowWebDialog(
1473 WebDialogDelegate* delegate,
[email protected]60fd60e2012-04-26 17:58:331474 gfx::NativeWindow parent_window) {
[email protected]92655362012-04-20 21:33:171475 if (!parent_window)
1476 parent_window = window_->GetNativeHandle();
1477
[email protected]60fd60e2012-04-26 17:58:331478 return browser::ShowWebDialog(parent_window, profile_, this, delegate);
[email protected]92655362012-04-20 21:33:171479}
1480
1481void Browser::BrowserRenderWidgetShowing() {
1482 RenderWidgetShowing();
1483}
1484
1485void Browser::BookmarkBarSizeChanged(bool is_animating) {
1486 window_->ToolbarSizeChanged(is_animating);
1487}
1488
[email protected]36b6dcb2008-11-12 01:19:571489void Browser::ReplaceRestoredTab(
1490 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301491 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101492 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071493 const std::string& extension_app_id,
[email protected]adbfb8df2012-02-24 01:19:431494 content::SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041495 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1496 TabContentsWrapper* wrapper = TabContentsFactory(
1497 profile(),
[email protected]3123d2092012-04-27 19:35:481498 tab_util::GetSiteInstanceForNewTab(profile_, restore_url),
[email protected]ecc523f62010-09-28 22:45:401499 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:441500 GetSelectedWebContents(),
[email protected]6ee12c42010-09-14 09:36:071501 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081502 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]d9083482012-01-06 00:38:461503 WebContents* replacement = wrapper->web_contents();
[email protected]10f417c52011-12-28 21:04:231504 std::vector<NavigationEntry*> entries;
[email protected]03838e22011-06-06 15:27:141505 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1506 profile_, navigations, &entries);
[email protected]f5fa20e2011-12-21 22:35:561507 replacement->GetController().Restore(
[email protected]03838e22011-06-06 15:27:141508 selected_navigation, from_last_session, &entries);
1509 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571510
[email protected]2fc15ae2012-05-06 00:01:371511 tab_strip_model_->ReplaceNavigationControllerAt(active_index(), wrapper);
[email protected]36b6dcb2008-11-12 01:19:571512}
1513
[email protected]3698f172010-03-17 20:50:291514bool Browser::NavigateToIndexWithDisposition(int index,
1515 WindowOpenDisposition disp) {
[email protected]c5eed492012-01-04 17:07:501516 NavigationController& controller =
[email protected]f5fa20e2011-12-21 22:35:561517 GetOrCloneTabForDisposition(disp)->GetController();
[email protected]a26023822011-12-29 00:23:551518 if (index < 0 || index >= controller.GetEntryCount())
[email protected]3698f172010-03-17 20:50:291519 return false;
[email protected]cb84d642010-06-10 00:56:281520 controller.GoToIndex(index);
1521 return true;
[email protected]3698f172010-03-17 20:50:291522}
1523
[email protected]fee320542011-03-02 01:30:491524void Browser::ShowSingletonTab(const GURL& url) {
1525 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331526 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571527}
[email protected]d938aed92009-01-22 19:49:331528
[email protected]578c6962011-08-24 22:06:401529void Browser::ShowSingletonTabRespectRef(const GURL& url) {
1530 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1531 params.ref_behavior = browser::NavigateParams::RESPECT_REF;
1532 browser::Navigate(&params);
1533}
1534
[email protected]ddddfda2011-07-14 23:19:391535void Browser::ShowSingletonTabOverwritingNTP(
1536 const browser::NavigateParams& params) {
1537 browser::NavigateParams local_params(params);
[email protected]4ca15302012-01-03 05:53:201538 WebContents* contents = GetSelectedWebContents();
[email protected]842a648c2011-07-20 23:23:161539 if (contents) {
1540 const GURL& contents_url = contents->GetURL();
1541 if ((contents_url == GURL(chrome::kChromeUINewTabURL) ||
1542 contents_url == GURL(chrome::kAboutBlankURL)) &&
1543 browser::GetIndexOfSingletonTab(&local_params) < 0) {
1544 local_params.disposition = CURRENT_TAB;
1545 }
[email protected]ddddfda2011-07-14 23:19:391546 }
1547
1548 browser::Navigate(&local_params);
1549}
1550
[email protected]92655362012-04-20 21:33:171551browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1552 const GURL& url) {
1553 browser::NavigateParams params(
1554 this, url, content::PAGE_TRANSITION_AUTO_BOOKMARK);
1555 params.disposition = SINGLETON_TAB;
1556 params.window_action = browser::NavigateParams::SHOW_WINDOW;
1557 params.user_gesture = true;
1558 return params;
1559}
1560
[email protected]227393e2011-06-29 21:28:391561void Browser::WindowFullscreenStateChanged() {
[email protected]01a5a762011-11-21 05:40:551562 fullscreen_controller_->WindowFullscreenStateChanged();
[email protected]9adb8b12011-12-09 06:49:131563 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1564 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
[email protected]ae2622c2009-07-30 23:47:581565}
1566
[email protected]36b6dcb2008-11-12 01:19:571567///////////////////////////////////////////////////////////////////////////////
1568// Browser, Assorted browser commands:
1569
[email protected]43c9dc722011-08-20 02:05:091570bool Browser::CanGoBack() const {
[email protected]3c790d22012-01-30 19:06:351571 return GetSelectedWebContents()->GetController().CanGoBack();
[email protected]43c9dc722011-08-20 02:05:091572}
1573
[email protected]485fba42009-03-24 23:27:291574void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381575 content::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271576
[email protected]3c9e1872010-11-18 16:17:491577 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]43c9dc722011-08-20 02:05:091578 if (CanGoBack()) {
[email protected]d9083482012-01-06 00:38:461579 WebContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061580 // If we are on an interstitial page and clone the tab, it won't be copied
1581 // to the new tab, so we don't need to go back.
[email protected]d9083482012-01-06 00:38:461582 if (current_tab->web_contents()->ShowingInterstitialPage() &&
1583 (new_tab != current_tab->web_contents()))
[email protected]d497b0782010-03-29 19:19:061584 return;
[email protected]f5fa20e2011-12-21 22:35:561585 new_tab->GetController().GoBack();
[email protected]485fba42009-03-24 23:27:291586 }
[email protected]36b6dcb2008-11-12 01:19:571587}
1588
[email protected]43c9dc722011-08-20 02:05:091589bool Browser::CanGoForward() const {
[email protected]3c790d22012-01-30 19:06:351590 return GetSelectedWebContents()->GetController().CanGoForward();
[email protected]43c9dc722011-08-20 02:05:091591}
1592
[email protected]3698f172010-03-17 20:50:291593void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381594 content::RecordAction(UserMetricsAction("Forward"));
[email protected]43c9dc722011-08-20 02:05:091595 if (CanGoForward())
[email protected]f5fa20e2011-12-21 22:35:561596 GetOrCloneTabForDisposition(disposition)->GetController().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571597}
1598
[email protected]cb84d642010-06-10 00:56:281599void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381600 content::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281601 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161602}
[email protected]fbd77592008-11-12 20:50:271603
[email protected]cb84d642010-06-10 00:56:281604void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381605 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281606 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161607}
1608
[email protected]485fba42009-03-24 23:27:291609void Browser::Home(WindowOpenDisposition disposition) {
[email protected]7f6f44c2011-12-14 13:23:381610 content::RecordAction(UserMetricsAction("Home"));
[email protected]e5d549d2011-12-28 01:29:201611 OpenURL(OpenURLParams(
1612 profile_->GetHomePage(), Referrer(), disposition,
[email protected]2905f742011-10-13 03:51:581613 content::PageTransitionFromInt(
1614 content::PAGE_TRANSITION_AUTO_BOOKMARK |
[email protected]e5d549d2011-12-28 01:29:201615 content::PAGE_TRANSITION_HOME_PAGE),
1616 false));
[email protected]36b6dcb2008-11-12 01:19:571617}
1618
[email protected]fbd77592008-11-12 20:50:271619void Browser::OpenCurrentURL() {
[email protected]7f6f44c2011-12-14 13:23:381620 content::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351621 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491622 if (!location_bar)
1623 return;
1624
[email protected]9d0306ea2009-09-02 19:38:391625 WindowOpenDisposition open_disposition =
1626 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271627 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301628 return;
[email protected]03bb953d2010-09-14 21:38:301629
[email protected]537de682011-08-08 18:10:141630 GURL url(location_bar->GetInputString());
[email protected]07d490bc2011-03-07 17:05:261631
1632 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1633 Browser* existing_browser = NULL;
[email protected]4ca15302012-01-03 05:53:201634 WebContents* existing_tab = TabFinder::GetInstance()->FindTab(
[email protected]07d490bc2011-03-07 17:05:261635 this, url, &existing_browser);
1636 if (existing_tab) {
1637 existing_browser->ActivateContents(existing_tab);
1638 return;
1639 }
1640 }
1641
[email protected]616381f02010-11-02 15:15:331642 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1643 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251644 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1645 // inherit the opener. In some cases the tabstrip will determine the group
1646 // should be inherited, in which case the group is inherited instead of the
1647 // opener.
[email protected]616381f02010-11-02 15:15:331648 params.tabstrip_add_types =
1649 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1650 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331651
[email protected]6e37fe32011-03-02 09:06:521652 DCHECK(profile_->GetExtensionService());
1653 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]a9acdff2012-03-08 04:04:521654 AppLauncherHandler::RecordAppLaunchType(
1655 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION);
[email protected]46fd1ea42011-02-16 15:59:331656 }
[email protected]fbd77592008-11-12 20:50:271657}
1658
[email protected]84214982008-12-10 18:49:101659void Browser::Stop() {
[email protected]7f6f44c2011-12-14 13:23:381660 content::RecordAction(UserMetricsAction("Stop"));
[email protected]41f022e2012-01-31 05:56:401661 GetSelectedWebContents()->Stop();
[email protected]84214982008-12-10 18:49:101662}
1663
1664void Browser::NewWindow() {
[email protected]eddcf7502012-02-09 22:43:481665 NewEmptyWindow(profile_->GetOriginalProfile());
[email protected]84214982008-12-10 18:49:101666}
1667
1668void Browser::NewIncognitoWindow() {
[email protected]eddcf7502012-02-09 22:43:481669 NewEmptyWindow(profile_->GetOffTheRecordProfile());
[email protected]84214982008-12-10 18:49:101670}
1671
[email protected]84214982008-12-10 18:49:101672void Browser::CloseWindow() {
[email protected]7f6f44c2011-12-14 13:23:381673 content::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101674 window_->Close();
1675}
1676
[email protected]fbd77592008-11-12 20:50:271677void Browser::NewTab() {
[email protected]7f6f44c2011-12-14 13:23:381678 content::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261679
[email protected]b35b26b32011-05-05 20:35:141680 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271681 AddBlankTab(true);
[email protected]41f022e2012-01-31 05:56:401682 GetSelectedWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271683 } else {
[email protected]1a6b30a2009-08-19 03:52:111684 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271685 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051686 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111687 // The call to AddBlankTab above did not set the focus to the tab as its
1688 // window was not active, so we have to do it explicitly.
1689 // See http://crbug.com/6380.
[email protected]41f022e2012-01-31 05:56:401690 b->GetSelectedWebContents()->GetView()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271691 }
1692}
1693
1694void Browser::CloseTab() {
[email protected]7f6f44c2011-12-14 13:23:381695 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211696 if (CanCloseTab())
[email protected]2fc15ae2012-05-06 00:01:371697 tab_strip_model_->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271698}
1699
[email protected]fbd77592008-11-12 20:50:271700void Browser::SelectNextTab() {
[email protected]7f6f44c2011-12-14 13:23:381701 content::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]2fc15ae2012-05-06 00:01:371702 tab_strip_model_->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271703}
1704
1705void Browser::SelectPreviousTab() {
[email protected]7f6f44c2011-12-14 13:23:381706 content::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]2fc15ae2012-05-06 00:01:371707 tab_strip_model_->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271708}
1709
[email protected]91ac9202010-07-30 18:32:351710void Browser::OpenTabpose() {
1711#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031712 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1713 switches::kEnableExposeForTabs)) {
1714 return;
1715 }
1716
[email protected]7f6f44c2011-12-14 13:23:381717 content::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351718 window()->OpenTabpose();
1719#else
1720 NOTREACHED();
1721#endif
1722}
1723
[email protected]9ac7fcb2009-09-14 18:22:521724void Browser::MoveTabNext() {
[email protected]7f6f44c2011-12-14 13:23:381725 content::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]2fc15ae2012-05-06 00:01:371726 tab_strip_model_->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521727}
1728
1729void Browser::MoveTabPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381730 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]2fc15ae2012-05-06 00:01:371731 tab_strip_model_->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521732}
1733
[email protected]fbd77592008-11-12 20:50:271734void Browser::SelectNumberedTab(int index) {
1735 if (index < tab_count()) {
[email protected]7f6f44c2011-12-14 13:23:381736 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]41f022e2012-01-31 05:56:401737 ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271738 }
1739}
1740
1741void Browser::SelectLastTab() {
[email protected]7f6f44c2011-12-14 13:23:381742 content::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]2fc15ae2012-05-06 00:01:371743 tab_strip_model_->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271744}
1745
1746void Browser::DuplicateTab() {
[email protected]7f6f44c2011-12-14 13:23:381747 content::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441748 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271749}
1750
[email protected]0c4c3882009-10-01 21:42:141751void Browser::WriteCurrentURLToClipboard() {
1752 // TODO(ericu): There isn't currently a metric for this. Should there be?
1753 // We don't appear to track the action when it comes from the
1754 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141755
[email protected]4ca15302012-01-03 05:53:201756 WebContents* contents = GetSelectedWebContents();
[email protected]ef557022012-03-16 10:05:331757 if (!toolbar_model_->ShouldDisplayURL())
[email protected]0c4c3882009-10-01 21:42:141758 return;
1759
[email protected]06305962012-05-09 22:34:361760 chrome_common_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141761 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171762 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141763 g_browser_process->clipboard());
1764}
1765
[email protected]fbd77592008-11-12 20:50:271766void Browser::ConvertPopupToTabbedBrowser() {
[email protected]7f6f44c2011-12-14 13:23:381767 content::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]2fc15ae2012-05-06 00:01:371768 TabContentsWrapper* contents = tab_strip_model_->DetachTabContentsAt(
1769 active_index());
[email protected]15952e462008-11-14 00:29:051770 Browser* browser = Browser::Create(profile_);
1771 browser->tabstrip_model()->AppendTabContents(contents, true);
1772 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271773}
1774
[email protected]184717d52012-02-22 04:46:161775void Browser::ToggleFullscreenMode() {
1776 fullscreen_controller_->ToggleFullscreenMode();
1777}
1778
[email protected]41d9faf2012-02-28 23:46:021779void Browser::ToggleFullscreenModeWithExtension(const GURL& extension_url) {
1780 fullscreen_controller_->ToggleFullscreenModeWithExtension(extension_url);
[email protected]9282cea2009-02-18 18:49:001781}
1782
[email protected]d3766932011-08-04 22:18:231783#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:161784void Browser::TogglePresentationMode() {
1785 fullscreen_controller_->TogglePresentationMode();
[email protected]d3766932011-08-04 22:18:231786}
1787#endif
1788
[email protected]92655362012-04-20 21:33:171789void Browser::Exit() {
1790 content::RecordAction(UserMetricsAction("Exit"));
1791 BrowserList::AttemptUserExit();
1792}
1793
[email protected]da17b372010-01-22 23:37:221794#if defined(OS_CHROMEOS)
[email protected]d14af522010-12-02 03:54:501795void Browser::ShowKeyboardOverlay() {
1796 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1797}
[email protected]20d17242009-10-26 20:21:051798#endif
1799
[email protected]36b6dcb2008-11-12 01:19:571800void Browser::BookmarkCurrentPage() {
[email protected]7f6f44c2011-12-14 13:23:381801 content::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271802
[email protected]76624fde2009-10-09 18:13:231803 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571804 if (!model || !model->IsLoaded())
1805 return; // Ignore requests until bookmarks are loaded.
1806
[email protected]76624fde2009-10-09 18:13:231807 GURL url;
[email protected]261cd762010-08-20 05:45:371808 string16 title;
[email protected]b375c5d2011-05-03 21:15:041809 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
[email protected]d9083482012-01-06 00:38:461810 bookmark_utils::GetURLAndTitleToBookmark(tab->web_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441811 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211812 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321813 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211814 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041815 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211816 }
[email protected]4394f2b2011-09-03 03:07:561817 bookmark_utils::AddIfNotBookmarked(model, url, title);
[email protected]11dbbd22009-11-06 18:55:041818 // Make sure the model actually added a bookmark before showing the star. A
1819 // bookmark isn't created if the url is invalid.
1820 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271821 // Only show the bubble if the window is active, otherwise we may get into
[email protected]b106ca52012-03-13 06:08:461822 // weird situations where the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441823 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271824 }
[email protected]36b6dcb2008-11-12 01:19:571825}
1826
[email protected]40bdb6d92009-02-25 00:22:271827void Browser::SavePage() {
[email protected]7f6f44c2011-12-14 13:23:381828 content::RecordAction(UserMetricsAction("SavePage"));
[email protected]4ca15302012-01-03 05:53:201829 WebContents* current_tab = GetSelectedWebContents();
[email protected]0bfbf882011-12-22 18:19:271830 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
[email protected]7f6f44c2011-12-14 13:23:381831 content::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]4ca15302012-01-03 05:53:201832 GetSelectedWebContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271833}
1834
[email protected]77d8d622010-12-15 10:30:121835void Browser::ViewSelectedSource() {
1836 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571837}
initial.commit09911bf2008-07-26 23:55:291838
[email protected]4801ecc2009-04-05 04:52:581839void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171840 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581841}
1842
[email protected]92655362012-04-20 21:33:171843void Browser::ShowPageInfo(content::WebContents* web_contents,
1844 const GURL& url,
1845 const SSLStatus& ssl,
1846 bool show_history) {
1847 Profile* profile = Profile::FromBrowserContext(
1848 web_contents->GetBrowserContext());
1849 TabContentsWrapper* wrapper =
1850 TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
1851
1852 if (CommandLine::ForCurrentProcess()->HasSwitch(
1853 switches::kEnableWebsiteSettings)) {
1854 window()->ShowWebsiteSettings(profile, wrapper, url, ssl, show_history);
1855 } else {
1856 window()->ShowPageInfo(profile, url, ssl, show_history);
1857 }
1858}
1859
1860void Browser::ShowChromeToMobileBubble() {
1861 // Only show the bubble if the window is active, otherwise we may get into
1862 // weird situations where the bubble is deleted as soon as it is shown.
1863 if (window_->IsActive())
1864 window_->ShowChromeToMobileBubble();
1865}
1866
[email protected]a3e18c42009-03-04 23:36:051867bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221868 return SupportsWindowFeatureImpl(feature, true);
1869}
[email protected]f5bf8ccf2010-02-05 18:19:251870
[email protected]018cf362010-05-05 22:43:221871bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1872 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051873}
1874
[email protected]fbd77592008-11-12 20:50:271875void Browser::Print() {
[email protected]47c7ec82012-01-18 03:29:211876 if (g_browser_process->local_state()->GetBoolean(
1877 prefs::kPrintPreviewDisabled)) {
[email protected]49fe2262011-04-15 20:56:151878 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]47c7ec82012-01-18 03:29:211879 } else {
1880 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1881 }
[email protected]fbd77592008-11-12 20:50:271882}
1883
[email protected]0996e9b2011-08-26 17:59:011884void Browser::AdvancedPrint() {
1885 GetSelectedTabContentsWrapper()->print_view_manager()->AdvancedPrintNow();
1886}
1887
[email protected]92655362012-04-20 21:33:171888void Browser::EmailPageLocation() {
1889 content::RecordAction(UserMetricsAction("EmailPageLocation"));
1890 WebContents* wc = GetSelectedWebContents();
1891 DCHECK(wc);
1892
1893 std::string title = net::EscapeQueryParamValue(
1894 UTF16ToUTF8(wc->GetTitle()), false);
1895 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
1896 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1897 title + "&body=%0A%0A" + page_url;
1898 platform_util::OpenExternal(GURL(mailto));
1899}
1900
[email protected]fbd77592008-11-12 20:50:271901void Browser::ToggleEncodingAutoDetect() {
[email protected]7f6f44c2011-12-14 13:23:381902 content::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271903 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181904 // If "auto detect" is turned on, then any current override encoding
1905 // is cleared. This also implicitly performs a reload.
1906 // OTOH, if "auto detect" is turned off, we don't change the currently
1907 // active encoding.
1908 if (encoding_auto_detect_.GetValue()) {
[email protected]4ca15302012-01-03 05:53:201909 WebContents* contents = GetSelectedWebContents();
[email protected]a697f4c2009-09-14 22:30:181910 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081911 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181912 }
[email protected]fbd77592008-11-12 20:50:271913}
1914
1915void Browser::OverrideEncoding(int encoding_id) {
[email protected]7f6f44c2011-12-14 13:23:381916 content::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401917 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271918 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]4ca15302012-01-03 05:53:201919 WebContents* contents = GetSelectedWebContents();
[email protected]57c6a652009-05-04 07:58:341920 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081921 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271922 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401923 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191924 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1925 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401926 encoding_id,
1927 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271928 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191929 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271930 }
[email protected]36b6dcb2008-11-12 01:19:571931}
1932
[email protected]84214982008-12-10 18:49:101933void Browser::Cut() {
[email protected]7f6f44c2011-12-14 13:23:381934 content::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231935 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571936}
1937
[email protected]84214982008-12-10 18:49:101938void Browser::Copy() {
[email protected]7f6f44c2011-12-14 13:23:381939 content::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231940 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571941}
1942
[email protected]84214982008-12-10 18:49:101943void Browser::Paste() {
[email protected]7f6f44c2011-12-14 13:23:381944 content::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231945 window()->Paste();
[email protected]84214982008-12-10 18:49:101946}
1947
1948void Browser::Find() {
[email protected]7f6f44c2011-12-14 13:23:381949 content::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291950 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101951}
1952
1953void Browser::FindNext() {
[email protected]7f6f44c2011-12-14 13:23:381954 content::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291955 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101956}
1957
1958void Browser::FindPrevious() {
[email protected]7f6f44c2011-12-14 13:23:381959 content::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291960 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101961}
1962
[email protected]54087fe2011-10-28 22:02:481963void Browser::Zoom(content::PageZoom zoom) {
[email protected]0bffaa322011-07-18 17:37:541964 if (is_devtools())
1965 return;
1966
[email protected]eaabba22012-03-07 15:02:111967 content::RenderViewHost* host = GetSelectedWebContents()->GetRenderViewHost();
[email protected]0f083402011-11-22 02:59:011968 if (zoom == content::PAGE_ZOOM_RESET) {
1969 host->SetZoomLevel(0);
[email protected]7f6f44c2011-12-14 13:23:381970 content::RecordAction(UserMetricsAction("ZoomNormal"));
[email protected]0f083402011-11-22 02:59:011971 return;
1972 }
[email protected]896220042010-03-23 18:14:281973
[email protected]4ca15302012-01-03 05:53:201974 double current_zoom_level = GetSelectedWebContents()->GetZoomLevel();
[email protected]0f083402011-11-22 02:59:011975 double default_zoom_level =
1976 profile_->GetPrefs()->GetDouble(prefs::kDefaultZoomLevel);
1977
1978 // Generate a vector of zoom levels from an array of known presets along with
1979 // the default level added if necessary.
1980 std::vector<double> zoom_levels =
1981 chrome_page_zoom::PresetZoomLevels(default_zoom_level);
1982
1983 if (zoom == content::PAGE_ZOOM_OUT) {
1984 // Iterate through the zoom levels in reverse order to find the next
1985 // lower level based on the current zoom level for this page.
1986 for (std::vector<double>::reverse_iterator i = zoom_levels.rbegin();
1987 i != zoom_levels.rend(); ++i) {
1988 double zoom_level = *i;
1989 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
1990 continue;
1991 if (zoom_level < current_zoom_level) {
1992 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:381993 content::RecordAction(UserMetricsAction("ZoomMinus"));
[email protected]0f083402011-11-22 02:59:011994 return;
1995 }
[email protected]7f6f44c2011-12-14 13:23:381996 content::RecordAction(UserMetricsAction("ZoomMinus_AtMinimum"));
[email protected]0f083402011-11-22 02:59:011997 }
1998 } else {
1999 // Iterate through the zoom levels in normal order to find the next
2000 // higher level based on the current zoom level for this page.
2001 for (std::vector<double>::const_iterator i = zoom_levels.begin();
2002 i != zoom_levels.end(); ++i) {
2003 double zoom_level = *i;
2004 if (content::ZoomValuesEqual(zoom_level, current_zoom_level))
2005 continue;
2006 if (zoom_level > current_zoom_level) {
2007 host->SetZoomLevel(zoom_level);
[email protected]7f6f44c2011-12-14 13:23:382008 content::RecordAction(UserMetricsAction("ZoomPlus"));
[email protected]0f083402011-11-22 02:59:012009 return;
2010 }
2011 }
[email protected]7f6f44c2011-12-14 13:23:382012 content::RecordAction(UserMetricsAction("ZoomPlus_AtMaximum"));
[email protected]0f083402011-11-22 02:59:012013 }
[email protected]84214982008-12-10 18:49:102014}
2015
2016void Browser::FocusToolbar() {
[email protected]7f6f44c2011-12-14 13:23:382017 content::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:102018 window_->FocusToolbar();
2019}
2020
2021void Browser::FocusLocationBar() {
[email protected]7f6f44c2011-12-14 13:23:382022 content::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:582023 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:102024}
2025
[email protected]92655362012-04-20 21:33:172026void Browser::FocusSearch() {
2027 // TODO(beng): replace this with FocusLocationBar
2028 content::RecordAction(UserMetricsAction("FocusSearch"));
2029 window_->GetLocationBar()->FocusSearch();
2030}
2031
2032void Browser::FocusAppMenu() {
2033 content::RecordAction(UserMetricsAction("FocusAppMenu"));
2034 window_->FocusAppMenu();
2035}
2036
[email protected]83548a42010-06-18 13:53:372037void Browser::FocusBookmarksToolbar() {
[email protected]7f6f44c2011-12-14 13:23:382038 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:372039 window_->FocusBookmarksToolbar();
2040}
2041
[email protected]83548a42010-06-18 13:53:372042void Browser::FocusNextPane() {
[email protected]7f6f44c2011-12-14 13:23:382043 content::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:372044 window_->RotatePaneFocus(true);
2045}
2046
2047void Browser::FocusPreviousPane() {
[email protected]7f6f44c2011-12-14 13:23:382048 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:372049 window_->RotatePaneFocus(false);
2050}
2051
[email protected]84214982008-12-10 18:49:102052void Browser::OpenFile() {
[email protected]7f6f44c2011-12-14 13:23:382053 content::RecordAction(UserMetricsAction("OpenFile"));
[email protected]84214982008-12-10 18:49:102054 if (!select_file_dialog_.get())
2055 select_file_dialog_ = SelectFileDialog::Create(this);
2056
[email protected]35896a32010-06-09 08:42:512057 const FilePath directory = profile_->last_selected_directory();
2058
[email protected]84214982008-12-10 18:49:102059 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:562060 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:102061 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:512062 string16(), directory,
[email protected]b949f1112009-04-12 20:03:082063 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]4ca15302012-01-03 05:53:202064 GetSelectedWebContents(),
[email protected]d56bcd22009-03-16 19:51:562065 parent_window, NULL);
[email protected]84214982008-12-10 18:49:102066}
2067
2068void Browser::OpenCreateShortcutsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382069 content::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:472070#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:492071 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
2072 DCHECK(current_tab &&
[email protected]d9083482012-01-06 00:38:462073 web_app::IsValidUrl(current_tab->web_contents()->GetURL())) <<
[email protected]3c9e1872010-11-18 16:17:492074 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:512075
[email protected]10f417c52011-12-28 21:04:232076 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:462077 current_tab->web_contents()->GetController().GetLastCommittedEntry();
[email protected]ed5431872009-11-17 08:39:512078 if (!entry)
2079 return;
2080
[email protected]eabfdae92009-12-11 06:13:512081 // RVH's GetApplicationInfo should not be called before it returns.
2082 DCHECK(pending_web_app_action_ == NONE);
2083 pending_web_app_action_ = CREATE_SHORTCUT;
2084
[email protected]a2cf65eb2010-01-18 08:20:382085 // Start fetching web app info for CreateApplicationShortcut dialog and show
2086 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]36fc0392011-12-25 03:59:512087 current_tab->extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]98f6e022009-06-05 22:49:532088#else
2089 NOTIMPLEMENTED();
2090#endif
[email protected]36b6dcb2008-11-12 01:19:572091}
2092
[email protected]2a8a98122010-07-16 11:58:482093void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
[email protected]e3791ce92011-08-09 01:03:322094 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
[email protected]7f6f44c2011-12-14 13:23:382095 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
[email protected]e3791ce92011-08-09 01:03:322096 else
[email protected]7f6f44c2011-12-14 13:23:382097 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
[email protected]e3791ce92011-08-09 01:03:322098
[email protected]aebdd072011-07-07 12:36:592099 DevToolsWindow::ToggleDevToolsWindow(
[email protected]41f022e2012-01-31 05:56:402100 GetSelectedWebContents()->GetRenderViewHost(),
[email protected]4a63e242011-12-12 15:23:082101 action);
[email protected]fbd77592008-11-12 20:50:272102}
2103
[email protected]adb6a84d2011-02-07 16:58:402104void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]7f6f44c2011-12-14 13:23:382105 content::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:402106 if (highlight_background_resources)
2107 window_->ShowBackgroundPages();
2108 else
2109 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:102110}
2111
[email protected]daa9e382012-01-06 00:30:342112void Browser::OpenFeedbackDialog() {
2113 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]5835871a2012-04-25 21:56:552114 browser::ShowWebFeedbackView(this, std::string(), std::string());
[email protected]84214982008-12-10 18:49:102115}
[email protected]44b2c8852009-03-18 00:57:492116
[email protected]84214982008-12-10 18:49:102117void Browser::ToggleBookmarkBar() {
[email protected]7f6f44c2011-12-14 13:23:382118 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:102119 window_->ToggleBookmarkBar();
2120}
2121
[email protected]84214982008-12-10 18:49:102122void Browser::OpenBookmarkManager() {
[email protected]7f6f44c2011-12-14 13:23:382123 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
2124 content::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]0af8f132011-07-16 01:37:022125 ShowSingletonTabOverwritingNTP(
[email protected]a179fac72011-08-29 22:22:422126 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIBookmarksURL)));
[email protected]0af8f132011-07-16 01:37:022127}
2128
[email protected]4c9ee222011-08-17 19:51:352129void Browser::OpenBookmarkManagerForNode(int64 node_id) {
2130 OpenBookmarkManagerWithHash("", node_id);
2131}
2132
2133void Browser::OpenBookmarkManagerEditNode(int64 node_id) {
2134 OpenBookmarkManagerWithHash("e=", node_id);
2135}
2136
[email protected]fdb98512009-08-26 01:37:102137void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:122138 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:102139 window_->ShowAppMenu();
2140}
2141
[email protected]7d2d08152011-10-25 22:58:472142void Browser::ShowAvatarMenu() {
2143 window_->ShowAvatarBubbleFromAvatarButton();
2144}
2145
[email protected]8bf80e922009-03-09 20:56:362146void Browser::ShowHistoryTab() {
[email protected]7f6f44c2011-12-14 13:23:382147 content::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]56e613862012-03-29 19:51:522148 browser::NavigateParams params(
2149 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIHistoryURL)));
[email protected]a048ad22012-03-23 04:26:562150 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2151 ShowSingletonTabOverwritingNTP(params);
[email protected]8bf80e922009-03-09 20:56:362152}
[email protected]84214982008-12-10 18:49:102153
2154void Browser::ShowDownloadsTab() {
[email protected]7f6f44c2011-12-14 13:23:382155 content::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]3d037ce72011-04-04 17:43:452156 if (window()) {
2157 DownloadShelf* shelf = window()->GetDownloadShelf();
2158 if (shelf->IsShowing())
2159 shelf->Close();
2160 }
[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]55a66012012-03-31 00:56:022167 browser::NavigateParams params(
2168 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIExtensionsURL)));
[email protected]a048ad22012-03-23 04:26:562169 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2170 ShowSingletonTabOverwritingNTP(params);
[email protected]34085a32009-11-06 22:49:482171}
2172
[email protected]c1bbaa82010-11-08 11:17:052173void Browser::ShowAboutConflictsTab() {
[email protected]7f6f44c2011-12-14 13:23:382174 content::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:492175 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:052176}
2177
[email protected]d9083482012-01-06 00:38:462178void Browser::ShowBrokenPageTab(WebContents* contents) {
[email protected]daa9e382012-01-06 00:30:342179 content::RecordAction(UserMetricsAction("Feedback"));
[email protected]10e457c2010-04-29 03:35:232180 string16 page_title = contents->GetTitle();
[email protected]10f417c52011-12-28 21:04:232181 NavigationEntry* entry = contents->GetController().GetActiveEntry();
[email protected]10e457c2010-04-29 03:35:232182 if (!entry)
2183 return;
[email protected]36fc0392011-12-25 03:59:512184 std::string page_url = entry->GetURL().spec();
[email protected]10e457c2010-04-29 03:35:232185 std::vector<std::string> subst;
2186 subst.push_back(UTF16ToASCII(page_title));
2187 subst.push_back(page_url);
2188 std::string report_page_url =
2189 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:492190 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:232191}
2192
[email protected]12e816bde2010-09-14 19:59:292193void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]55a66012012-03-31 00:56:022194 std::string url = std::string(chrome::kChromeUISettingsURL) + sub_page;
[email protected]f563e9132012-03-07 02:04:302195#if defined(OS_CHROMEOS)
[email protected]55a66012012-03-31 00:56:022196 if (sub_page.find(chrome::kInternetOptionsSubPage, 0) != std::string::npos) {
[email protected]a048ad22012-03-23 04:26:562197 std::string::size_type loc = sub_page.find("?", 0);
2198 std::string network_page = loc != std::string::npos ?
2199 sub_page.substr(loc) : std::string();
[email protected]55a66012012-03-31 00:56:022200 url = std::string(chrome::kChromeUISettingsURL) + network_page;
[email protected]f5ec7242012-01-27 07:15:152201 }
[email protected]55a66012012-03-31 00:56:022202#endif
[email protected]a048ad22012-03-23 04:26:562203 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
2204 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2205 ShowSingletonTabOverwritingNTP(params);
[email protected]4a42d272010-06-18 01:29:422206}
2207
[email protected]92655362012-04-20 21:33:172208void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
2209 ShowOptionsTab(
2210 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
2211 options2::ContentSettingsHandler::ContentSettingsTypeToGroupName(
2212 content_type));
2213}
2214
[email protected]84214982008-12-10 18:49:102215void Browser::OpenClearBrowsingDataDialog() {
[email protected]7f6f44c2011-12-14 13:23:382216 content::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:052217 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:102218}
2219
[email protected]84214982008-12-10 18:49:102220void Browser::OpenOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382221 content::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]089562d2012-03-26 20:41:512222 ShowOptionsTab(std::string());
[email protected]fbd77592008-11-12 20:50:272223}
2224
2225void Browser::OpenPasswordManager() {
[email protected]7f6f44c2011-12-14 13:23:382226 content::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:042227 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272228}
2229
[email protected]1bdf29e2009-05-11 23:45:252230void Browser::OpenImportSettingsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382231 content::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052232 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252233}
[email protected]1bdf29e2009-05-11 23:45:252234
[email protected]b99081b2011-03-10 17:43:472235void Browser::OpenInstantConfirmDialog() {
2236 ShowOptionsTab(chrome::kInstantConfirmPage);
2237}
2238
[email protected]fbd77592008-11-12 20:50:272239void Browser::OpenAboutChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382240 content::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]a9fbb0962012-03-21 23:25:132241#if !defined(OS_WIN)
[email protected]55a66012012-03-31 00:56:022242 browser::NavigateParams params(
2243 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIUberURL)));
[email protected]a8928f82012-03-27 05:48:122244 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2245 ShowSingletonTabOverwritingNTP(params);
[email protected]4ea87862012-02-21 19:45:102246#else
[email protected]a048ad22012-03-23 04:26:562247 // crbug.com/115123.
2248 window_->ShowAboutChromeDialog();
[email protected]4ea87862012-02-21 19:45:102249#endif
[email protected]fbd77592008-11-12 20:50:272250}
2251
[email protected]b1b73942010-05-26 20:11:542252void Browser::OpenUpdateChromeDialog() {
[email protected]7f6f44c2011-12-14 13:23:382253 content::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542254 window_->ShowUpdateChromeDialog();
2255}
2256
[email protected]202802e42011-07-06 11:40:462257void Browser::ShowHelpTab() {
[email protected]7f6f44c2011-12-14 13:23:382258 content::RecordAction(UserMetricsAction("ShowHelpTab"));
[email protected]adc8e852012-01-29 08:58:222259 ShowSingletonTab(GURL(chrome::kChromeHelpURL));
[email protected]fbd77592008-11-12 20:50:272260}
2261
[email protected]92655362012-04-20 21:33:172262void Browser::OpenAutofillHelpTabAndActivate() {
2263 AddSelectedTabWithURL(GURL(chrome::kAutofillHelpURL),
2264 content::PAGE_TRANSITION_LINK);
2265}
2266
[email protected]31cc1c022010-10-15 20:03:472267void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202268 OpenURL(OpenURLParams(
2269 GURL(kPrivacyDashboardUrl), Referrer(),
2270 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_LINK, false));
[email protected]31cc1c022010-10-15 20:03:472271 window_->Activate();
2272}
2273
[email protected]024617a2010-08-20 05:08:052274void Browser::OpenSearchEngineOptionsDialog() {
[email protected]7f6f44c2011-12-14 13:23:382275 content::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052276 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052277}
2278
[email protected]a003d8e2010-10-02 21:03:352279void Browser::OpenPluginsTabAndActivate() {
[email protected]e5d549d2011-12-28 01:29:202280 OpenURL(OpenURLParams(
2281 GURL(chrome::kChromeUIPluginsURL), Referrer(), NEW_FOREGROUND_TAB,
2282 content::PAGE_TRANSITION_LINK, false));
[email protected]a003d8e2010-10-02 21:03:352283 window_->Activate();
2284}
2285
[email protected]92655362012-04-20 21:33:172286void Browser::ShowSyncSetup(SyncPromoUI::Source source) {
2287 ProfileSyncService* service =
2288 ProfileSyncServiceFactory::GetInstance()->GetForProfile(
2289 profile()->GetOriginalProfile());
2290 LoginUIService* login_service =
2291 LoginUIServiceFactory::GetForProfile(profile()->GetOriginalProfile());
2292 if (service->HasSyncSetupCompleted()) {
2293 ShowOptionsTab(std::string());
2294 } else if (SyncPromoUI::ShouldShowSyncPromo(profile()) &&
2295 login_service->current_login_ui() == NULL) {
2296 // There is no currently active login UI, so display a new promo page.
2297 GURL url(SyncPromoUI::GetSyncPromoURL(GURL(), source));
2298 browser::NavigateParams params(GetSingletonTabNavigateParams(GURL(url)));
2299 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
2300 ShowSingletonTabOverwritingNTP(params);
2301 } else {
2302 LoginUIServiceFactory::GetForProfile(
[email protected]bdb27902012-05-01 23:33:392303 profile()->GetOriginalProfile())->ShowLoginUI();
[email protected]92655362012-04-20 21:33:172304 }
2305}
2306
2307void Browser::ToggleSpeechInput() {
2308 GetSelectedWebContents()->GetRenderViewHost()->ToggleSpeechInput();
2309}
2310
2311void Browser::UpdateDownloadShelfVisibility(bool visible) {
2312 if (GetStatusBubble())
2313 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
2314}
2315
[email protected]36b6dcb2008-11-12 01:19:572316///////////////////////////////////////////////////////////////////////////////
2317
2318// static
[email protected]79117172009-08-28 16:11:442319void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542320 const PrefService::Preference* home_page_pref =
2321 prefs->FindPreference(prefs::kHomePage);
2322 if (home_page_pref &&
2323 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192324 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]1d8e794e42012-04-06 02:41:452325 prefs->SetString(prefs::kHomePage, std::string());
[email protected]ddd231e2010-06-29 20:35:192326 }
[email protected]8fe6e1c2010-05-27 08:21:542327 const PrefService::Preference* home_page_is_new_tab_page_pref =
2328 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2329 if (home_page_is_new_tab_page_pref &&
2330 !home_page_is_new_tab_page_pref->IsManaged() &&
2331 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332332 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442333}
2334
2335// static
[email protected]36b6dcb2008-11-12 01:19:572336void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572337 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]d9898912011-04-15 21:10:002338 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]4e72ebb2011-10-18 05:02:182339 prefs->RegisterBooleanPref(prefs::kShouldShowFirstRunBubble, false);
[email protected]47c7ec82012-01-18 03:29:212340 prefs->RegisterBooleanPref(prefs::kPrintPreviewDisabled,
2341#if defined(GOOGLE_CHROME_BUILD)
2342 false
2343#else
2344 true
2345#endif
2346 );
[email protected]36b6dcb2008-11-12 01:19:572347}
2348
2349// static
2350void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182351 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]1d8e794e42012-04-06 02:41:452352 std::string(),
[email protected]d36f941b2011-05-09 06:19:162353 PrefService::SYNCABLE_PREF);
[email protected]6c6b02d2011-09-02 03:36:472354 prefs->RegisterBooleanPref(prefs::kHomePageChanged,
2355 false,
2356 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162357 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2358 true,
2359 PrefService::SYNCABLE_PREF);
2360 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2361 false,
2362 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092363#if defined(OS_MACOSX)
2364 // This really belongs in platform code, but there's no good place to
2365 // initialize it between the time when the AppController is created
2366 // (where there's no profile) and the time the controller gets another
[email protected]fe7c4872012-05-10 20:06:032367 // crack at the start of the main event loop. By that time,
2368 // StartupBrowserCreator has already created the browser window, and it's too
2369 // late: we need the pref to be already initialized. Doing it here also saves
2370 // us from having to hard-code pref registration in the several unit tests
2371 // that use this preference.
[email protected]d36f941b2011-05-09 06:19:162372 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2373 true,
2374 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092375#endif
[email protected]d36f941b2011-05-09 06:19:162376 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2377 true,
2378 PrefService::SYNCABLE_PREF);
2379 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2380 true,
2381 PrefService::SYNCABLE_PREF);
2382 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2383 true,
2384 PrefService::SYNCABLE_PREF);
2385 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2386 true,
2387 PrefService::SYNCABLE_PREF);
2388 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2389 false,
2390 PrefService::SYNCABLE_PREF);
2391 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2392 false,
2393 PrefService::SYNCABLE_PREF);
2394 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2395 0,
2396 PrefService::SYNCABLE_PREF);
2397 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2398 true,
2399 PrefService::UNSYNCABLE_PREF);
2400 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2401 true,
2402 PrefService::UNSYNCABLE_PREF);
2403 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2404 true,
2405 PrefService::UNSYNCABLE_PREF);
2406 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2407 true,
2408 PrefService::UNSYNCABLE_PREF);
2409 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2410 true,
2411 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162412 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2413 true,
2414 PrefService::SYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162415 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2416 std::string(),
2417 PrefService::UNSYNCABLE_PREF);
2418 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2419 true,
2420 PrefService::UNSYNCABLE_PREF);
[email protected]1af419c2011-10-31 23:45:412421 prefs->RegisterBooleanPref(prefs::kCloudPrintSubmitEnabled,
2422 true,
2423 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162424 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2425 false,
2426 PrefService::UNSYNCABLE_PREF);
[email protected]945ec5c2012-03-06 18:00:212427 prefs->RegisterIntegerPref(prefs::kDevToolsHSplitLocation,
2428 -1,
2429 PrefService::UNSYNCABLE_PREF);
2430 prefs->RegisterIntegerPref(prefs::kDevToolsVSplitLocation,
[email protected]d36f941b2011-05-09 06:19:162431 -1,
2432 PrefService::UNSYNCABLE_PREF);
2433 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2434 PrefService::UNSYNCABLE_PREF);
2435 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2436 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122437 prefs->RegisterBooleanPref(prefs::kImportBookmarks,
2438 true,
2439 PrefService::UNSYNCABLE_PREF);
2440 prefs->RegisterBooleanPref(prefs::kImportHistory,
2441 true,
2442 PrefService::UNSYNCABLE_PREF);
2443 prefs->RegisterBooleanPref(prefs::kImportHomepage,
2444 true,
2445 PrefService::UNSYNCABLE_PREF);
2446 prefs->RegisterBooleanPref(prefs::kImportSearchEngine,
2447 true,
2448 PrefService::UNSYNCABLE_PREF);
2449 prefs->RegisterBooleanPref(prefs::kImportSavedPasswords,
2450 true,
2451 PrefService::UNSYNCABLE_PREF);
[email protected]f6e680912011-09-21 20:26:192452 // The map of timestamps of the last used file browser handlers.
2453 prefs->RegisterDictionaryPref(prefs::kLastUsedFileBrowserHandlers,
2454 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122455
[email protected]2bf2bd92011-03-31 07:12:442456 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162457 // them even though they're only typically controlled via policy.
2458 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2459 false,
2460 PrefService::UNSYNCABLE_PREF);
2461 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2462 false,
2463 PrefService::UNSYNCABLE_PREF);
2464 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2465 false,
2466 PrefService::UNSYNCABLE_PREF);
2467 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2468 true,
2469 PrefService::UNSYNCABLE_PREF);
2470 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2471 true,
2472 PrefService::UNSYNCABLE_PREF);
[email protected]781be952011-08-31 20:22:142473 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled,
2474 true,
2475 PrefService::UNSYNCABLE_PREF);
[email protected]80b07612011-12-12 16:04:302476 prefs->RegisterBooleanPref(prefs::kEnableMemoryInfo,
2477 false,
2478 PrefService::UNSYNCABLE_PREF);
[email protected]f2df3112011-11-18 10:21:482479
2480 // Initialize the disk cache prefs.
2481 prefs->RegisterFilePathPref(prefs::kDiskCacheDir,
2482 FilePath(),
2483 PrefService::UNSYNCABLE_PREF);
2484 prefs->RegisterIntegerPref(prefs::kDiskCacheSize,
2485 0,
2486 PrefService::UNSYNCABLE_PREF);
2487 prefs->RegisterIntegerPref(prefs::kMediaCacheSize,
2488 0,
2489 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572490}
2491
2492// static
[email protected]d9083482012-01-06 00:38:462493bool Browser::RunUnloadEventsHelper(WebContents* contents) {
[email protected]075969d2012-04-17 20:05:552494 // If the WebContents is not connected yet, then there's no unload
2495 // handler we can fire even if the WebContents has an unload listener.
[email protected]ecc523f62010-09-28 22:45:402496 // One case where we hit this is in a tab that has an infinite loop
2497 // before load.
[email protected]5aab5e22010-12-08 22:13:292498 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402499 // If the page has unload listeners, then we tell the renderer to fire
2500 // them. Once they have fired, we'll get a message back saying whether
2501 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292502 // with the NeedToFireBeforeUnload bit cleared.
[email protected]151a63d2011-12-20 22:32:522503 contents->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]ecc523f62010-09-28 22:45:402504 return true;
2505 }
2506 return false;
2507}
2508
2509// static
[email protected]36b6dcb2008-11-12 01:19:572510Browser* Browser::GetBrowserForController(
[email protected]c5eed492012-01-04 17:07:502511 const NavigationController* controller, int* index_result) {
[email protected]36b6dcb2008-11-12 01:19:572512 BrowserList::const_iterator it;
2513 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]41f022e2012-01-31 05:56:402514 int index = (*it)->GetIndexOfController(controller);
[email protected]36b6dcb2008-11-12 01:19:572515 if (index != TabStripModel::kNoTab) {
2516 if (index_result)
2517 *index_result = index;
2518 return *it;
2519 }
2520 }
2521
2522 return NULL;
2523}
2524
[email protected]3a29a6e2011-08-24 18:26:212525// static
[email protected]1953f41f2012-05-10 21:21:592526Browser* Browser::GetTabbedBrowser(Profile* profile,
2527 bool match_original_profiles) {
2528 return BrowserList::FindTabbedBrowser(profile, match_original_profiles);
[email protected]92655362012-04-20 21:33:172529}
2530
2531// static
2532Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
2533 Browser* browser = GetTabbedBrowser(profile, false);
2534 if (!browser)
2535 browser = Browser::Create(profile);
2536 return browser;
2537}
2538
2539// static
[email protected]3a29a6e2011-08-24 18:26:212540void Browser::RunFileChooserHelper(
[email protected]2a6bc3e2011-12-28 23:51:332541 WebContents* tab, const content::FileChooserParams& params) {
[email protected]3a29a6e2011-08-24 18:26:212542 Profile* profile =
[email protected]627e0512011-12-21 22:55:302543 Profile::FromBrowserContext(tab->GetBrowserContext());
[email protected]9f054aa12011-09-29 19:13:452544 // FileSelectHelper adds a reference to itself and only releases it after
2545 // sending the result message. It won't be destroyed when this reference
2546 // goes out of scope.
2547 scoped_refptr<FileSelectHelper> file_select_helper(
2548 new FileSelectHelper(profile));
[email protected]151a63d2011-12-20 22:32:522549 file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params);
[email protected]3a29a6e2011-08-24 18:26:212550}
2551
2552// static
[email protected]2a6bc3e2011-12-28 23:51:332553void Browser::EnumerateDirectoryHelper(WebContents* tab, int request_id,
[email protected]3a29a6e2011-08-24 18:26:212554 const FilePath& path) {
[email protected]3a29a6e2011-08-24 18:26:212555 Profile* profile =
[email protected]627e0512011-12-21 22:55:302556 Profile::FromBrowserContext(tab->GetBrowserContext());
[email protected]9f054aa12011-09-29 19:13:452557 // FileSelectHelper adds a reference to itself and only releases it after
2558 // sending the result message. It won't be destroyed when this reference
2559 // goes out of scope.
2560 scoped_refptr<FileSelectHelper> file_select_helper(
2561 new FileSelectHelper(profile));
[email protected]3a29a6e2011-08-24 18:26:212562 file_select_helper->EnumerateDirectory(request_id,
[email protected]151a63d2011-12-20 22:32:522563 tab->GetRenderViewHost(),
[email protected]3a29a6e2011-08-24 18:26:212564 path);
2565}
2566
[email protected]7d189022011-08-25 22:54:202567// static
[email protected]2a6bc3e2011-12-28 23:51:332568void Browser::JSOutOfMemoryHelper(WebContents* tab) {
[email protected]7d189022011-08-25 22:54:202569 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2570 tab);
[email protected]2a6bc3e2011-12-28 23:51:332571 if (!tcw)
2572 return;
2573
2574 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
2575 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
2576 infobar_helper,
2577 NULL,
2578 l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT),
2579 true));
[email protected]7d189022011-08-25 22:54:202580}
2581
2582// static
[email protected]2a6bc3e2011-12-28 23:51:332583void Browser::RegisterProtocolHandlerHelper(WebContents* tab,
[email protected]7d189022011-08-25 22:54:202584 const std::string& protocol,
2585 const GURL& url,
2586 const string16& title) {
2587 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2588 tab);
2589 if (!tcw || tcw->profile()->IsOffTheRecord())
2590 return;
2591
[email protected]7d189022011-08-25 22:54:202592 ProtocolHandler handler =
2593 ProtocolHandler::CreateProtocolHandler(protocol, url, title);
2594
2595 ProtocolHandlerRegistry* registry =
2596 tcw->profile()->GetProtocolHandlerRegistry();
[email protected]7d189022011-08-25 22:54:202597
[email protected]a50af292011-10-25 03:07:402598 if (!registry->SilentlyHandleRegisterHandlerRequest(handler)) {
[email protected]7f6f44c2011-12-14 13:23:382599 content::RecordAction(
[email protected]7d189022011-08-25 22:54:202600 UserMetricsAction("RegisterProtocolHandler.InfoBar_Shown"));
[email protected]95a33ed62011-09-30 15:07:082601 InfoBarTabHelper* infobar_helper = tcw->infobar_tab_helper();
[email protected]d3ddb6d2012-01-06 02:51:172602
2603 RegisterProtocolHandlerInfoBarDelegate* rph_delegate =
[email protected]95a33ed62011-09-30 15:07:082604 new RegisterProtocolHandlerInfoBarDelegate(infobar_helper,
2605 registry,
[email protected]d3ddb6d2012-01-06 02:51:172606 handler);
2607
2608 for (size_t i = 0; i < infobar_helper->infobar_count(); i++) {
2609 InfoBarDelegate* delegate = infobar_helper->GetInfoBarDelegateAt(i);
2610 RegisterProtocolHandlerInfoBarDelegate* cast_delegate =
2611 delegate->AsRegisterProtocolHandlerInfoBarDelegate();
2612 if (cast_delegate != NULL && cast_delegate->IsReplacedBy(rph_delegate)) {
2613 infobar_helper->ReplaceInfoBar(cast_delegate, rph_delegate);
2614 rph_delegate = NULL;
2615 break;
2616 }
2617 }
2618
2619 if (rph_delegate != NULL)
2620 infobar_helper->AddInfoBar(rph_delegate);
[email protected]7d189022011-08-25 22:54:202621 }
2622}
2623
2624// static
[email protected]2a6bc3e2011-12-28 23:51:332625void Browser::FindReplyHelper(WebContents* tab,
[email protected]b888919c2011-09-02 00:32:162626 int request_id,
2627 int number_of_matches,
2628 const gfx::Rect& selection_rect,
2629 int active_match_ordinal,
2630 bool final_update) {
2631 TabContentsWrapper* tcw = TabContentsWrapper::GetCurrentWrapperForContents(
2632 tab);
2633 if (!tcw || !tcw->find_tab_helper())
2634 return;
2635
2636 tcw->find_tab_helper()->HandleFindReply(request_id, number_of_matches,
2637 selection_rect, active_match_ordinal,
2638 final_update);
2639}
2640
[email protected]ef557022012-03-16 10:05:332641void Browser::ExecuteCommand(int id) {
2642 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2643}
2644
2645void Browser::ExecuteCommand(int id, int event_flags) {
2646 ExecuteCommandWithDisposition(
2647 id, browser::DispositionFromEventFlags(event_flags));
2648}
2649
2650bool Browser::ExecuteCommandIfEnabled(int id) {
2651 if (command_updater_.SupportsCommand(id) &&
2652 command_updater_.IsCommandEnabled(id)) {
2653 ExecuteCommand(id);
2654 return true;
2655 }
2656 return false;
2657}
2658
2659bool Browser::IsReservedCommandOrKey(int command_id,
2660 const NativeWebKeyboardEvent& event) {
2661#if defined(OS_CHROMEOS)
2662 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
2663 // aren't able to block Chrome from performing the standard actions for F1-F4
2664 // (F5-7 are grabbed by other X clients and hence don't need this protection,
2665 // and F8-10 are handled separately in Chrome via a GDK event filter, but
2666 // let's future-proof this).
2667 ui::KeyboardCode key_code =
2668 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
2669 if (key_code == ui::VKEY_F1 ||
2670 key_code == ui::VKEY_F2 ||
2671 key_code == ui::VKEY_F3 ||
2672 key_code == ui::VKEY_F4 ||
2673 key_code == ui::VKEY_F5 ||
2674 key_code == ui::VKEY_F6 ||
2675 key_code == ui::VKEY_F7 ||
2676 key_code == ui::VKEY_F8 ||
2677 key_code == ui::VKEY_F9 ||
2678 key_code == ui::VKEY_F10) {
2679 return true;
2680 }
2681#endif
2682
[email protected]68676962012-03-20 21:22:102683 // In Apps mode, no keys are reserved.
2684 if (is_app())
2685 return false;
2686
[email protected]ef557022012-03-16 10:05:332687 if (window_->IsFullscreen() && command_id == IDC_FULLSCREEN)
2688 return true;
2689 return command_id == IDC_CLOSE_TAB ||
2690 command_id == IDC_CLOSE_WINDOW ||
2691 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2692 command_id == IDC_NEW_TAB ||
2693 command_id == IDC_NEW_WINDOW ||
2694 command_id == IDC_RESTORE_TAB ||
2695 command_id == IDC_SELECT_NEXT_TAB ||
2696 command_id == IDC_SELECT_PREVIOUS_TAB ||
2697 command_id == IDC_TABPOSE ||
2698 command_id == IDC_EXIT ||
2699 command_id == IDC_SEARCH;
2700}
2701
2702void Browser::SetBlockCommandExecution(bool block) {
2703 block_command_execution_ = block;
2704 if (block) {
2705 last_blocked_command_id_ = -1;
2706 last_blocked_command_disposition_ = CURRENT_TAB;
2707 }
2708}
2709
2710int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2711 if (disposition)
2712 *disposition = last_blocked_command_disposition_;
2713 return last_blocked_command_id_;
2714}
2715
2716void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
2717 content::PageTransition transition,
2718 bool user_initiated) {
[email protected]2fc15ae2012-05-06 00:01:372719 tab_strip_model_->TabNavigating(contents, transition);
[email protected]ef557022012-03-16 10:05:332720
2721 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
2722 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2723 // Forcibly reset the location bar if the url is going to change in the
2724 // current tab, since otherwise it won't discard any ongoing user edits,
2725 // since it doesn't realize this is a user-initiated action.
2726 window()->GetLocationBar()->Revert();
2727 }
2728
2729 if (GetStatusBubble())
2730 GetStatusBubble()->Hide();
2731
2732 // Update the location bar. This is synchronous. We specifically don't
2733 // update the load state since the load hasn't started yet and updating it
2734 // will put it out of sync with the actual state like whether we're
2735 // displaying a favicon, which controls the throbber. If we updated it here,
2736 // the throbber will show the default favicon for a split second when
2737 // navigating away from the new tab page.
2738 ScheduleUIUpdate(contents->web_contents(), content::INVALIDATE_TYPE_URL);
2739
2740 if (contents_is_selected)
2741 contents->web_contents()->Focus();
2742}
2743
[email protected]92655362012-04-20 21:33:172744void Browser::ShowCollectedCookiesDialog(TabContentsWrapper* wrapper) {
2745 browser::ShowCollectedCookiesDialog(window()->GetNativeHandle(), wrapper);
2746}
2747
[email protected]ef557022012-03-16 10:05:332748///////////////////////////////////////////////////////////////////////////////
2749// Browser, PageNavigator implementation:
2750
2751WebContents* Browser::OpenURL(const OpenURLParams& params) {
2752 return OpenURLFromTab(NULL, params);
2753}
2754
2755///////////////////////////////////////////////////////////////////////////////
2756// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2757
[email protected]485fba42009-03-24 23:27:292758void Browser::ExecuteCommandWithDisposition(
2759 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142760 // No commands are enabled if there is not yet any selected tab.
2761 // TODO(pkasting): It seems like we should not need this, because either
2762 // most/all commands should not have been enabled yet anyway or the ones that
2763 // are enabled should be global, or safe themselves against having no selected
2764 // tab. However, Ben says he tried removing this before and got lots of
2765 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2766 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492767 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142768 return;
2769
[email protected]59c9f002010-11-19 00:38:052770 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2771 << id;
[email protected]36b6dcb2008-11-12 01:19:572772
[email protected]867125a02009-12-10 06:01:482773 // If command execution is blocked then just record the command and return.
2774 if (block_command_execution_) {
2775 // We actually only allow no more than one blocked command, otherwise some
2776 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062777 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482778 last_blocked_command_id_ = id;
2779 last_blocked_command_disposition_ = disposition;
2780 return;
2781 }
2782
[email protected]fbd77592008-11-12 20:50:272783 // The order of commands in this switch statement must match the function
2784 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572785 switch (id) {
[email protected]84214982008-12-10 18:49:102786 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282787 case IDC_BACK: GoBack(disposition); break;
2788 case IDC_FORWARD: GoForward(disposition); break;
2789 case IDC_RELOAD: Reload(disposition); break;
2790 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2791 case IDC_HOME: Home(disposition); break;
2792 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282793 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572794
[email protected]84214982008-12-10 18:49:102795 // Window management commands
[email protected]cb84d642010-06-10 00:56:282796 case IDC_NEW_WINDOW: NewWindow(); break;
2797 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282798 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2799 case IDC_NEW_TAB: NewTab(); break;
2800 case IDC_CLOSE_TAB: CloseTab(); break;
2801 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2802 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352803 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282804 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2805 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572806 case IDC_SELECT_TAB_0:
2807 case IDC_SELECT_TAB_1:
2808 case IDC_SELECT_TAB_2:
2809 case IDC_SELECT_TAB_3:
2810 case IDC_SELECT_TAB_4:
2811 case IDC_SELECT_TAB_5:
2812 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542813 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282814 break;
2815 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2816 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2817 case IDC_RESTORE_TAB: RestoreTab(); break;
2818 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2819 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
[email protected]184717d52012-02-22 04:46:162820 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
[email protected]d3766932011-08-04 22:18:232821#if defined(OS_MACOSX)
[email protected]184717d52012-02-22 04:46:162822 case IDC_PRESENTATION_MODE: TogglePresentationMode(); break;
[email protected]d3766932011-08-04 22:18:232823#endif
[email protected]cb84d642010-06-10 00:56:282824 case IDC_EXIT: Exit(); break;
[email protected]da17b372010-01-22 23:37:222825#if defined(OS_CHROMEOS)
[email protected]d14af522010-12-02 03:54:502826 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052827#endif
[email protected]36b6dcb2008-11-12 01:19:572828
[email protected]84214982008-12-10 18:49:102829 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282830 case IDC_SAVE_PAGE: SavePage(); break;
2831 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2832 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122833 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282834 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2835 case IDC_PRINT: Print(); break;
[email protected]0996e9b2011-08-26 17:59:012836 case IDC_ADVANCED_PRINT: AdvancedPrint(); break;
[email protected]b106ca52012-03-13 06:08:462837 case IDC_CHROME_TO_MOBILE_PAGE: ShowChromeToMobileBubble(); break;
[email protected]cb84d642010-06-10 00:56:282838 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572839 case IDC_ENCODING_UTF8:
2840 case IDC_ENCODING_UTF16LE:
2841 case IDC_ENCODING_ISO88591:
2842 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492843 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572844 case IDC_ENCODING_GB18030:
2845 case IDC_ENCODING_BIG5HKSCS:
2846 case IDC_ENCODING_BIG5:
2847 case IDC_ENCODING_KOREAN:
2848 case IDC_ENCODING_SHIFTJIS:
2849 case IDC_ENCODING_ISO2022JP:
2850 case IDC_ENCODING_EUCJP:
2851 case IDC_ENCODING_THAI:
2852 case IDC_ENCODING_ISO885915:
2853 case IDC_ENCODING_MACINTOSH:
2854 case IDC_ENCODING_ISO88592:
2855 case IDC_ENCODING_WINDOWS1250:
2856 case IDC_ENCODING_ISO88595:
2857 case IDC_ENCODING_WINDOWS1251:
2858 case IDC_ENCODING_KOI8R:
2859 case IDC_ENCODING_KOI8U:
2860 case IDC_ENCODING_ISO88597:
2861 case IDC_ENCODING_WINDOWS1253:
2862 case IDC_ENCODING_ISO88594:
2863 case IDC_ENCODING_ISO885913:
2864 case IDC_ENCODING_WINDOWS1257:
2865 case IDC_ENCODING_ISO88593:
2866 case IDC_ENCODING_ISO885910:
2867 case IDC_ENCODING_ISO885914:
2868 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572869 case IDC_ENCODING_WINDOWS1254:
2870 case IDC_ENCODING_ISO88596:
2871 case IDC_ENCODING_WINDOWS1256:
2872 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002873 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572874 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282875 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572876
[email protected]84214982008-12-10 18:49:102877 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282878 case IDC_CUT: Cut(); break;
2879 case IDC_COPY: Copy(); break;
2880 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102881
2882 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282883 case IDC_FIND: Find(); break;
2884 case IDC_FIND_NEXT: FindNext(); break;
2885 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102886
2887 // Zoom
[email protected]54087fe2011-10-28 22:02:482888 case IDC_ZOOM_PLUS: Zoom(content::PAGE_ZOOM_IN); break;
2889 case IDC_ZOOM_NORMAL: Zoom(content::PAGE_ZOOM_RESET); break;
2890 case IDC_ZOOM_MINUS: Zoom(content::PAGE_ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102891
2892 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282893 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2894 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2895 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522896 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372897 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
[email protected]83548a42010-06-18 13:53:372898 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2899 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102900
2901 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282902 case IDC_OPEN_FILE: OpenFile(); break;
2903 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482904 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2905 DEVTOOLS_TOGGLE_ACTION_NONE);
2906 break;
2907 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2908 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2909 break;
2910 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2911 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2912 break;
[email protected]adb6a84d2011-02-07 16:58:402913 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2914 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]daa9e382012-01-06 00:30:342915 case IDC_FEEDBACK: OpenFeedbackDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492916
[email protected]cb84d642010-06-10 00:56:282917 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252918 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492919
[email protected]cb84d642010-06-10 00:56:282920 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2921 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]7d2d08152011-10-25 22:58:472922 case IDC_SHOW_AVATAR_MENU: ShowAvatarMenu(); break;
[email protected]cb84d642010-06-10 00:56:282923 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2924 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2925 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
[email protected]cb84d642010-06-10 00:56:282926 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052927 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282928 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2929 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2930 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412931 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2932 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052933 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]202802e42011-07-06 11:40:462934 case IDC_HELP_PAGE: ShowHelpTab(); break;
[email protected]713d01b2012-03-24 05:58:202935 case IDC_SHOW_SYNC_SETUP: ShowSyncSetup(SyncPromoUI::SOURCE_MENU);
2936 break;
[email protected]afcb43562011-09-02 23:33:382937 case IDC_TOGGLE_SPEECH_INPUT: ToggleSpeechInput(); break;
[email protected]d938aed92009-01-22 19:49:332938
[email protected]36b6dcb2008-11-12 01:19:572939 default:
[email protected]84214982008-12-10 18:49:102940 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272941 break;
[email protected]36b6dcb2008-11-12 01:19:572942 }
2943}
2944
[email protected]92655362012-04-20 21:33:172945////////////////////////////////////////////////////////////////////////////////
2946// Browser, TabRestoreServiceObserver:
2947
2948void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
2949 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
2950 !service->entries().empty());
2951}
2952
2953void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
2954 if (!tab_restore_service_)
2955 return;
2956
2957 DCHECK_EQ(tab_restore_service_, service);
2958 tab_restore_service_->RemoveObserver(this);
2959 tab_restore_service_ = NULL;
2960}
2961
2962// Centralized method for creating a TabContentsWrapper, configuring and
2963// installing all its supporting objects and observers.
2964TabContentsWrapper* Browser::TabContentsFactory(
2965 Profile* profile,
2966 SiteInstance* site_instance,
2967 int routing_id,
2968 const WebContents* base_web_contents,
2969 content::SessionStorageNamespace* session_storage_namespace) {
2970 WebContents* new_contents = WebContents::Create(
2971 profile, site_instance, routing_id, base_web_contents,
2972 session_storage_namespace);
2973 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
2974 return wrapper;
2975}
2976
[email protected]485fba42009-03-24 23:27:292977///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572978// Browser, TabStripModelDelegate implementation:
2979
[email protected]3c9e1872010-11-18 16:17:492980TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582981 return AddBlankTabAt(-1, foreground);
2982}
2983
[email protected]3c9e1872010-11-18 16:17:492984TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052985 // Time new tab page creation time. We keep track of the timing data in
[email protected]075969d2012-04-17 20:05:552986 // WebContents, but we want to include the time it takes to create the
2987 // WebContents object too.
[email protected]3f8eb7f2009-10-02 23:58:052988 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332989 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
[email protected]2905f742011-10-13 03:51:582990 content::PAGE_TRANSITION_TYPED);
[email protected]616381f02010-11-02 15:15:332991 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2992 params.tabstrip_index = index;
2993 browser::Navigate(&params);
[email protected]d9083482012-01-06 00:38:462994 params.target_contents->web_contents()->SetNewTabStartTime(
[email protected]3c9e1872010-11-18 16:17:492995 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332996 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052997}
2998
[email protected]3c9e1872010-11-18 16:17:492999Browser* Browser::CreateNewStripWithContents(
3000 TabContentsWrapper* detached_contents,
3001 const gfx::Rect& window_bounds,
3002 const DockInfo& dock_info,
3003 bool maximize) {
[email protected]018cf362010-05-05 22:43:223004 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:063005
[email protected]5e495462008-11-20 23:07:413006 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:413007 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
3008 dock_info.AdjustOtherWindowBounds();
3009
[email protected]36b6dcb2008-11-12 01:19:573010 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:143011 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:413012 browser->set_override_bounds(new_window_bounds);
[email protected]400eaf82011-08-22 15:47:393013 browser->set_show_state(
3014 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
[email protected]9800de5e2011-03-11 18:19:493015 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:053016 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:273017 // Make sure the loading state is updated correctly, otherwise the throbber
3018 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:333019 browser->LoadingStateChanged(detached_contents->web_contents());
[email protected]3d1104f2009-03-26 15:30:283020 return browser;
[email protected]36b6dcb2008-11-12 01:19:573021}
3022
3023int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:403024 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
3025 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:573026}
3027
[email protected]3c9e1872010-11-18 16:17:493028TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]3ebe558b2011-12-06 08:05:083029 const GURL& url, const content::Referrer& referrer, Profile* profile,
[email protected]2905f742011-10-13 03:51:583030 content::PageTransition transition, bool defer_load,
[email protected]36b6dcb2008-11-12 01:19:573031 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:493032 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:403033 MSG_ROUTING_NONE,
[email protected]bb81f382012-01-03 22:45:443034 GetSelectedWebContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:573035 if (!defer_load) {
3036 // Load the initial URL before adding the new tab contents to the tab strip
3037 // so that the tab contents has navigation state.
[email protected]d9083482012-01-06 00:38:463038 contents->web_contents()->GetController().LoadURL(
[email protected]4a63e242011-12-12 15:23:083039 url, referrer, transition, std::string());
[email protected]36b6dcb2008-11-12 01:19:573040 }
3041
3042 return contents;
3043}
3044
3045bool Browser::CanDuplicateContentsAt(int index) {
[email protected]c5eed492012-01-04 17:07:503046 NavigationController& nc = GetWebContentsAt(index)->GetController();
[email protected]fbc5e5f92012-01-02 06:08:323047 return nc.GetWebContents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:573048}
3049
3050void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:493051 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:333052 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:123053 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:563054
3055 bool pinned = false;
3056 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
3057 // If this is a tabbed browser, just create a duplicate tab inside the same
3058 // window next to the tab being duplicated.
[email protected]2fc15ae2012-05-06 00:01:373059 int index = tab_strip_model_->GetIndexOfTabContents(contents);
[email protected]41f022e2012-01-31 05:56:403060 pinned = IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:413061 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:563062 TabStripModel::ADD_INHERIT_GROUP |
3063 (pinned ? TabStripModel::ADD_PINNED : 0);
[email protected]2fc15ae2012-05-06 00:01:373064 tab_strip_model_->InsertTabContentsAt(index + 1, contents_dupe, add_types);
[email protected]47b309f2010-12-28 17:35:563065 } else {
3066 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:143067 if (is_app()) {
3068 CHECK(!is_type_popup());
3069 CHECK(!is_type_panel());
[email protected]da22aa62012-04-04 18:54:353070 browser = Browser::CreateWithParams(
3071 Browser::CreateParams::CreateForApp(
3072 TYPE_POPUP, app_name_, gfx::Rect(),profile_));
[email protected]b35b26b32011-05-05 20:35:143073 } else if (is_type_popup()) {
[email protected]da22aa62012-04-04 18:54:353074 browser = Browser::CreateWithParams(
3075 Browser::CreateParams(TYPE_POPUP, profile_));
[email protected]47b309f2010-12-28 17:35:563076 }
3077
3078 // Preserve the size of the original window. The new window has already
3079 // been given an offset by the OS, so we shouldn't copy the old bounds.
3080 BrowserWindow* new_window = browser->window();
3081 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
3082 window()->GetRestoredBounds().size()));
3083
[email protected]4e595682011-02-09 17:07:023084 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]075969d2012-04-17 20:05:553085 // WebContents is invisible and won't size it.
[email protected]47b309f2010-12-28 17:35:563086 browser->window()->Show();
3087
3088 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:583089 browser->AddTab(contents_dupe, content::PAGE_TRANSITION_LINK);
[email protected]47b309f2010-12-28 17:35:563090 }
3091
[email protected]92371eb2011-04-28 11:50:153092 SessionService* session_service =
3093 SessionServiceFactory::GetForProfileIfExisting(profile_);
3094 if (session_service)
[email protected]81898992011-06-14 22:15:003095 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:573096}
3097
[email protected]36b6dcb2008-11-12 01:19:573098void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:473099#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:573100 // This is scheduled to run after we return to the message loop because
3101 // otherwise the frame will think the drag session is still active and ignore
3102 // the request.
[email protected]d6a3c772009-01-27 19:41:203103 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:373104 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363105 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]d6a3c772009-01-27 19:41:203106#endif
initial.commit09911bf2008-07-26 23:55:293107}
3108
[email protected]3c9e1872010-11-18 16:17:493109void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:583110 // We don't create historical tabs for incognito windows or windows without
3111 // profiles.
[email protected]92371eb2011-04-28 11:50:153112 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:583113 return;
[email protected]92371eb2011-04-28 11:50:153114
[email protected]0d4ef7f2011-05-12 22:38:573115 // We don't create historical tabs for print preview tabs.
[email protected]d9083482012-01-06 00:38:463116 if (contents->web_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
[email protected]0d4ef7f2011-05-12 22:38:573117 return;
3118
[email protected]92371eb2011-04-28 11:50:153119 TabRestoreService* service =
3120 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:583121
[email protected]fb5ff422010-05-03 20:46:103122 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:153123 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
[email protected]d9083482012-01-06 00:38:463124 service->CreateHistoricalTab(&contents->web_contents()->GetController(),
[email protected]2fc15ae2012-05-06 00:01:373125 tab_strip_model_->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:583126 }
3127}
3128
[email protected]3c9e1872010-11-18 16:17:493129bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
[email protected]d9083482012-01-06 00:38:463130 return Browser::RunUnloadEventsHelper(contents->web_contents());
[email protected]505323e22009-01-24 02:47:583131}
3132
[email protected]2db5a2042011-04-26 17:13:473133bool Browser::CanCloseContents(std::vector<int>* indices) {
3134 DCHECK(!indices->empty());
3135 TabCloseableStateWatcher* watcher =
3136 g_browser_process->tab_closeable_state_watcher();
3137 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
3138 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:043139 return false;
[email protected]2db5a2042011-04-26 17:13:473140 // Now, handle cases where at least one tab can be closed.
3141 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:103142 // in-progress downloads.
3143 // Note that the next call when it returns false will ask the user for
3144 // confirmation before closing the browser if the user decides so.
[email protected]41f022e2012-01-31 05:56:403145 if (tab_count() == static_cast<int>(indices->size()) &&
[email protected]2db5a2042011-04-26 17:13:473146 !CanCloseWithInProgressDownloads()) {
3147 indices->clear();
3148 can_close_all = false;
3149 }
3150 return can_close_all;
[email protected]940ccb22009-04-30 17:11:103151}
[email protected]d6a3c772009-01-27 19:41:203152
[email protected]a206b442009-10-08 23:20:203153bool Browser::CanBookmarkAllTabs() const {
3154 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:583155 return (model && model->IsLoaded()) &&
3156 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:043157 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:203158}
3159
[email protected]b3ac5c82009-10-08 20:56:543160void Browser::BookmarkAllTabs() {
[email protected]9d603392011-11-18 05:45:283161 BookmarkEditor::ShowBookmarkAllTabsDialog(this);
[email protected]b3ac5c82009-10-08 20:56:543162}
3163
[email protected]0b4d3382010-07-14 16:13:043164bool Browser::CanCloseTab() const {
3165 TabCloseableStateWatcher* watcher =
3166 g_browser_process->tab_closeable_state_watcher();
3167 return !watcher || watcher->CanCloseTab(this);
3168}
3169
[email protected]92655362012-04-20 21:33:173170bool Browser::CanRestoreTab() {
3171 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
3172}
3173
3174void Browser::RestoreTab() {
3175 content::RecordAction(UserMetricsAction("RestoreTab"));
3176 TabRestoreService* service =
3177 TabRestoreServiceFactory::GetForProfile(profile_);
3178 if (!service)
3179 return;
3180
3181 service->RestoreMostRecentEntry(tab_restore_service_delegate());
3182}
3183
[email protected]b283a7532010-08-12 21:24:593184bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:443185 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
3186 // for those windows, we already have a big icon in the top-left outside any
3187 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:333188 return true;
[email protected]b283a7532010-08-12 21:24:593189}
3190
[email protected]2d46c842008-11-14 19:24:313191///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573192// Browser, TabStripModelObserver implementation:
3193
[email protected]3c9e1872010-11-18 16:17:493194void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573195 int index,
3196 bool foreground) {
[email protected]9219d262011-02-15 21:05:123197 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:003198 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:583199
[email protected]c37e3b62010-01-22 00:15:173200 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:573201
[email protected]159f7762008-12-19 14:58:273202 // Make sure the loading state is updated correctly, otherwise the throbber
3203 // won't start if the page is loading.
[email protected]2a6bc3e2011-12-28 23:51:333204 LoadingStateChanged(contents->web_contents());
[email protected]159f7762008-12-19 14:58:273205
[email protected]36b6dcb2008-11-12 01:19:573206 // If the tab crashes in the beforeunload or unload handler, it won't be
3207 // able to ack. But we know we can close it.
[email protected]fbc5e5f92012-01-02 06:08:323208 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
3209 content::Source<WebContents>(contents->web_contents()));
[email protected]93f230e02011-06-01 14:40:003210
[email protected]432115822011-07-10 15:52:273211 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:323212 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:503213
3214 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]fbc5e5f92012-01-02 06:08:323215 content::Source<WebContents>(contents->web_contents()));
[email protected]36b6dcb2008-11-12 01:19:573216}
3217
[email protected]f2cc7382010-10-15 18:03:053218void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:493219 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:053220 int index) {
[email protected]d9083482012-01-06 00:38:463221 fullscreen_controller_->OnTabClosing(contents->web_contents());
[email protected]ad50def52011-10-19 23:17:073222 content::NotificationService::current()->Notify(
[email protected]884033e2012-04-16 19:38:423223 chrome::NOTIFICATION_TAB_CLOSING,
[email protected]c5eed492012-01-04 17:07:503224 content::Source<NavigationController>(
[email protected]cca0f1e2012-01-03 18:27:463225 &contents->web_contents()->GetController()),
[email protected]ad50def52011-10-19 23:17:073226 content::NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:573227
[email protected]075969d2012-04-17 20:05:553228 // Sever the WebContents' connection back to us.
[email protected]9219d262011-02-15 21:05:123229 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:573230}
3231
[email protected]3c9e1872010-11-18 16:17:493232void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:173233 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:573234}
3235
[email protected]9ac8a242011-06-07 19:42:523236void Browser::TabDeactivated(TabContentsWrapper* contents) {
[email protected]01a5a762011-11-21 05:40:553237 fullscreen_controller_->OnTabDeactivated(contents);
[email protected]6b723f82010-10-05 20:14:273238 if (instant())
[email protected]3e481282011-10-15 15:39:503239 instant()->Hide();
[email protected]03bb953d2010-09-14 21:38:303240
[email protected]85ff2c42009-05-29 21:22:033241 // Save what the user's currently typing, so it can be restored when we
3242 // switch back to this tab.
[email protected]83a2610a2012-01-05 01:00:273243 window_->GetLocationBar()->SaveStateToContents(contents->web_contents());
[email protected]85ff2c42009-05-29 21:22:033244}
3245
[email protected]3aca95d42011-05-24 22:06:543246void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
3247 TabContentsWrapper* new_contents,
3248 int index,
3249 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:163250 // On some platforms we want to automatically reload tabs that are
3251 // killed when the user selects them.
[email protected]9d7518f2012-04-17 02:15:203252 bool did_reload = false;
[email protected]d9083482012-01-06 00:38:463253 if (user_gesture && new_contents->web_contents()->GetCrashedStatus() ==
[email protected]a8f024392011-01-13 21:50:163254 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
3255 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:563256 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]734d26692012-03-26 18:00:253257 LOG(WARNING) << "Reloading killed tab at " << index;
[email protected]d6d4dae2012-04-18 17:47:323258 static int reload_count = 0;
[email protected]24c463a2012-04-20 22:33:503259 UMA_HISTOGRAM_CUSTOM_COUNTS(
3260 "Tabs.SadTab.ReloadCount", ++reload_count, 1, 1000, 50);
[email protected]a8f024392011-01-13 21:50:163261 Reload(CURRENT_TAB);
[email protected]9d7518f2012-04-17 02:15:203262 did_reload = true;
[email protected]f8a35772011-02-02 23:17:563263 }
[email protected]a8f024392011-01-13 21:50:163264 }
3265
[email protected]002efb042011-10-07 17:30:243266 // Discarded tabs always get reloaded.
[email protected]9d7518f2012-04-17 02:15:203267 if (!did_reload && IsTabDiscarded(index)) {
[email protected]d6d4dae2012-04-18 17:47:323268 LOG(WARNING) << "Reloading discarded tab at " << index;
3269 static int reload_count = 0;
[email protected]24c463a2012-04-20 22:33:503270 UMA_HISTOGRAM_CUSTOM_COUNTS(
3271 "Tabs.Discard.ReloadCount", ++reload_count, 1, 1000, 50);
[email protected]002efb042011-10-07 17:30:243272 Reload(CURRENT_TAB);
[email protected]002efb042011-10-07 17:30:243273 }
3274
[email protected]36b6dcb2008-11-12 01:19:573275 // If we have any update pending, do it now.
[email protected]24f1477532011-11-22 22:55:363276 if (chrome_updater_factory_.HasWeakPtrs() && old_contents)
[email protected]36b6dcb2008-11-12 01:19:573277 ProcessPendingUIUpdates();
3278
[email protected]36b6dcb2008-11-12 01:19:573279 // Propagate the profile to the location bar.
3280 UpdateToolbar(true);
3281
[email protected]943d8122010-06-11 02:13:453282 // Update reload/stop state.
[email protected]d9083482012-01-06 00:38:463283 UpdateReloadStopState(new_contents->web_contents()->IsLoading(), true);
[email protected]36b6dcb2008-11-12 01:19:573284
[email protected]84214982008-12-10 18:49:103285 // Update commands to reflect current state.
3286 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:573287
3288 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:103289 StatusBubble* status_bubble = GetStatusBubble();
3290 if (status_bubble) {
3291 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:573292
[email protected]be3877f2009-01-14 15:51:103293 // Show the loading state (if any).
[email protected]51d83bdf2011-12-09 16:09:293294 status_bubble->SetStatus(
3295 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:103296 }
[email protected]36b6dcb2008-11-12 01:19:573297
[email protected]24db8a072009-10-29 20:35:373298 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:243299 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:173300 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:583301 }
3302
[email protected]36b6dcb2008-11-12 01:19:573303 // Update sessions. Don't force creation of sessions. If sessions doesn't
3304 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:153305 SessionService* session_service =
3306 SessionServiceFactory::GetForProfileIfExisting(profile_);
[email protected]2fc15ae2012-05-06 00:01:373307 if (session_service && !tab_strip_model_->closing_all()) {
[email protected]41f022e2012-01-31 05:56:403308 session_service->SetSelectedTabInWindow(session_id(), active_index());
[email protected]36b6dcb2008-11-12 01:19:573309 }
[email protected]09b29342011-06-24 19:18:483310
3311 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:573312}
3313
[email protected]3c9e1872010-11-18 16:17:493314void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573315 int from_index,
[email protected]1a242c32010-02-02 21:20:543316 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:573317 DCHECK(from_index >= 0 && to_index >= 0);
3318 // Notify the history service.
3319 SyncHistoryWithTabs(std::min(from_index, to_index));
3320}
3321
[email protected]da25dd52011-01-11 19:06:303322void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
3323 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:493324 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:433325 int index) {
[email protected]c37e3b62010-01-22 00:15:173326 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
[email protected]41f022e2012-01-31 05:56:403327 TabInsertedAt(new_contents, index, (index == active_index()));
[email protected]c37e3b62010-01-22 00:15:173328
[email protected]a26023822011-12-29 00:23:553329 int entry_count =
[email protected]d9083482012-01-06 00:38:463330 new_contents->web_contents()->GetController().GetEntryCount();
[email protected]c37e3b62010-01-22 00:15:173331 if (entry_count > 0) {
3332 // Send out notification so that observers are updated appropriately.
[email protected]d9083482012-01-06 00:38:463333 new_contents->web_contents()->GetController().NotifyEntryChanged(
3334 new_contents->web_contents()->GetController().GetEntryAtIndex(
[email protected]4a63e242011-12-12 15:23:083335 entry_count - 1),
[email protected]c37e3b62010-01-22 00:15:173336 entry_count - 1);
3337 }
[email protected]47e020a2010-10-15 14:43:373338
[email protected]92371eb2011-04-28 11:50:153339 SessionService* session_service =
3340 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:373341 if (session_service) {
3342 // The new_contents may end up with a different navigation stack. Force
3343 // the session service to update itself.
[email protected]41f022e2012-01-31 05:56:403344 session_service->TabRestored(new_contents, IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373345 }
[email protected]2914600d2011-01-31 23:25:143346
[email protected]a0262432012-04-13 15:48:093347 content::DevToolsManager::GetInstance()->ContentsReplaced(
[email protected]d9083482012-01-06 00:38:463348 old_contents->web_contents(), new_contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:173349}
3350
[email protected]3c9e1872010-11-18 16:17:493351void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153352 SessionService* session_service =
3353 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093354 if (session_service) {
3355 session_service->SetPinnedState(
3356 session_id(),
[email protected]81898992011-06-14 22:15:003357 GetTabContentsWrapperAt(index)->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:403358 IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093359 }
3360}
3361
[email protected]36b6dcb2008-11-12 01:19:573362void Browser::TabStripEmpty() {
3363 // Close the frame after we return to the message loop (not immediately,
3364 // otherwise it will destroy this object before the stack has a chance to
3365 // cleanly unwind.)
3366 // Note: This will be called several times if TabStripEmpty is called several
3367 // times. This is because it does not close the window if tabs are
3368 // still present.
3369 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3370 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373371 MessageLoop::current()->PostTask(
[email protected]24f1477532011-11-22 22:55:363372 FROM_HERE, base::Bind(&Browser::CloseFrame, weak_factory_.GetWeakPtr()));
[email protected]49d864f2012-04-09 21:14:393373 // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not
3374 // attempt to add tabs to the browser before it closes.
3375 is_attempting_to_close_browser_ = true;
[email protected]36b6dcb2008-11-12 01:19:573376}
3377
[email protected]92655362012-04-20 21:33:173378void Browser::OnAcceptFullscreenPermission(
3379 const GURL& url,
3380 FullscreenExitBubbleType bubble_type) {
3381 fullscreen_controller_->OnAcceptFullscreenPermission(url, bubble_type);
3382}
3383
3384void Browser::OnDenyFullscreenPermission(FullscreenExitBubbleType bubble_type) {
3385 fullscreen_controller_->OnDenyFullscreenPermission(bubble_type);
3386}
3387
3388bool Browser::TabsNeedBeforeUnloadFired() {
3389 if (tabs_needing_before_unload_fired_.empty()) {
3390 for (int i = 0; i < tab_count(); ++i) {
3391 WebContents* contents = GetTabContentsWrapperAt(i)->web_contents();
3392 if (contents->NeedToFireBeforeUnload())
3393 tabs_needing_before_unload_fired_.insert(contents);
3394 }
3395 }
3396 return !tabs_needing_before_unload_fired_.empty();
3397}
3398
3399bool Browser::IsFullscreenForTabOrPending() const {
3400 return fullscreen_controller_->IsFullscreenForTabOrPending();
3401}
3402
[email protected]d013f142012-04-27 17:31:143403bool Browser::IsMouseLocked() const {
3404 return fullscreen_controller_->IsMouseLocked();
[email protected]92655362012-04-20 21:33:173405}
3406
3407void Browser::OnWindowDidShow() {
3408 if (window_has_shown_)
3409 return;
3410 window_has_shown_ = true;
3411
3412 // Nothing to do for non-tabbed windows.
3413 if (!is_type_tabbed())
3414 return;
3415
3416 // Show any pending global error bubble.
3417 GlobalErrorService* service =
3418 GlobalErrorServiceFactory::GetForProfile(profile());
3419 GlobalError* error = service->GetFirstGlobalErrorWithBubbleView();
3420 if (error)
3421 error->ShowBubbleView(this);
3422}
3423
3424void Browser::ShowFirstRunBubble() {
3425 window()->GetLocationBar()->ShowFirstRunBubble();
3426}
3427
3428///////////////////////////////////////////////////////////////////////////////
3429// Browser, protected:
3430
3431BrowserWindow* Browser::CreateBrowserWindow() {
3432 bool create_panel = false;
3433#if defined(USE_ASH)
3434 if (CommandLine::ForCurrentProcess()->HasSwitch(
3435 ash::switches::kAuraPanelManager))
3436 create_panel = is_type_panel();
3437#elif !defined(OS_CHROMEOS)
3438 create_panel = is_type_panel();
3439#endif
3440 if (create_panel)
3441 return PanelManager::GetInstance()->CreatePanel(this);
3442
3443 return BrowserWindow::CreateBrowserWindow(this);
3444}
3445
[email protected]36b6dcb2008-11-12 01:19:573446///////////////////////////////////////////////////////////////////////////////
[email protected]674bc592011-12-20 23:00:423447// Browser, content::WebContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293448
[email protected]e5d549d2011-12-28 01:29:203449WebContents* Browser::OpenURLFromTab(WebContents* source,
[email protected]00c37fc2011-08-02 00:22:503450 const OpenURLParams& params) {
3451 browser::NavigateParams nav_params(this, params.url, params.transition);
[email protected]41f022e2012-01-31 05:56:403452 nav_params.source_contents = GetTabContentsWrapperAt(
[email protected]2fc15ae2012-05-06 00:01:373453 tab_strip_model_->GetWrapperIndex(source));
[email protected]cb8fb01a2011-12-05 21:01:143454 nav_params.referrer = params.referrer;
[email protected]00c37fc2011-08-02 00:22:503455 nav_params.disposition = params.disposition;
3456 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
3457 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
3458 nav_params.user_gesture = true;
3459 nav_params.override_encoding = params.override_encoding;
[email protected]e47ae9472011-10-13 19:48:343460 nav_params.is_renderer_initiated = params.is_renderer_initiated;
[email protected]4ad5d77d2011-12-03 02:00:483461 nav_params.transferred_global_request_id =
3462 params.transferred_global_request_id;
[email protected]00c37fc2011-08-02 00:22:503463 browser::Navigate(&nav_params);
3464
3465 return nav_params.target_contents ?
[email protected]d9083482012-01-06 00:38:463466 nav_params.target_contents->web_contents() : NULL;
initial.commit09911bf2008-07-26 23:55:293467}
3468
[email protected]2a6bc3e2011-12-28 23:51:333469void Browser::NavigationStateChanged(const WebContents* source,
initial.commit09911bf2008-07-26 23:55:293470 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293471 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403472 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293473 ScheduleUIUpdate(source, changed_flags);
3474
[email protected]83c2e232011-10-07 21:36:463475 // We can synchronously update commands since they will only change once per
3476 // navigation, so we don't have to worry about flickering. We do, however,
3477 // need to update the command state early on load to always present usable
3478 // actions in the face of slow-to-commit pages.
[email protected]d9083482012-01-06 00:38:463479 if (changed_flags & (content::INVALIDATE_TYPE_URL |
3480 content::INVALIDATE_TYPE_LOAD))
[email protected]84214982008-12-10 18:49:103481 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293482}
3483
[email protected]2a6bc3e2011-12-28 23:51:333484void Browser::AddNewContents(WebContents* source,
3485 WebContents* new_contents,
initial.commit09911bf2008-07-26 23:55:293486 WindowOpenDisposition disposition,
3487 const gfx::Rect& initial_pos,
3488 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373489 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333490 DCHECK(disposition != SAVE_TO_DISK);
3491 // Can't create a new contents for the current tab - invalid case.
3492 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293493
[email protected]e7cfdbd2011-04-22 14:41:373494 TabContentsWrapper* source_wrapper = NULL;
3495 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453496 TabContentsWrapper* new_wrapper =
3497 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
[email protected]2a6bc3e2011-12-28 23:51:333498 if (!new_wrapper) {
[email protected]d9083482012-01-06 00:38:463499 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]2a6bc3e2011-12-28 23:51:333500 }
[email protected]e7cfdbd2011-04-22 14:41:373501 if (source) {
3502 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3503 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3504 }
3505
3506 if (source_wrapper) {
3507 // Handle blocking of all contents.
3508 if (source_blocked_content->all_contents_blocked()) {
3509 source_blocked_content->AddTabContents(new_wrapper,
3510 disposition,
[email protected]9e4ae3d2012-03-27 01:05:463511 initial_pos,
[email protected]e7cfdbd2011-04-22 14:41:373512 user_gesture);
3513 return;
3514 }
3515
3516 // Handle blocking of popups.
3517 if ((disposition == NEW_POPUP) && !user_gesture &&
3518 !CommandLine::ForCurrentProcess()->HasSwitch(
3519 switches::kDisablePopupBlocking)) {
3520 // Unrequested popups from normal pages are constrained unless they're in
3521 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363522 GetConstrainingContentsWrapper(source_wrapper)->
3523 blocked_content_tab_helper()->
[email protected]9e4ae3d2012-03-27 01:05:463524 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373525 return;
3526 }
3527
[email protected]151a63d2011-12-20 22:32:523528 new_contents->GetRenderViewHost()->DisassociateFromPopupCount();
[email protected]e7cfdbd2011-04-22 14:41:373529 }
3530
[email protected]e7cfdbd2011-04-22 14:41:373531 browser::NavigateParams params(this, new_wrapper);
[email protected]2fc15ae2012-05-06 00:01:373532 params.source_contents = source ?
3533 GetTabContentsWrapperAt(tab_strip_model_->GetWrapperIndex(source)): NULL;
[email protected]3c9e1872010-11-18 16:17:493534 params.disposition = disposition;
[email protected]9e4ae3d2012-03-27 01:05:463535 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353536 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3537 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493538 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293539}
3540
[email protected]2a6bc3e2011-12-28 23:51:333541void Browser::ActivateContents(WebContents* contents) {
[email protected]2fc15ae2012-05-06 00:01:373542 ActivateTabAt(tab_strip_model_->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393543 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293544}
3545
[email protected]2a6bc3e2011-12-28 23:51:333546void Browser::DeactivateContents(WebContents* contents) {
[email protected]ea42e7782010-08-23 23:58:123547 window_->Deactivate();
3548}
3549
[email protected]2a6bc3e2011-12-28 23:51:333550void Browser::LoadingStateChanged(WebContents* source) {
[email protected]2fc15ae2012-05-06 00:01:373551 window_->UpdateLoadingAnimations(tab_strip_model_->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393552 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293553
[email protected]4ca15302012-01-03 05:53:203554 WebContents* selected_contents = GetSelectedWebContents();
[email protected]3c9e1872010-11-18 16:17:493555 if (source == selected_contents) {
[email protected]f5d978c2011-07-21 14:43:513556 bool is_loading = source->IsLoading();
3557 UpdateReloadStopState(is_loading, false);
[email protected]43d259d2010-09-03 21:37:463558 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443559 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:293560 GetSelectedTabContentsWrapper()->core_tab_helper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463561 }
[email protected]eabfdae92009-12-11 06:13:513562
[email protected]f5d978c2011-07-21 14:43:513563 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333564 // Schedule a shortcut update when web application info is available if
3565 // last committed entry is not NULL. Last committed entry could be NULL
3566 // when an interstitial page is injected (e.g. bad https certificate,
3567 // malware site etc). When this happens, we abort the shortcut update.
[email protected]10f417c52011-12-28 21:04:233568 NavigationEntry* entry = source->GetController().GetLastCommittedEntry();
[email protected]eabfdae92009-12-11 06:13:513569 if (entry) {
[email protected]553602e12011-04-05 17:01:183570 TabContentsWrapper::GetCurrentWrapperForContents(source)->
[email protected]36fc0392011-12-25 03:59:513571 extension_tab_helper()->GetApplicationInfo(entry->GetPageID());
[email protected]eabfdae92009-12-11 06:13:513572 } else {
3573 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513574 }
3575 }
initial.commit09911bf2008-07-26 23:55:293576 }
3577}
3578
[email protected]a81343d232011-12-27 07:39:203579void Browser::CloseContents(WebContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473580 if (is_attempting_to_close_browser_) {
3581 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063582 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473583 // will go down the slow shutdown path instead of the fast path of killing
3584 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213585 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473586 return;
3587 }
3588
[email protected]2fc15ae2012-05-06 00:01:373589 int index = tab_strip_model_->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293590 if (index == TabStripModel::kNoTab) {
3591 NOTREACHED() << "CloseContents called for tab not in our strip";
3592 return;
3593 }
[email protected]2fc15ae2012-05-06 00:01:373594 tab_strip_model_->CloseTabContentsAt(index,
[email protected]0cce15f2010-05-21 16:58:393595 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293596}
3597
[email protected]2a6bc3e2011-12-28 23:51:333598void Browser::MoveContents(WebContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143599 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293600 NOTREACHED() << "moving invalid browser type";
3601 return;
3602 }
[email protected]e561e202010-03-24 17:57:123603 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293604}
3605
[email protected]2a6bc3e2011-12-28 23:51:333606void Browser::DetachContents(WebContents* source) {
[email protected]2fc15ae2012-05-06 00:01:373607 int index = tab_strip_model_->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313608 if (index >= 0)
[email protected]2fc15ae2012-05-06 00:01:373609 tab_strip_model_->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313610}
3611
[email protected]2a6bc3e2011-12-28 23:51:333612bool Browser::IsPopupOrPanel(const WebContents* source) const {
initial.commit09911bf2008-07-26 23:55:293613 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143614 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293615}
3616
[email protected]92655362012-04-20 21:33:173617bool Browser::CanReloadContents(WebContents* source) const {
3618 return !is_devtools();
[email protected]36b6dcb2008-11-12 01:19:573619}
3620
[email protected]2a6bc3e2011-12-28 23:51:333621void Browser::UpdateTargetURL(WebContents* source, int32 page_id,
[email protected]d952a052011-09-06 18:42:453622 const GURL& url) {
[email protected]be3877f2009-01-14 15:51:103623 if (!GetStatusBubble())
3624 return;
3625
[email protected]4ca15302012-01-03 05:53:203626 if (source == GetSelectedWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:573627 PrefService* prefs = profile_->GetPrefs();
[email protected]65233052011-08-22 19:02:483628 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
[email protected]36b6dcb2008-11-12 01:19:573629 }
3630}
3631
[email protected]92655362012-04-20 21:33:173632void Browser::ContentsMouseEvent(
3633 WebContents* source, const gfx::Point& location, bool motion) {
3634 if (!GetStatusBubble())
3635 return;
3636
3637 if (source == GetSelectedWebContents()) {
3638 GetStatusBubble()->MouseMoved(location, !motion);
3639 if (!motion)
3640 GetStatusBubble()->SetURL(GURL(), std::string());
3641 }
[email protected]3a6a3b62009-05-27 21:36:203642}
3643
[email protected]36b6dcb2008-11-12 01:19:573644void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253645 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573646}
3647
[email protected]2a6bc3e2011-12-28 23:51:333648void Browser::WebContentsFocused(WebContents* contents) {
3649 window_->WebContentsFocused(contents);
[email protected]7e383692009-06-12 19:14:543650}
3651
[email protected]130efb02009-09-18 18:54:353652bool Browser::TakeFocus(bool reverse) {
[email protected]ad50def52011-10-19 23:17:073653 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273654 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
[email protected]6c2381d2011-10-19 02:52:533655 content::Source<Browser>(this),
[email protected]ad50def52011-10-19 23:17:073656 content::NotificationService::NoDetails());
[email protected]130efb02009-09-18 18:54:353657 return false;
3658}
3659
[email protected]36b6dcb2008-11-12 01:19:573660bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143661 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573662}
3663
[email protected]2a6bc3e2011-12-28 23:51:333664void Browser::ConvertContentsToApplication(WebContents* contents) {
[email protected]36fc0392011-12-25 03:59:513665 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
[email protected]57ecc4b2010-08-11 03:02:513666 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573667
[email protected]b6c874582009-05-08 19:38:313668 DetachContents(contents);
[email protected]da22aa62012-04-04 18:54:353669 Browser* app_browser = Browser::CreateWithParams(
3670 Browser::CreateParams::CreateForApp(
3671 TYPE_POPUP, app_name, gfx::Rect(), profile_));
[email protected]ae2f2a772011-05-04 16:30:273672 TabContentsWrapper* wrapper =
3673 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3674 if (!wrapper)
[email protected]d9083482012-01-06 00:38:463675 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323676 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3677
3678 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
[email protected]151a63d2011-12-20 22:32:523679 contents->GetRenderViewHost()->SyncRendererPrefs();
[email protected]75aef122010-12-06 21:48:323680 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573681}
3682
[email protected]b7a756d42012-01-23 18:08:173683gfx::Rect Browser::GetRootWindowResizerRect() const {
3684 return window_->GetRootWindowResizerRect();
3685}
3686
[email protected]2a6bc3e2011-12-28 23:51:333687void Browser::BeforeUnloadFired(WebContents* tab,
[email protected]36b6dcb2008-11-12 01:19:573688 bool proceed,
3689 bool* proceed_to_fire_unload) {
3690 if (!is_attempting_to_close_browser_) {
3691 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393692 if (!proceed)
[email protected]0bfbf882011-12-22 18:19:273693 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573694 return;
3695 }
3696
3697 if (!proceed) {
3698 CancelWindowClose();
3699 *proceed_to_fire_unload = false;
[email protected]0bfbf882011-12-22 18:19:273700 tab->SetClosedByUserGesture(false);
[email protected]36b6dcb2008-11-12 01:19:573701 return;
3702 }
3703
[email protected]06b42f032008-12-03 18:43:053704 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313705 // Now that beforeunload has fired, put the tab on the queue to fire
3706 // unload.
[email protected]06b42f032008-12-03 18:43:053707 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573708 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063709 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573710 // fire all the beforeunload events before attempting to fire the unload
3711 // events should the user cancel closing the browser.
3712 *proceed_to_fire_unload = false;
3713 return;
3714 }
3715
3716 *proceed_to_fire_unload = true;
3717}
3718
[email protected]a26dc362010-04-23 01:48:583719void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133720 // Two differences between this and FocusLocationBar():
3721 // (1) This doesn't get recorded in user metrics, since it's called
3722 // internally.
3723 // (2) This checks whether the location bar can be focused, and if not, clears
3724 // the focus. FocusLocationBar() is only reached when the location bar is
3725 // focusable, but this may be reached at other times, e.g. while in
3726 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583727 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573728}
3729
[email protected]7d5925a2009-03-03 02:59:123730void Browser::RenderWidgetShowing() {
3731 window_->DisableInactiveFrame();
3732}
[email protected]a239c3f2009-02-17 22:13:193733
[email protected]0a2aeb82009-05-15 21:52:483734int Browser::GetExtraRenderViewHeight() const {
3735 return window_->GetExtraRenderViewHeight();
3736}
3737
[email protected]2a6bc3e2011-12-28 23:51:333738void Browser::OnStartDownload(WebContents* source,
[email protected]e582fdd2011-12-20 16:48:173739 content::DownloadItem* download) {
[email protected]686493142011-07-15 21:47:223740 TabContentsWrapper* wrapper =
3741 TabContentsWrapper::GetCurrentWrapperForContents(source);
3742 TabContentsWrapper* constrained = GetConstrainingContentsWrapper(wrapper);
3743 if (constrained != wrapper) {
3744 // Download in a constrained popup is shown in the tab that opened it.
[email protected]d9083482012-01-06 00:38:463745 WebContents* constrained_tab = constrained->web_contents();
[email protected]6934a702011-12-20 00:04:513746 constrained_tab->GetDelegate()->OnStartDownload(constrained_tab, download);
[email protected]686493142011-07-15 21:47:223747 return;
3748 }
3749
3750 if (!window())
3751 return;
3752
[email protected]a0e4b072011-08-17 01:47:073753 if (DisplayOldDownloadsUI()) {
[email protected]a0e4b072011-08-17 01:47:073754 // GetDownloadShelf creates the download shelf if it was not yet created.
3755 DownloadShelf* shelf = window()->GetDownloadShelf();
3756 shelf->AddDownload(new DownloadItemModel(download));
3757 // Don't show the animation for "Save file" downloads.
3758 // For non-theme extensions, we don't show the download animation.
3759 // Show animation in same window as the download shelf. Download shelf
3760 // may not be in the same window that initiated the download, e.g.
3761 // Panels.
3762 // Don't show the animation if the selected tab is not visible (i.e. the
3763 // window is minimized, we're in a unit test, etc.).
[email protected]bb81f382012-01-03 22:45:443764 WebContents* shelf_tab = shelf->browser()->GetSelectedWebContents();
[email protected]c09a8fd2011-11-21 19:54:503765 if ((download->GetTotalBytes() > 0) &&
[email protected]b0cfcee2011-10-27 03:55:373766 !ChromeDownloadManagerDelegate::IsExtensionDownload(download) &&
[email protected]a0e4b072011-08-17 01:47:073767 platform_util::IsVisible(shelf_tab->GetNativeView()) &&
3768 ui::Animation::ShouldRenderRichAnimation()) {
3769 DownloadStartedAnimation::Show(shelf_tab);
3770 }
[email protected]a0e4b072011-08-17 01:47:073771 }
[email protected]686493142011-07-15 21:47:223772
3773 // If the download occurs in a new tab, close it.
[email protected]f5fa20e2011-12-21 22:35:563774 if (source->GetController().IsInitialNavigation() && tab_count() > 1)
[email protected]686493142011-07-15 21:47:223775 CloseContents(source);
3776}
3777
[email protected]2a6bc3e2011-12-28 23:51:333778void Browser::ViewSourceForTab(WebContents* source, const GURL& page_url) {
[email protected]1788e772010-12-15 16:40:503779 DCHECK(source);
[email protected]41f022e2012-01-31 05:56:403780 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(
[email protected]2fc15ae2012-05-06 00:01:373781 tab_strip_model_->GetWrapperIndex(source));
[email protected]77d8d622010-12-15 10:30:123782 ViewSource(wrapper);
3783}
3784
[email protected]2a6bc3e2011-12-28 23:51:333785void Browser::ViewSourceForFrame(WebContents* source,
[email protected]932b7a12011-03-09 12:50:273786 const GURL& frame_url,
3787 const std::string& frame_content_state) {
3788 DCHECK(source);
[email protected]41f022e2012-01-31 05:56:403789 TabContentsWrapper* wrapper = GetTabContentsWrapperAt(
[email protected]2fc15ae2012-05-06 00:01:373790 tab_strip_model_->GetWrapperIndex(source));
[email protected]932b7a12011-03-09 12:50:273791 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]4fdf6742012-01-10 20:14:363809void Browser::ShowRepostFormWarningDialog(WebContents* source) {
[email protected]67baffc82011-12-19 18:03:073810 browser::ShowTabModalConfirmDialog(
[email protected]2a6bc3e2011-12-28 23:51:333811 new RepostFormWarningController(source),
3812 TabContentsWrapper::GetCurrentWrapperForContents(source));
[email protected]14f3408a2009-08-31 20:53:533813}
3814
[email protected]ec0b6c42010-08-26 03:16:583815bool Browser::ShouldAddNavigationToHistory(
3816 const history::HistoryAddPageArgs& add_page_args,
[email protected]610cbb82011-10-18 16:35:083817 content::NavigationType navigation_type) {
[email protected]2e29d922009-10-22 22:13:353818 // Don't update history if running as app.
3819 return !IsApplication();
3820}
3821
[email protected]4fdf6742012-01-10 20:14:363822bool Browser::ShouldCreateWebContents(
3823 WebContents* web_contents,
3824 int route_id,
3825 WindowContainerType window_container_type,
[email protected]03b6d552012-03-29 04:03:013826 const string16& frame_name,
3827 const GURL& target_url) {
[email protected]4fdf6742012-01-10 20:14:363828 if (window_container_type == WINDOW_CONTAINER_TYPE_BACKGROUND) {
3829 // If a BackgroundContents is created, suppress the normal WebContents.
3830 return !MaybeCreateBackgroundContents(
[email protected]03b6d552012-03-29 04:03:013831 route_id, web_contents, frame_name, target_url);
[email protected]4fdf6742012-01-10 20:14:363832 }
3833
3834 return true;
3835}
3836
3837void Browser::WebContentsCreated(WebContents* source_contents,
3838 int64 source_frame_id,
3839 const GURL& target_url,
3840 WebContents* new_contents) {
[email protected]80c7b802011-10-28 19:59:083841 // Create a TabContentsWrapper now, so all observers are in place, as the
3842 // network requests for its initial navigation will start immediately. The
[email protected]075969d2012-04-17 20:05:553843 // WebContents will later be inserted into this browser using
[email protected]80c7b802011-10-28 19:59:083844 // Browser::Navigate via AddNewContents. The latter will retrieve the newly
[email protected]075969d2012-04-17 20:05:553845 // created TabContentsWrapper from WebContents object.
[email protected]d9083482012-01-06 00:38:463846 new TabContentsWrapper(new_contents);
[email protected]4fdf6742012-01-10 20:14:363847
3848 // Notify.
3849 RetargetingDetails details;
3850 details.source_web_contents = source_contents;
3851 details.source_frame_id = source_frame_id;
3852 details.target_url = target_url;
3853 details.target_web_contents = new_contents;
3854 details.not_yet_in_tabstrip = true;
3855 content::NotificationService::current()->Notify(
3856 chrome::NOTIFICATION_RETARGETING,
3857 content::Source<Profile>(profile_),
3858 content::Details<RetargetingDetails>(&details));
[email protected]80c7b802011-10-28 19:59:083859}
3860
[email protected]2a6bc3e2011-12-28 23:51:333861void Browser::ContentRestrictionsChanged(WebContents* source) {
[email protected]9e823662010-10-13 23:36:003862 UpdateCommandsForContentRestrictionState();
3863}
3864
[email protected]2a6bc3e2011-12-28 23:51:333865void Browser::RendererUnresponsive(WebContents* source) {
[email protected]c19d9542011-11-15 22:26:423866 // Ignore hangs if print preview is open.
3867 TabContentsWrapper* source_wrapper =
3868 TabContentsWrapper::GetCurrentWrapperForContents(source);
3869 if (source_wrapper) {
3870 printing::PrintPreviewTabController* controller =
3871 printing::PrintPreviewTabController::GetInstance();
3872 if (controller) {
3873 TabContentsWrapper* preview_tab =
3874 controller->GetPrintPreviewForTab(source_wrapper);
3875 if (preview_tab && preview_tab != source_wrapper) {
3876 return;
3877 }
3878 }
3879 }
3880
[email protected]55452902011-06-01 21:57:473881 browser::ShowHungRendererDialog(source);
3882}
3883
[email protected]2a6bc3e2011-12-28 23:51:333884void Browser::RendererResponsive(WebContents* source) {
[email protected]55452902011-06-01 21:57:473885 browser::HideHungRendererDialog(source);
3886}
3887
[email protected]2a6bc3e2011-12-28 23:51:333888void Browser::WorkerCrashed(WebContents* source) {
[email protected]55452902011-06-01 21:57:473889 TabContentsWrapper* wrapper =
3890 TabContentsWrapper::GetCurrentWrapperForContents(source);
[email protected]95a33ed62011-09-30 15:07:083891 InfoBarTabHelper* infobar_helper = wrapper->infobar_tab_helper();
3892 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3893 infobar_helper,
3894 NULL,
3895 l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
[email protected]55452902011-06-01 21:57:473896 true));
[email protected]0dd3a0ab2011-02-18 08:17:443897}
3898
[email protected]2a6bc3e2011-12-28 23:51:333899void Browser::DidNavigateMainFramePostCommit(WebContents* tab) {
[email protected]4ca15302012-01-03 05:53:203900 if (tab == GetSelectedWebContents())
[email protected]09b29342011-06-24 19:18:483901 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003902}
3903
[email protected]2a6bc3e2011-12-28 23:51:333904void Browser::DidNavigateToPendingEntry(WebContents* tab) {
[email protected]4ca15302012-01-03 05:53:203905 if (tab == GetSelectedWebContents())
[email protected]09b29342011-06-24 19:18:483906 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003907}
3908
[email protected]3ab9cb82011-06-03 18:02:073909content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
3910 return GetJavaScriptDialogCreatorInstance();
3911}
3912
[email protected]da8543762012-03-20 08:52:203913content::ColorChooser* Browser::OpenColorChooser(WebContents* tab,
3914 int color_chooser_id,
[email protected]55578b0a2012-04-18 14:31:323915 SkColor color) {
[email protected]da8543762012-03-20 08:52:203916#if defined(OS_WIN)
3917 // On Windows, only create a color chooser if one doesn't exist, because we
3918 // can't close the old color chooser dialog.
3919 if (!color_chooser_.get())
3920 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, tab,
3921 color));
3922#else
3923 if (color_chooser_.get())
3924 color_chooser_->End();
3925 color_chooser_.reset(content::ColorChooser::Create(color_chooser_id, tab,
3926 color));
3927#endif
3928 return color_chooser_.get();
3929}
3930
3931void Browser::DidEndColorChooser() {
3932 color_chooser_.reset();
3933}
3934
[email protected]2a6bc3e2011-12-28 23:51:333935void Browser::RunFileChooser(WebContents* tab,
[email protected]8caadeb2011-11-22 02:45:233936 const content::FileChooserParams& params) {
[email protected]b888919c2011-09-02 00:32:163937 RunFileChooserHelper(tab, params);
[email protected]3a29a6e2011-08-24 18:26:213938}
3939
[email protected]2a6bc3e2011-12-28 23:51:333940void Browser::EnumerateDirectory(WebContents* tab, int request_id,
[email protected]3a29a6e2011-08-24 18:26:213941 const FilePath& path) {
[email protected]b888919c2011-09-02 00:32:163942 EnumerateDirectoryHelper(tab, request_id, path);
[email protected]3a29a6e2011-08-24 18:26:213943}
3944
[email protected]2a6bc3e2011-12-28 23:51:333945void Browser::ToggleFullscreenModeForTab(WebContents* tab,
[email protected]01a5a762011-11-21 05:40:553946 bool enter_fullscreen) {
3947 fullscreen_controller_->ToggleFullscreenModeForTab(tab, enter_fullscreen);
[email protected]8a5e0ca2011-08-25 06:30:473948}
3949
[email protected]199bba6e2012-04-04 16:19:383950bool Browser::IsFullscreenForTabOrPending(const WebContents* tab) const {
[email protected]ff475a322012-03-14 00:05:353951 return fullscreen_controller_->IsFullscreenForTabOrPending(tab);
[email protected]5d5f7af2011-10-01 01:38:123952}
3953
[email protected]2a6bc3e2011-12-28 23:51:333954void Browser::JSOutOfMemory(WebContents* tab) {
[email protected]b888919c2011-09-02 00:32:163955 JSOutOfMemoryHelper(tab);
[email protected]7d189022011-08-25 22:54:203956}
3957
[email protected]2a6bc3e2011-12-28 23:51:333958void Browser::RegisterProtocolHandler(WebContents* tab,
[email protected]7d189022011-08-25 22:54:203959 const std::string& protocol,
3960 const GURL& url,
3961 const string16& title) {
[email protected]b888919c2011-09-02 00:32:163962 RegisterProtocolHandlerHelper(tab, protocol, url, title);
[email protected]7d189022011-08-25 22:54:203963}
3964
[email protected]2a6bc3e2011-12-28 23:51:333965void Browser::RegisterIntentHandler(WebContents* tab,
[email protected]7d189022011-08-25 22:54:203966 const string16& action,
3967 const string16& type,
3968 const string16& href,
[email protected]63c239322011-10-31 23:56:303969 const string16& title,
3970 const string16& disposition) {
[email protected]7e199322012-03-13 20:04:563971#if defined(ENABLE_WEB_INTENTS)
[email protected]63c239322011-10-31 23:56:303972 RegisterIntentHandlerHelper(tab, action, type, href, title, disposition);
[email protected]7e199322012-03-13 20:04:563973#endif
[email protected]7d189022011-08-25 22:54:203974}
3975
[email protected]0d9989d2011-12-21 20:26:003976void Browser::WebIntentDispatch(
[email protected]2a6bc3e2011-12-28 23:51:333977 WebContents* tab, content::WebIntentsDispatcher* intents_dispatcher) {
[email protected]7e199322012-03-13 20:04:563978#if defined(ENABLE_WEB_INTENTS)
[email protected]203da212012-05-02 19:26:023979 if (!web_intents::IsWebIntentsEnabled(profile_))
[email protected]828e61af2011-09-14 19:45:063980 return;
3981
3982 TabContentsWrapper* tcw =
3983 TabContentsWrapper::GetCurrentWrapperForContents(tab);
[email protected]0d9989d2011-12-21 20:26:003984 tcw->web_intent_picker_controller()->SetIntentsDispatcher(intents_dispatcher);
[email protected]ada02b312011-12-01 21:54:533985 tcw->web_intent_picker_controller()->ShowDialog(
[email protected]0d9989d2011-12-21 20:26:003986 intents_dispatcher->GetIntent().action,
3987 intents_dispatcher->GetIntent().type);
[email protected]b7813a22012-04-04 18:41:023988#endif // defined(ENABLE_WEB_INTENTS)
[email protected]b888919c2011-09-02 00:32:163989}
3990
[email protected]2a6bc3e2011-12-28 23:51:333991void Browser::UpdatePreferredSize(WebContents* source,
[email protected]0548c5352011-09-07 00:33:333992 const gfx::Size& pref_size) {
3993 window_->UpdatePreferredSize(source, pref_size);
3994}
3995
[email protected]61e2b3cc2012-03-02 16:13:343996void Browser::ResizeDueToAutoResize(WebContents* source,
3997 const gfx::Size& new_size) {
3998 window_->ResizeDueToAutoResize(source, new_size);
3999}
4000
[email protected]92655362012-04-20 21:33:174001void Browser::FindReply(WebContents* tab,
4002 int request_id,
4003 int number_of_matches,
4004 const gfx::Rect& selection_rect,
4005 int active_match_ordinal,
4006 bool final_update) {
4007 FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
4008 active_match_ordinal, final_update);
4009}
4010
[email protected]42252e02012-04-26 16:29:394011void Browser::RequestToLockMouse(WebContents* tab, bool user_gesture) {
4012 fullscreen_controller_->RequestToLockMouse(tab, user_gesture);
[email protected]55c87fa2011-10-15 07:28:284013}
4014
[email protected]5ef8e372011-10-18 04:25:554015void Browser::LostMouseLock() {
[email protected]01a5a762011-11-21 05:40:554016 fullscreen_controller_->LostMouseLock();
[email protected]5ef8e372011-10-18 04:25:554017}
4018
[email protected]36b6dcb2008-11-12 01:19:574019///////////////////////////////////////////////////////////////////////////////
[email protected]51d83bdf2011-12-09 16:09:294020// Browser, CoreTabHelperDelegate implementation:
[email protected]a0366a52011-02-04 20:04:214021
[email protected]92655362012-04-20 21:33:174022void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
4023 TabContentsWrapper* new_tab_contents) {
[email protected]2fc15ae2012-05-06 00:01:374024 int index = tab_strip_model_->GetIndexOfTabContents(old_tab_contents);
[email protected]92655362012-04-20 21:33:174025 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]2fc15ae2012-05-06 00:01:374026 tab_strip_model_->ReplaceTabContentsAt(index, new_tab_contents);
[email protected]92655362012-04-20 21:33:174027}
4028
4029///////////////////////////////////////////////////////////////////////////////
4030// Browser, SearchEngineTabHelperDelegate implementation:
4031
[email protected]3613347d2012-04-27 20:27:374032void Browser::ConfirmAddSearchProvider(TemplateURL* template_url,
[email protected]92655362012-04-20 21:33:174033 Profile* profile) {
4034 window()->ConfirmAddSearchProvider(template_url, profile);
4035}
4036
4037///////////////////////////////////////////////////////////////////////////////
4038// Browser, ConstrainedWindowTabHelperDelegate implementation:
4039
4040void Browser::SetTabContentBlocked(TabContentsWrapper* wrapper, bool blocked) {
[email protected]2fc15ae2012-05-06 00:01:374041 int index = tab_strip_model_->GetIndexOfTabContents(wrapper);
[email protected]92655362012-04-20 21:33:174042 if (index == TabStripModel::kNoTab) {
4043 NOTREACHED();
4044 return;
4045 }
[email protected]2fc15ae2012-05-06 00:01:374046 tab_strip_model_->SetTabBlocked(index, blocked);
[email protected]92655362012-04-20 21:33:174047 UpdatePrintingState(wrapper->web_contents()->GetContentRestrictions());
4048 if (!blocked && GetSelectedTabContentsWrapper() == wrapper)
4049 wrapper->web_contents()->Focus();
4050}
4051
4052///////////////////////////////////////////////////////////////////////////////
4053// Browser, BlockedContentTabHelperDelegate implementation:
4054
4055TabContentsWrapper* Browser::GetConstrainingContentsWrapper(
4056 TabContentsWrapper* source) {
4057 return source;
4058}
4059
4060///////////////////////////////////////////////////////////////////////////////
4061// Browser, BookmarkTabHelperDelegate implementation:
4062
4063void Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
4064 if (source == GetSelectedTabContentsWrapper())
4065 window_->SetStarredState(starred);
4066}
4067
4068///////////////////////////////////////////////////////////////////////////////
4069// Browser, ExtensionTabHelperDelegate implementation:
4070
[email protected]553602e12011-04-05 17:01:184071void Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
4072 int32 page_id) {
4073 if (GetSelectedTabContentsWrapper() != source)
4074 return;
4075
[email protected]10f417c52011-12-28 21:04:234076 NavigationEntry* entry =
[email protected]d9083482012-01-06 00:38:464077 source->web_contents()->GetController().GetLastCommittedEntry();
[email protected]36fc0392011-12-25 03:59:514078 if (!entry || (entry->GetPageID() != page_id))
[email protected]553602e12011-04-05 17:01:184079 return;
4080
4081 switch (pending_web_app_action_) {
4082 case CREATE_SHORTCUT: {
4083 window()->ShowCreateWebAppShortcutsDialog(source);
4084 break;
4085 }
4086 case UPDATE_SHORTCUT: {
4087 web_app::UpdateShortcutForTabContents(source);
4088 break;
4089 }
4090 default:
4091 NOTREACHED();
4092 break;
4093 }
4094
4095 pending_web_app_action_ = NONE;
4096}
4097
4098void Browser::OnInstallApplication(TabContentsWrapper* source,
4099 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:364100 ExtensionService* extension_service = profile()->GetExtensionService();
4101 if (!extension_service)
[email protected]553602e12011-04-05 17:01:184102 return;
4103
[email protected]d8c8f25f2011-11-02 18:18:014104 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(
4105 extension_service,
[email protected]14908b72011-04-20 06:54:364106 extension_service->show_extensions_prompts() ?
4107 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:184108 installer->InstallWebApp(web_app);
4109}
4110
[email protected]c90c6ca2011-02-16 20:11:384111///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574112// Browser, SelectFileDialog::Listener implementation:
4113
[email protected]561abe62009-04-06 18:08:344114void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:514115 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:124116 GURL file_url = net::FilePathToFileURL(path);
[email protected]b7813a22012-04-04 18:41:024117
4118#if defined(OS_CHROMEOS)
4119 gdata::util::ModifyGDataFileResourceUrl(profile_, path, &file_url);
4120#endif
4121
[email protected]e5d549d2011-12-28 01:29:204122 if (file_url.is_empty())
4123 return;
4124
4125 OpenURL(OpenURLParams(
4126 file_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED,
4127 false));
[email protected]36b6dcb2008-11-12 01:19:574128}
4129
4130///////////////////////////////////////////////////////////////////////////////
[email protected]6c2381d2011-10-19 02:52:534131// Browser, content::NotificationObserver implementation:
[email protected]36b6dcb2008-11-12 01:19:574132
[email protected]432115822011-07-10 15:52:274133void Browser::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:534134 const content::NotificationSource& source,
4135 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:274136 switch (type) {
[email protected]fbc5e5f92012-01-02 06:08:324137 case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:404138 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:214139 // Pass in false so that we delay processing. We need to delay the
4140 // processing as it may close the tab, which is currently on the call
4141 // stack above us.
[email protected]fbc5e5f92012-01-02 06:08:324142 ClearUnloadState(content::Source<WebContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:404143 }
4144 break;
4145
[email protected]432115822011-07-10 15:52:274146 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:404147 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:324148 // bar to reflect the new state. Note that it's possible for the selected
4149 // tab contents to be NULL. This is because we listen for all sources
4150 // (NavigationControllers) for convenience, so the notification could
4151 // actually be for a different window while we're doing asynchronous
4152 // closing of this one.
[email protected]4ca15302012-01-03 05:53:204153 if (GetSelectedWebContents() &&
4154 &GetSelectedWebContents()->GetController() ==
[email protected]c5eed492012-01-04 17:07:504155 content::Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:574156 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:404157 break;
4158
[email protected]432115822011-07-10 15:52:274159 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:364160 if (window()->GetLocationBar())
4161 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:384162
[email protected]b3f7fe22011-11-11 19:27:564163 // Close any tabs from the unloaded extension, unless it's terminated,
4164 // in which case let the sad tabs remain.
4165 if (content::Details<UnloadedExtensionInfo>(details)->reason !=
4166 extension_misc::UNLOAD_REASON_TERMINATE) {
4167 const Extension* extension =
4168 content::Details<UnloadedExtensionInfo>(details)->extension;
[email protected]2fc15ae2012-05-06 00:01:374169 for (int i = tab_strip_model_->count() - 1; i >= 0; --i) {
4170 WebContents* tc =
4171 tab_strip_model_->GetTabContentsAt(i)->web_contents();
[email protected]b3f7fe22011-11-11 19:27:564172 bool close_tab_contents =
4173 tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
4174 tc->GetURL().host() == extension->id();
4175 // We want to close all panels originated by the unloaded extension.
4176 close_tab_contents = close_tab_contents ||
4177 (type_ == TYPE_PANEL &&
4178 (web_app::GetExtensionIdFromApplicationName(app_name_) ==
[email protected]f9e82d92011-10-29 00:50:454179 extension->id()));
[email protected]b3f7fe22011-11-11 19:27:564180 if (close_tab_contents) {
4181 CloseTabContents(tc);
4182 }
[email protected]894bb502009-05-21 22:39:574183 }
4184 }
4185 break;
4186 }
4187
[email protected]432115822011-07-10 15:52:274188 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
[email protected]6c2381d2011-10-19 02:52:534189 Profile* profile = content::Source<Profile>(source).ptr();
[email protected]fe8944f2011-08-30 17:47:324190 if (profile_->IsSameProfile(profile) && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364191 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:464192 break;
4193 }
4194
[email protected]432115822011-07-10 15:52:274195 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
4196 case chrome::NOTIFICATION_EXTENSION_LOADED:
[email protected]1797f4a2011-08-30 18:00:284197 // During window creation on Windows we may end up calling into
4198 // SHAppBarMessage, which internally spawns a nested message loop. This
4199 // makes it possible for us to end up here before window creation has
4200 // completed,at which point window_ is NULL. See 94752 for details.
4201 if (window() && window()->GetLocationBar())
[email protected]ce696a452011-05-31 17:47:364202 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:364203 break;
[email protected]ad0c2e1b2010-01-30 00:00:104204
[email protected]6b40bb582012-03-15 20:50:384205#if defined(ENABLE_THEMES)
[email protected]432115822011-07-10 15:52:274206 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
[email protected]e001d412009-06-26 20:53:254207 window()->UserChangedTheme();
4208 break;
[email protected]6b40bb582012-03-15 20:50:384209#endif
[email protected]e001d412009-06-26 20:53:254210
[email protected]432115822011-07-10 15:52:274211 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]6c2381d2011-10-19 02:52:534212 const std::string& pref_name =
4213 *content::Details<std::string>(details).ptr();
[email protected]3cf345b2011-10-06 17:51:254214 if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:374215 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]3819f2ee2011-08-21 09:44:384216 } else if (pref_name == prefs::kInstantEnabled ||
4217 pref_name == prefs::kMetricsReportingEnabled ||
4218 pref_name == prefs::kSearchSuggestEnabled) {
[email protected]73de26a2010-10-17 03:23:254219 if (!InstantController::IsEnabled(profile())) {
4220 if (instant()) {
4221 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:294222 instant_.reset();
4223 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:254224 }
4225 } else {
4226 CreateInstantIfNecessary();
4227 }
[email protected]4e94ab32011-08-05 05:28:274228 } else if (pref_name == prefs::kIncognitoModeAvailability) {
[email protected]93ad8e1c2011-11-08 21:34:054229 UpdateCommandsForIncognitoAvailability();
[email protected]543432ee2010-10-22 16:32:134230 } else if (pref_name == prefs::kDevToolsDisabled) {
4231 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:044232 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]0e12d7d2011-12-01 16:21:444233 content::DevToolsManager::GetInstance()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:584234 } else if (pref_name == prefs::kEditBookmarksEnabled) {
4235 UpdateCommandsForBookmarkEditing();
[email protected]3710d0002011-10-11 00:35:004236 } else if (pref_name == prefs::kShowBookmarkBar) {
[email protected]a007e732011-08-05 13:32:194237 UpdateCommandsForBookmarkBar();
[email protected]3710d0002011-10-11 00:35:004238 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]6c6b02d2011-09-02 03:36:474239 } else if (pref_name == prefs::kHomePage) {
[email protected]6c2381d2011-10-19 02:52:534240 PrefService* pref_service = content::Source<PrefService>(source).ptr();
[email protected]6c6b02d2011-09-02 03:36:474241 MarkHomePageAsChanged(pref_service);
[email protected]97b46382011-05-02 13:23:044242 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
4243 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
4244 UpdateOpenFileState();
[email protected]623294c42012-04-27 18:27:144245 } else if (pref_name == prefs::kInManagedMode) {
4246 UpdateCommandsForMultipleProfiles();
[email protected]2a7e7c152010-10-01 20:12:094247 } else {
[email protected]b9c505b2010-04-30 15:05:104248 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:094249 }
[email protected]b9c505b2010-04-30 15:05:104250 break;
4251 }
4252
[email protected]ea049a02011-12-25 21:37:094253 case chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED: {
4254 WebContents* web_contents = content::Source<WebContents>(source).ptr();
[email protected]4ca15302012-01-03 05:53:204255 if (web_contents == GetSelectedWebContents()) {
[email protected]9a9a9e22011-05-13 22:20:354256 LocationBar* location_bar = window()->GetLocationBar();
4257 if (location_bar)
4258 location_bar->UpdateContentSettingsIcons();
4259 }
4260 break;
4261 }
4262
[email protected]432115822011-07-10 15:52:274263 case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:484264 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]e397a4472011-12-21 21:47:504265 UpdateCommandsForTabState();
4266 break;
4267
4268 case content::NOTIFICATION_INTERSTITIAL_DETACHED:
4269 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
4270 UpdateCommandsForTabState();
[email protected]09b29342011-06-24 19:18:484271 break;
4272
[email protected]e83f1682008-09-07 23:57:404273 default:
4274 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:294275 }
4276}
4277
[email protected]d3b98c82010-07-14 07:45:594278///////////////////////////////////////////////////////////////////////////////
4279// Browser, ProfileSyncServiceObserver implementation:
4280
4281void Browser::OnStateChanged() {
[email protected]5e61afb92012-01-27 20:09:134282 DCHECK(ProfileSyncServiceFactory::GetInstance()->HasProfileSyncService(
4283 profile_));
[email protected]99e652f2012-01-22 04:05:074284 // For unit tests, we don't have a window.
4285 if (!window_)
4286 return;
[email protected]93ad8e1c2011-11-08 21:34:054287 const bool show_main_ui = IsShowingMainUI(window_->IsFullscreen());
[email protected]65549182012-02-25 00:45:404288 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
[email protected]49385da692011-08-05 04:03:394289 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]d3b98c82010-07-14 07:45:594290}
[email protected]88d74942009-01-21 22:04:444291
[email protected]36b6dcb2008-11-12 01:19:574292///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:274293// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:304294
[email protected]3c9e1872010-11-18 16:17:494295void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
4296 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:144297 window_->ShowInstant(preview_contents);
[email protected]42f027fb2011-10-27 16:37:484298
[email protected]4ca15302012-01-03 05:53:204299 GetSelectedWebContents()->HideContents();
4300 preview_contents->web_contents()->ShowContents();
[email protected]03bb953d2010-09-14 21:38:304301}
4302
[email protected]6b723f82010-10-05 20:14:274303void Browser::HideInstant() {
[email protected]3e481282011-10-15 15:39:504304 window_->HideInstant();
[email protected]4ca15302012-01-03 05:53:204305 if (GetSelectedWebContents())
4306 GetSelectedWebContents()->ShowContents();
[email protected]42f027fb2011-10-27 16:37:484307 if (instant_->GetPreviewContents())
[email protected]4ca15302012-01-03 05:53:204308 instant_->GetPreviewContents()->web_contents()->HideContents();
[email protected]03bb953d2010-09-14 21:38:304309}
4310
[email protected]3c9e1872010-11-18 16:17:494311void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
4312 TabContentsWrapper* tab_contents = instant_->tab_contents();
[email protected]2fc15ae2012-05-06 00:01:374313 int index = tab_strip_model_->GetIndexOfTabContents(tab_contents);
[email protected]3c9e1872010-11-18 16:17:494314 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:304315 // TabStripModel takes ownership of preview_contents.
[email protected]2fc15ae2012-05-06 00:01:374316 tab_strip_model_->ReplaceTabContentsAt(index, preview_contents);
[email protected]43032342011-03-21 14:10:314317 // InstantUnloadHandler takes ownership of tab_contents.
4318 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:334319
[email protected]d9083482012-01-06 00:38:464320 GURL url = preview_contents->web_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:524321 DCHECK(profile_->GetExtensionService());
4322 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]a9acdff2012-03-08 04:04:524323 AppLauncherHandler::RecordAppLaunchType(
4324 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT);
[email protected]46fd1ea42011-02-16 15:59:334325 }
[email protected]03bb953d2010-09-14 21:38:304326}
4327
[email protected]33b8b8e2011-03-15 14:51:554328void Browser::SetSuggestedText(const string16& text,
4329 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:364330 if (window()->GetLocationBar())
4331 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:304332}
4333
[email protected]6b723f82010-10-05 20:14:274334gfx::Rect Browser::GetInstantBounds() {
4335 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:474336}
4337
[email protected]09c69432012-03-16 16:23:284338void Browser::InstantPreviewFocused() {
4339 // NOTE: This is only invoked on aura.
4340 window_->WebContentsFocused(instant_->GetPreviewContents()->web_contents());
4341}
4342
[email protected]9800de5e2011-03-11 18:19:494343
4344
4345///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574346// Browser, Command and state updating (private):
4347
[email protected]92655362012-04-20 21:33:174348bool Browser::IsShowingMainUI(bool is_fullscreen) {
4349#if !defined(OS_MACOSX)
4350 return is_type_tabbed() && !is_fullscreen;
4351#else
4352 return is_type_tabbed();
4353#endif
4354}
4355
[email protected]36b6dcb2008-11-12 01:19:574356void Browser::InitCommandState() {
4357 // All browser commands whose state isn't set automagically some other way
4358 // (like Back & Forward with initial page load) must have their state
4359 // initialized here, otherwise they will be forever disabled.
4360
[email protected]84214982008-12-10 18:49:104361 // Navigation commands
[email protected]1fc025202009-01-20 23:03:144362 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:164363 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:104364
4365 // Window management commands
[email protected]1fc025202009-01-20 23:03:144366 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
4367 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
4368 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
4369 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:134370 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:144371 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]cdc05ec2011-05-18 15:15:594372 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:104373
4374 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:514375 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:144376 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
4377 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
4378 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
4379 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
4380 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
4381 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
4382 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
4383 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
4384 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
4385 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
4386 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
4387 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
4388 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
4389 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
4390 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
4391 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
4392 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
4393 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
4394 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
4395 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
4396 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
4397 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
4398 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
4399 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
4400 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
4401 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
4402 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
4403 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
4404 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
4405 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
4406 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
4407 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
4408 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
4409 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
4410 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:004411 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:144412 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
4413 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:104414
[email protected]63b02932009-06-05 09:40:514415 // Zoom
4416 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
4417 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
4418 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
4419 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
4420
[email protected]84214982008-12-10 18:49:104421 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:044422 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:144423 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:134424 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:144425 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:144426 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]1fc025202009-01-20 23:03:144427 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
4428 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]d6852fd2011-05-20 17:19:124429 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:294430
[email protected]96e34672010-02-09 21:40:294431#if defined(OS_CHROMEOS)
[email protected]d14af522010-12-02 03:54:504432 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]96e34672010-02-09 21:40:294433#endif
[email protected]a038159b2011-08-18 02:55:364434 command_updater_.UpdateCommandEnabled(
4435 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]c8b59f92010-05-28 21:45:474436
[email protected]64ff7942008-12-17 18:11:234437 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:144438 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:234439
[email protected]11f4857282009-11-13 19:56:174440 // Navigation commands
4441 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:234442
[email protected]11f4857282009-11-13 19:56:174443 // Window management commands
[email protected]d3766932011-08-04 22:18:234444 // TODO(rohitrao): Disable fullscreen on non-Lion?
[email protected]cf299bc2010-08-12 20:27:094445 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:144446 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:174447 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
4448 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
4449 normal_window);
4450 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
4451 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
4452 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
4453 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
4454 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
4455 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
4456 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
4457 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
4458 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
4459 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
4460 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:554461#if defined(OS_MACOSX)
4462 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
[email protected]d3766932011-08-04 22:18:234463 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
4464 !(is_type_panel() && is_app()));
[email protected]c1d0d812010-07-27 20:21:554465#endif
[email protected]e662ade2009-06-08 18:20:144466
[email protected]fc33e9992010-04-08 19:40:134467 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:144468 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134469
4470 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:144471 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
4472 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
4473 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134474
[email protected]11f4857282009-11-13 19:56:174475 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:134476 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:004477
[email protected]c1bbaa82010-11-08 11:17:054478 // The upgrade entry and the view incompatibility entry should always be
4479 // enabled. Whether they are visible is a separate matter determined on menu
4480 // show.
[email protected]b21d6912010-08-31 19:22:414481 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:054482 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:414483
[email protected]b569c112010-11-22 20:53:444484 // View Background Pages entry is always enabled, but is hidden if there are
4485 // no background pages.
4486 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
4487
[email protected]afcb43562011-09-02 23:33:384488 // Toggle speech input
4489 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
4490
[email protected]9282cea2009-02-18 18:49:004491 // Initialize other commands whose state changes based on fullscreen mode.
4492 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:004493
4494 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584495
4496 UpdateCommandsForBookmarkEditing();
[email protected]93ad8e1c2011-11-08 21:34:054497
4498 UpdateCommandsForIncognitoAvailability();
4499}
4500
[email protected]93ad8e1c2011-11-08 21:34:054501void Browser::UpdateCommandsForIncognitoAvailability() {
4502 IncognitoModePrefs::Availability incognito_availability =
4503 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
4504 command_updater_.UpdateCommandEnabled(
4505 IDC_NEW_WINDOW,
4506 incognito_availability != IncognitoModePrefs::FORCED);
4507 command_updater_.UpdateCommandEnabled(
4508 IDC_NEW_INCOGNITO_WINDOW,
4509 incognito_availability != IncognitoModePrefs::DISABLED);
4510
4511 // Bookmark manager and settings page/subpages are forced to open in normal
4512 // mode. For this reason we disable these commands when incognito is forced.
4513 const bool command_enabled =
4514 incognito_availability != IncognitoModePrefs::FORCED;
4515 command_updater_.UpdateCommandEnabled(
4516 IDC_SHOW_BOOKMARK_MANAGER,
4517 browser_defaults::bookmarks_enabled && command_enabled);
4518 ExtensionService* extension_service = profile()->GetExtensionService();
4519 bool enable_extensions =
4520 extension_service && extension_service->extensions_enabled();
4521 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
4522 enable_extensions && command_enabled);
4523
4524 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4525 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS,
4526 show_main_ui && command_enabled);
4527 command_updater_.UpdateCommandEnabled(IDC_OPTIONS,
4528 show_main_ui && command_enabled);
[email protected]36b6dcb2008-11-12 01:19:574529}
4530
[email protected]84214982008-12-10 18:49:104531void Browser::UpdateCommandsForTabState() {
[email protected]4ca15302012-01-03 05:53:204532 WebContents* current_tab = GetSelectedWebContents();
[email protected]a0366a52011-02-04 20:04:214533 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
4534 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:394535 return;
[email protected]d8375fd2008-11-25 22:45:394536
[email protected]84214982008-12-10 18:49:104537 // Navigation commands
[email protected]c5eed492012-01-04 17:07:504538 NavigationController& nc = current_tab->GetController();
[email protected]ce3fa3c2009-04-20 19:55:574539 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
4540 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:134541 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
4542 CanReloadContents(current_tab));
4543 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
4544 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:294545
[email protected]84214982008-12-10 18:49:104546 // Window management commands
[email protected]1fc025202009-01-20 23:03:144547 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:144548 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:104549
[email protected]57c6a652009-05-04 07:58:344550 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:384551 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:144552 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:344553 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]f5fa20e2011-12-21 22:35:564554 current_tab->GetController().CanViewSource());
[email protected]151666e2010-10-21 17:05:254555 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
[email protected]ef557022012-03-16 10:05:334556 toolbar_model_->ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:404557 if (is_devtools())
4558 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:254559
4560 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]e397a4472011-12-21 21:47:504561 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry()) ||
[email protected]0bfbf882011-12-22 18:19:274562 current_tab->ShowingInterstitialPage();
[email protected]c0f82ec52010-07-27 14:22:144563 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
[email protected]a53209b2012-01-20 16:48:164564 !is_chrome_internal && current_tab->IsSavable());
[email protected]c0f82ec52010-07-27 14:22:144565
[email protected]57c6a652009-05-04 07:58:344566 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254567 // TODO(pinkerton): Disable app-mode in the model until we implement it
4568 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4569#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344570 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234571 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:254572#endif
[email protected]9e823662010-10-13 23:36:004573
4574 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584575 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004576}
4577
4578void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374579 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004580
4581 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184582 IDC_COPY, !(restrictions & content::CONTENT_RESTRICTION_COPY));
[email protected]9e823662010-10-13 23:36:004583 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184584 IDC_CUT, !(restrictions & content::CONTENT_RESTRICTION_CUT));
[email protected]9e823662010-10-13 23:36:004585 command_updater_.UpdateCommandEnabled(
[email protected]4573fbd2011-10-31 20:25:184586 IDC_PASTE, !(restrictions & content::CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044587 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004588 UpdatePrintingState(restrictions);
4589}
4590
[email protected]543432ee2010-10-22 16:32:134591void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044592 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424593 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134594 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4595 dev_tools_enabled);
4596 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4597 dev_tools_enabled);
4598 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4599 dev_tools_enabled);
4600}
4601
[email protected]a13f47d12011-04-14 11:41:584602void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044603 bool enabled =
4604 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4605 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584606
4607 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144608 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584609 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4610 enabled && CanBookmarkAllTabs());
4611}
4612
[email protected]a007e732011-08-05 13:32:194613void Browser::UpdateCommandsForBookmarkBar() {
[email protected]93ad8e1c2011-11-08 21:34:054614 const bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
[email protected]a007e732011-08-05 13:32:194615 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
4616 browser_defaults::bookmarks_enabled &&
[email protected]3710d0002011-10-11 00:35:004617 !profile_->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
[email protected]a007e732011-08-05 13:32:194618 show_main_ui);
4619}
4620
[email protected]6c6b02d2011-09-02 03:36:474621void Browser::MarkHomePageAsChanged(PrefService* pref_service) {
4622 pref_service->SetBoolean(prefs::kHomePageChanged, true);
[email protected]6c6b02d2011-09-02 03:36:474623}
4624
[email protected]92655362012-04-20 21:33:174625void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
4626 const bool show_main_ui = IsShowingMainUI(is_fullscreen);
4627 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
4628
4629 // Navigation commands
4630 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
4631
4632 // Window management commands
4633 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
4634 type_ != TYPE_TABBED && !is_fullscreen);
4635
4636 // Focus various bits of UI
4637 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
4638 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
4639 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
4640 command_updater_.UpdateCommandEnabled(
4641 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
4642 command_updater_.UpdateCommandEnabled(
4643 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
4644 command_updater_.UpdateCommandEnabled(
4645 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
4646 command_updater_.UpdateCommandEnabled(
4647 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
4648
4649 // Show various bits of UI
4650 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
4651 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
4652 command_updater_.UpdateCommandEnabled(IDC_SHOW_SYNC_SETUP,
4653 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
4654
4655 // Settings page/subpages are forced to open in normal mode. We disable these
4656 // commands when incognito is forced.
4657 const bool options_enabled = show_main_ui &&
4658 IncognitoModePrefs::GetAvailability(
4659 profile_->GetPrefs()) != IncognitoModePrefs::FORCED;
4660 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled);
4661 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, options_enabled);
4662
4663 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
4664 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
4665 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
4666 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]92655362012-04-20 21:33:174667#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
4668 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
4669#endif
4670
4671 UpdateCommandsForBookmarkBar();
[email protected]623294c42012-04-27 18:27:144672 UpdateCommandsForMultipleProfiles();
4673}
4674
4675void Browser::UpdateCommandsForMultipleProfiles() {
4676 bool show_main_ui = IsShowingMainUI(window_ && window_->IsFullscreen());
4677 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU,
4678 show_main_ui &&
4679 !profile()->IsOffTheRecord() &&
4680 ProfileManager::IsMultipleProfilesEnabled());
[email protected]92655362012-04-20 21:33:174681}
4682
4683void Browser::UpdatePrintingState(int content_restrictions) {
4684 bool print_enabled = true;
4685 bool advanced_print_enabled = true;
4686 if (g_browser_process->local_state()) {
4687 print_enabled =
4688 g_browser_process->local_state()->GetBoolean(prefs::kPrintingEnabled);
4689 advanced_print_enabled = print_enabled;
4690 }
4691 if (print_enabled) {
4692 // Do not print when a constrained window is showing. It's confusing.
4693 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
4694 bool has_constrained_window = (wrapper &&
4695 wrapper->constrained_window_tab_helper()->constrained_window_count());
4696 if (has_constrained_window ||
4697 content_restrictions & content::CONTENT_RESTRICTION_PRINT) {
4698 print_enabled = false;
4699 advanced_print_enabled = false;
4700 }
4701
4702 // The exception is print preview,
4703 // where advanced printing is always enabled.
4704 printing::PrintPreviewTabController* controller =
4705 printing::PrintPreviewTabController::GetInstance();
4706 if (controller && (controller->GetPrintPreviewForTab(wrapper) ||
4707 controller->is_creating_print_preview_tab())) {
4708 advanced_print_enabled = true;
4709 }
4710 }
4711 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
4712 command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
4713 advanced_print_enabled);
4714}
4715
[email protected]97b46382011-05-02 13:23:044716void Browser::UpdateSaveAsState(int content_restrictions) {
[email protected]4573fbd2011-10-31 20:25:184717 bool enabled = !(content_restrictions & content::CONTENT_RESTRICTION_SAVE);
[email protected]97b46382011-05-02 13:23:044718 PrefService* state = g_browser_process->local_state();
4719 if (state)
4720 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4721
4722 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4723}
4724
4725void Browser::UpdateOpenFileState() {
4726 bool enabled = true;
4727 PrefService* local_state = g_browser_process->local_state();
4728 if (local_state)
4729 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4730
4731 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4732}
4733
[email protected]92655362012-04-20 21:33:174734void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4735 window_->UpdateReloadStopState(is_loading, force);
4736 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
4737}
4738
[email protected]36b6dcb2008-11-12 01:19:574739///////////////////////////////////////////////////////////////////////////////
4740// Browser, UI update coalescing and handling (private):
4741
4742void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:494743 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294744}
4745
[email protected]2a6bc3e2011-12-28 23:51:334746void Browser::ScheduleUIUpdate(const WebContents* source,
[email protected]36b6dcb2008-11-12 01:19:574747 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004748 if (!source)
4749 return;
4750
[email protected]2b4355c2009-04-04 17:55:464751 // Do some synchronous updates.
[email protected]d9083482012-01-06 00:38:464752 if (changed_flags & content::INVALIDATE_TYPE_URL &&
[email protected]4ca15302012-01-03 05:53:204753 source == GetSelectedWebContents()) {
[email protected]36b6dcb2008-11-12 01:19:574754 // Only update the URL for the current tab. Note that we do not update
4755 // the navigation commands since those would have already been updated
4756 // synchronously by NavigationStateChanged.
4757 UpdateToolbar(false);
[email protected]d9083482012-01-06 00:38:464758 changed_flags &= ~content::INVALIDATE_TYPE_URL;
[email protected]36b6dcb2008-11-12 01:19:574759 }
[email protected]d9083482012-01-06 00:38:464760 if (changed_flags & content::INVALIDATE_TYPE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574761 // Update the loading state synchronously. This is so the throbber will
4762 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004763 // this for any tab so they start & stop quickly.
[email protected]2fc15ae2012-05-06 00:01:374764 tab_strip_model_->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:404765 GetIndexOfController(&source->GetController()),
[email protected]6ebdc9b2010-09-27 16:55:574766 TabStripModelObserver::LOADING_ONLY);
[email protected]d9083482012-01-06 00:38:464767 // The status bubble needs to be updated during INVALIDATE_TYPE_LOAD too,
4768 // but we do that asynchronously by not stripping INVALIDATE_TYPE_LOAD from
[email protected]6ebdc9b2010-09-27 16:55:574769 // changed_flags.
[email protected]8030f012009-09-25 18:09:374770 }
4771
[email protected]d9083482012-01-06 00:38:464772 if (changed_flags & content::INVALIDATE_TYPE_TITLE && !source->IsLoading()) {
[email protected]f1cd5e82009-10-23 17:19:034773 // To correctly calculate whether the title changed while not loading
4774 // we need to process the update synchronously. This state only matters for
4775 // the TabStripModel, so we notify the TabStripModel now and notify others
4776 // asynchronously.
[email protected]2fc15ae2012-05-06 00:01:374777 tab_strip_model_->UpdateTabContentsStateAt(
[email protected]41f022e2012-01-31 05:56:404778 GetIndexOfController(&source->GetController()),
[email protected]f1cd5e82009-10-23 17:19:034779 TabStripModelObserver::TITLE_NOT_LOADING);
4780 }
4781
[email protected]2b4355c2009-04-04 17:55:464782 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374783 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464784 return;
[email protected]36b6dcb2008-11-12 01:19:574785
4786 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404787 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574788
[email protected]24f1477532011-11-22 22:55:364789 if (!chrome_updater_factory_.HasWeakPtrs()) {
[email protected]36b6dcb2008-11-12 01:19:574790 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374791 MessageLoop::current()->PostDelayedTask(
4792 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:364793 base::Bind(&Browser::ProcessPendingUIUpdates,
4794 chrome_updater_factory_.GetWeakPtr()),
[email protected]11d6ab1a2012-01-12 21:37:264795 base::TimeDelta::FromMilliseconds(kUIUpdateCoalescingTimeMS));
[email protected]36b6dcb2008-11-12 01:19:574796 }
4797}
4798
4799void Browser::ProcessPendingUIUpdates() {
4800#ifndef NDEBUG
4801 // Validate that all tabs we have pending updates for exist. This is scary
4802 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004803 // deleted tabs.
[email protected]85354982009-09-25 19:58:404804 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4805 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574806 bool found = false;
4807 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]6acde6352012-01-04 16:52:204808 if (GetWebContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574809 found = true;
4810 break;
4811 }
4812 }
4813 DCHECK(found);
4814 }
4815#endif
4816
[email protected]24f1477532011-11-22 22:55:364817 chrome_updater_factory_.InvalidateWeakPtrs();
[email protected]36b6dcb2008-11-12 01:19:574818
[email protected]85354982009-09-25 19:58:404819 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4820 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574821 // Do not dereference |contents|, it may be out-of-date!
[email protected]2a6bc3e2011-12-28 23:51:334822 const WebContents* contents = i->first;
[email protected]85354982009-09-25 19:58:404823 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574824
[email protected]4ca15302012-01-03 05:53:204825 if (contents == GetSelectedWebContents()) {
[email protected]a5231662009-09-26 00:56:004826 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344827
[email protected]d9083482012-01-06 00:38:464828 if (flags & content::INVALIDATE_TYPE_PAGE_ACTIONS) {
[email protected]9800de5e2011-03-11 18:19:494829 LocationBar* location_bar = window()->GetLocationBar();
4830 if (location_bar)
4831 location_bar->UpdatePageActions();
4832 }
[email protected]6ebdc9b2010-09-27 16:55:574833 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]d9083482012-01-06 00:38:464834 if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:444835 GetStatusBubble()->SetStatus(
[email protected]51d83bdf2011-12-09 16:09:294836 GetSelectedTabContentsWrapper()->
4837 core_tab_helper()->GetStatusText());
[email protected]0dd3a0ab2011-02-18 08:17:444838 }
[email protected]a5231662009-09-26 00:56:004839
[email protected]d9083482012-01-06 00:38:464840 if (flags & (content::INVALIDATE_TYPE_TAB |
4841 content::INVALIDATE_TYPE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254842// TODO(pinkerton): Disable app-mode in the model until we implement it
4843// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4844#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004845 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234846 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254847#endif
[email protected]a5231662009-09-26 00:56:004848 window_->UpdateTitleBar();
4849 }
[email protected]4d34e2e2009-05-26 22:55:284850 }
[email protected]36b6dcb2008-11-12 01:19:574851
[email protected]a5231662009-09-26 00:56:004852 // Updates that don't depend upon the selected state go here.
[email protected]d9083482012-01-06 00:38:464853 if (flags &
4854 (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) {
[email protected]2fc15ae2012-05-06 00:01:374855 tab_strip_model_->UpdateTabContentsStateAt(
4856 tab_strip_model_->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034857 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574858 }
4859
4860 // We don't need to process INVALIDATE_STATE, since that's not visible.
4861 }
4862
4863 scheduled_updates_.clear();
4864}
4865
[email protected]d9083482012-01-06 00:38:464866void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
[email protected]36b6dcb2008-11-12 01:19:574867 if (!contents)
4868 return;
4869
[email protected]85354982009-09-25 19:58:404870 UpdateMap::iterator i = scheduled_updates_.find(contents);
4871 if (i != scheduled_updates_.end())
4872 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294873}
4874
[email protected]d938aed92009-01-22 19:49:334875
[email protected]36b6dcb2008-11-12 01:19:574876///////////////////////////////////////////////////////////////////////////////
4877// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294878
[email protected]36b6dcb2008-11-12 01:19:574879StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094880#if !defined(OS_MACOSX)
4881 // In kiosk mode, we want to always hide the status bubble.
4882 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4883 return NULL;
4884#endif
[email protected]9b032bf2009-07-21 17:34:234885 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294886}
4887
[email protected]36b6dcb2008-11-12 01:19:574888///////////////////////////////////////////////////////////////////////////////
4889// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294890
4891void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154892 SessionService* session_service =
4893 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294894 if (session_service) {
4895 for (int i = index; i < tab_count(); ++i) {
[email protected]81898992011-06-14 22:15:004896 TabContentsWrapper* tab = GetTabContentsWrapperAt(i);
4897 if (tab) {
initial.commit09911bf2008-07-26 23:55:294898 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:004899 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404900 session_service->SetPinnedState(
4901 session_id(),
[email protected]81898992011-06-14 22:15:004902 tab->restore_tab_helper()->session_id(),
[email protected]41f022e2012-01-31 05:56:404903 IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294904 }
4905 }
4906 }
4907}
4908
[email protected]36b6dcb2008-11-12 01:19:574909///////////////////////////////////////////////////////////////////////////////
4910// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294911
[email protected]04b4a6c2008-08-02 00:44:474912void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214913 if (!is_attempting_to_close_browser_) {
4914 // Because we might invoke this after a delay it's possible for the value of
4915 // is_attempting_to_close_browser_ to have changed since we scheduled the
4916 // task.
4917 return;
4918 }
initial.commit09911bf2008-07-26 23:55:294919
[email protected]04b4a6c2008-08-02 00:44:474920 if (HasCompletedUnloadProcessing()) {
4921 // We've finished all the unload events and can proceed to close the
4922 // browser.
4923 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294924 return;
4925 }
4926
[email protected]04b4a6c2008-08-02 00:44:474927 // Process beforeunload tabs first. When that queue is empty, process
4928 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474929 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]a81343d232011-12-27 07:39:204930 WebContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244931 // Null check render_view_host here as this gets called on a PostTask and
4932 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524933 if (tab->GetRenderViewHost()) {
4934 tab->GetRenderViewHost()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244935 } else {
[email protected]08f0d612011-01-13 23:58:214936 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244937 }
[email protected]04b4a6c2008-08-02 00:44:474938 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294939 // We've finished firing all beforeunload events and can proceed with unload
4940 // events.
4941 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4942 // somewhere around here so that we have accurate measurements of shutdown
4943 // time.
[email protected]04b4a6c2008-08-02 00:44:474944 // TODO(ojan): We can probably fire all the unload events in parallel and
4945 // get a perf benefit from that in the cases where the tab hangs in it's
4946 // unload handler or takes a long time to page in.
[email protected]a81343d232011-12-27 07:39:204947 WebContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244948 // Null check render_view_host here as this gets called on a PostTask and
4949 // the tab's render_view_host may have been nulled out.
[email protected]151a63d2011-12-20 22:32:524950 if (tab->GetRenderViewHost()) {
4951 tab->GetRenderViewHost()->ClosePage();
[email protected]22484622009-06-10 21:17:244952 } else {
[email protected]08f0d612011-01-13 23:58:214953 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244954 }
initial.commit09911bf2008-07-26 23:55:294955 } else {
[email protected]04b4a6c2008-08-02 00:44:474956 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294957 }
4958}
4959
[email protected]d043c2cc2009-03-25 18:30:454960bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474961 return is_attempting_to_close_browser_ &&
4962 tabs_needing_before_unload_fired_.empty() &&
4963 tabs_needing_unload_fired_.empty();
4964}
4965
4966void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044967 // Closing of window can be canceled from:
4968 // - canceling beforeunload
4969 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474970 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284971 tabs_needing_before_unload_fired_.clear();
4972 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474973 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044974
[email protected]9cc821652012-04-18 18:18:104975 content::NotificationService::current()->Notify(
4976 chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
4977 content::Source<Browser>(this),
4978 content::NotificationService::NoDetails());
4979
[email protected]0b4d3382010-07-14 16:13:044980 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4981 TabCloseableStateWatcher* watcher =
4982 g_browser_process->tab_closeable_state_watcher();
4983 if (watcher)
4984 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474985}
4986
[email protected]a81343d232011-12-27 07:39:204987bool Browser::RemoveFromSet(UnloadListenerSet* set, WebContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474988 DCHECK(is_attempting_to_close_browser_);
4989
[email protected]06b42f032008-12-03 18:43:054990 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4991 if (iter != set->end()) {
4992 set->erase(iter);
4993 return true;
[email protected]04b4a6c2008-08-02 00:44:474994 }
4995 return false;
4996}
initial.commit09911bf2008-07-26 23:55:294997
[email protected]a81343d232011-12-27 07:39:204998void Browser::ClearUnloadState(WebContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044999 // Closing of browser could be canceled (via IsClosingPermitted) between the
5000 // time when request was initiated and when this method is called, so check
5001 // for is_attempting_to_close_browser_ flag before proceeding.
5002 if (is_attempting_to_close_browser_) {
5003 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
5004 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:215005 if (process_now) {
5006 ProcessPendingTabs();
5007 } else {
5008 MessageLoop::current()->PostTask(
5009 FROM_HERE,
[email protected]24f1477532011-11-22 22:55:365010 base::Bind(&Browser::ProcessPendingTabs, weak_factory_.GetWeakPtr()));
[email protected]08f0d612011-01-13 23:58:215011 }
[email protected]0b4d3382010-07-14 16:13:045012 }
initial.commit09911bf2008-07-26 23:55:295013}
5014
[email protected]36b6dcb2008-11-12 01:19:575015///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:065016// Browser, In-progress download termination handling (private):
5017
[email protected]b6a4ac2b2011-10-17 20:05:485018bool Browser::CanCloseWithInProgressDownloads() {
[email protected]5a17d492011-10-24 19:37:035019 // If we've prompted, we need to hear from the user before we
5020 // can close.
5021 if (cancel_download_confirmation_state_ != NOT_PROMPTED)
5022 return cancel_download_confirmation_state_ != WAITING_FOR_RESPONSE;
5023
5024 int num_downloads_blocking;
5025 if (DOWNLOAD_CLOSE_OK ==
5026 OkToCloseWithInProgressDownloads(&num_downloads_blocking))
[email protected]446295a2010-04-19 23:43:005027 return true;
5028
[email protected]5a17d492011-10-24 19:37:035029 // Closing this window will kill some downloads; prompt to make sure
5030 // that's ok.
[email protected]69444cc2009-04-09 20:40:065031 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
5032 window_->ConfirmBrowserCloseWithPendingDownloads();
5033
5034 // Return false so the browser does not close. We'll close if the user
5035 // confirms in the dialog.
5036 return false;
5037}
5038
5039///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:575040// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:295041
[email protected]9219d262011-02-15 21:05:125042void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]075969d2012-04-17 20:05:555043 // WebContents...
[email protected]d9083482012-01-06 00:38:465044 tab->web_contents()->SetDelegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:375045
5046 // ...and all the helpers.
5047 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:145048 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]31145092011-09-30 01:49:445049 tab->constrained_window_tab_helper()->set_delegate(delegate);
[email protected]51d83bdf2011-12-09 16:09:295050 tab->core_tab_helper()->set_delegate(delegate);
[email protected]1739e57d2011-11-30 21:18:255051 tab->extension_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:125052 tab->search_engine_tab_helper()->set_delegate(delegate);
5053}
5054
[email protected]4f3dc372009-02-24 00:10:295055void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:585056 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:295057 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:005058 string16 find_text;
5059#if defined(OS_MACOSX)
5060 // We always want to search for the contents of the find pasteboard on OS X.
5061 find_text = GetFindPboardText();
5062#endif
[email protected]9c318862011-02-01 22:27:245063 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:385064 find_tab_helper()->StartFinding(find_text,
5065 forward_direction,
5066 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:295067 }
[email protected]fbd77592008-11-12 20:50:275068}
[email protected]cb17f7f2009-02-06 18:14:485069
[email protected]36b6dcb2008-11-12 01:19:575070void Browser::CloseFrame() {
5071 window_->Close();
initial.commit09911bf2008-07-26 23:55:295072}
5073
[email protected]3c9e1872010-11-18 16:17:495074void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:175075 DetachType type) {
5076 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:155077 // Save the current location bar state, but only if the tab being detached
5078 // is the selected tab. Because saving state can conditionally revert the
5079 // location bar, saving the current tab's location bar state to a
5080 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:495081 if (contents == GetSelectedTabContentsWrapper()) {
5082 LocationBar* location_bar = window()->GetLocationBar();
5083 if (location_bar)
[email protected]83a2610a2012-01-05 01:00:275084 location_bar->SaveStateToContents(contents->web_contents());
[email protected]9800de5e2011-03-11 18:19:495085 }
[email protected]c37e3b62010-01-22 00:15:175086
[email protected]2fc15ae2012-05-06 00:01:375087 if (!tab_strip_model_->closing_all())
[email protected]c37e3b62010-01-22 00:15:175088 SyncHistoryWithTabs(0);
5089 }
5090
[email protected]9219d262011-02-15 21:05:125091 SetAsDelegate(contents, NULL);
[email protected]d9083482012-01-06 00:38:465092 RemoveScheduledUpdatesFor(contents->web_contents());
[email protected]c37e3b62010-01-22 00:15:175093
[email protected]41f022e2012-01-31 05:56:405094 if (find_bar_controller_.get() && index == 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.
[email protected]d9083482012-01-06 00:38:465103 ClearUnloadState(contents->web_contents(), false);
[email protected]08f0d612011-01-13 23:58:215104 }
5105
[email protected]432115822011-07-10 15:52:275106 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]fbc5e5f92012-01-02 06:08:325107 content::Source<WebContents>(contents->web_contents()));
[email protected]e397a4472011-12-21 21:47:505108 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_DETACHED,
[email protected]4b19ea52012-01-02 20:15:255109 content::Source<WebContents>(contents->web_contents()));
[email protected]fbc5e5f92012-01-02 06:08:325110 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
5111 content::Source<WebContents>(contents->web_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]92655362012-04-20 21:33:175127void Browser::ReloadInternal(WindowOpenDisposition disposition,
5128 bool ignore_cache) {
5129 // If we are showing an interstitial, treat this as an OpenURL.
5130 WebContents* current_tab = GetSelectedWebContents();
5131 if (current_tab && current_tab->ShowingInterstitialPage()) {
5132 NavigationEntry* entry = current_tab->GetController().GetActiveEntry();
5133 DCHECK(entry); // Should exist if interstitial is showing.
5134 OpenURL(OpenURLParams(
5135 entry->GetURL(), Referrer(), disposition,
5136 content::PAGE_TRANSITION_RELOAD, false));
[email protected]281918912010-05-27 22:05:135137 return;
[email protected]92655362012-04-20 21:33:175138 }
[email protected]281918912010-05-27 22:05:135139
[email protected]92655362012-04-20 21:33:175140 // As this is caused by a user action, give the focus to the page.
5141 //
5142 // Also notify RenderViewHostDelegate of the user gesture; this is
5143 // normally done in Browser::Navigate, but a reload bypasses Navigate.
5144 WebContents* tab = GetOrCloneTabForDisposition(disposition);
5145 tab->GetRenderViewHost()->GetDelegate()->OnUserGesture();
5146 if (!tab->FocusLocationBarByDefault())
5147 tab->Focus();
5148 if (ignore_cache)
5149 tab->GetController().ReloadIgnoringCache(true);
5150 else
5151 tab->GetController().Reload(true);
[email protected]281918912010-05-27 22:05:135152}
[email protected]97b6c4f2010-09-27 19:31:265153
[email protected]92655362012-04-20 21:33:175154WebContents* Browser::GetOrCloneTabForDisposition(
5155 WindowOpenDisposition disposition) {
5156 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
5157 switch (disposition) {
5158 case NEW_FOREGROUND_TAB:
5159 case NEW_BACKGROUND_TAB: {
5160 current_tab = current_tab->Clone();
[email protected]2fc15ae2012-05-06 00:01:375161 tab_strip_model_->AddTabContents(
[email protected]92655362012-04-20 21:33:175162 current_tab, -1, content::PAGE_TRANSITION_LINK,
5163 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
5164 TabStripModel::ADD_NONE);
5165 break;
5166 }
5167 case NEW_WINDOW: {
5168 current_tab = current_tab->Clone();
5169 Browser* browser = Browser::Create(profile_);
5170 browser->tabstrip_model()->AddTabContents(
5171 current_tab, -1, content::PAGE_TRANSITION_LINK,
5172 TabStripModel::ADD_ACTIVE);
5173 browser->window()->Show();
5174 break;
5175 }
5176 default:
5177 break;
5178 }
5179 return current_tab->web_contents();
5180}
5181
5182bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
5183 bool check_fullscreen) const {
5184 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
5185 // other platforms, we hide some controls when in fullscreen mode.
5186 bool hide_ui_for_fullscreen = false;
5187#if !defined(OS_MACOSX)
5188 hide_ui_for_fullscreen = check_fullscreen && window_ &&
5189 window_->IsFullscreen();
5190#endif
5191
5192 unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF;
5193
5194 if (is_type_tabbed())
5195 features |= FEATURE_BOOKMARKBAR;
5196
5197 if (!hide_ui_for_fullscreen) {
5198 if (!is_type_tabbed())
5199 features |= FEATURE_TITLEBAR;
5200
5201 if (is_type_tabbed())
5202 features |= FEATURE_TABSTRIP;
5203
5204 if (is_type_tabbed())
5205 features |= FEATURE_TOOLBAR;
5206
5207 if (!is_app())
5208 features |= FEATURE_LOCATIONBAR;
5209 }
5210 return !!(features & feature);
5211}
5212
5213bool Browser::IsClosingPermitted() {
5214 TabCloseableStateWatcher* watcher =
5215 g_browser_process->tab_closeable_state_watcher();
5216 bool can_close = !watcher || watcher->CanCloseBrowser(this);
5217 if (!can_close && is_attempting_to_close_browser_)
5218 CancelWindowClose();
5219 return can_close;
[email protected]3c9e1872010-11-18 16:17:495220}
5221
[email protected]6b723f82010-10-05 20:14:275222bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]3e481282011-10-15 15:39:505223 if (!instant() || !instant()->PrepareForCommit() ||
[email protected]35242602011-01-06 16:38:535224 disposition == NEW_BACKGROUND_TAB) {
5225 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
5226 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:265227 return false;
[email protected]35242602011-01-06 16:38:535228 }
[email protected]97b6c4f2010-09-27 19:31:265229
5230 if (disposition == CURRENT_TAB) {
[email protected]ad50def52011-10-19 23:17:075231 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275232 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535233 content::Source<TabContentsWrapper>(instant()->CommitCurrentPreview(
[email protected]094b0522011-10-06 00:55:275234 INSTANT_COMMIT_PRESSED_ENTER)),
[email protected]ad50def52011-10-19 23:17:075235 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265236 return true;
5237 }
[email protected]35242602011-01-06 16:38:535238 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:495239 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]5419ff92012-01-06 21:17:155240 INSTANT_COMMIT_PRESSED_ENTER, NULL);
[email protected]a0df03c122011-01-05 00:22:555241 // HideInstant is invoked after release so that InstantController is not
5242 // active when HideInstant asks it for its state.
5243 HideInstant();
[email protected]d9083482012-01-06 00:38:465244 preview_contents->web_contents()->GetController().PruneAllButActive();
[email protected]2fc15ae2012-05-06 00:01:375245 tab_strip_model_->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:265246 preview_contents,
5247 -1,
[email protected]6b723f82010-10-05 20:14:275248 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:415249 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:375250 instant()->CompleteRelease(preview_contents);
[email protected]ad50def52011-10-19 23:17:075251 content::NotificationService::current()->Notify(
[email protected]094b0522011-10-06 00:55:275252 chrome::NOTIFICATION_INSTANT_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:535253 content::Source<TabContentsWrapper>(preview_contents),
[email protected]ad50def52011-10-19 23:17:075254 content::NotificationService::NoDetails());
[email protected]97b6c4f2010-09-27 19:31:265255 return true;
5256 }
5257 // The omnibox currently doesn't use other dispositions, so we don't attempt
5258 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
5259 // support for the new disposition.
5260 NOTREACHED();
5261 return false;
5262}
[email protected]2031cf9d2010-10-12 05:05:375263
5264void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:145265 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:375266 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:195267 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:295268 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:375269 }
5270}
[email protected]77d8d622010-12-15 10:30:125271
5272void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:275273 DCHECK(contents);
5274
[email protected]10f417c52011-12-28 21:04:235275 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:465276 contents->web_contents()->GetController().GetActiveEntry();
[email protected]932b7a12011-03-09 12:50:275277 if (!active_entry)
5278 return;
5279
[email protected]36fc0392011-12-25 03:59:515280 ViewSource(contents, active_entry->GetURL(), active_entry->GetContentState());
[email protected]932b7a12011-03-09 12:50:275281}
5282
5283void Browser::ViewSource(TabContentsWrapper* contents,
5284 const GURL& url,
5285 const std::string& content_state) {
[email protected]7f6f44c2011-12-14 13:23:385286 content::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:125287 DCHECK(contents);
5288
5289 TabContentsWrapper* view_source_contents = contents->Clone();
[email protected]d9083482012-01-06 00:38:465290 view_source_contents->web_contents()->GetController().PruneAllButActive();
[email protected]10f417c52011-12-28 21:04:235291 NavigationEntry* active_entry =
[email protected]d9083482012-01-06 00:38:465292 view_source_contents->web_contents()->GetController().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:505293 if (!active_entry)
5294 return;
5295
[email protected]932b7a12011-03-09 12:50:275296 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
5297 url.spec());
[email protected]36fc0392011-12-25 03:59:515298 active_entry->SetVirtualURL(view_source_url);
[email protected]1436beff2010-12-16 19:47:045299
[email protected]932b7a12011-03-09 12:50:275300 // Do not restore scroller position.
[email protected]36fc0392011-12-25 03:59:515301 active_entry->SetContentState(
[email protected]932b7a12011-03-09 12:50:275302 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
5303
[email protected]cd3d50d2010-12-18 21:03:295304 // Do not restore title, derive it from the url.
[email protected]36fc0392011-12-25 03:59:515305 active_entry->SetTitle(string16());
[email protected]77d8d622010-12-15 10:30:125306
[email protected]47b309f2010-12-28 17:35:565307 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:125308 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
5309 // If this is a tabbed browser, just create a duplicate tab inside the same
5310 // window next to the tab being duplicated.
[email protected]2fc15ae2012-05-06 00:01:375311 int index = tab_strip_model_->GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:415312 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:565313 TabStripModel::ADD_INHERIT_GROUP;
[email protected]2fc15ae2012-05-06 00:01:375314 tab_strip_model_->InsertTabContentsAt(index + 1, view_source_contents,
5315 add_types);
[email protected]77d8d622010-12-15 10:30:125316 } else {
[email protected]da22aa62012-04-04 18:54:355317 Browser* browser = Browser::CreateWithParams(
5318 Browser::CreateParams(TYPE_TABBED, profile_));
[email protected]77d8d622010-12-15 10:30:125319
5320 // Preserve the size of the original window. The new window has already
5321 // been given an offset by the OS, so we shouldn't copy the old bounds.
5322 BrowserWindow* new_window = browser->window();
5323 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
5324 window()->GetRestoredBounds().size()));
5325
5326 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]075969d2012-04-17 20:05:555327 // WebContents is invisible and won't size it.
[email protected]77d8d622010-12-15 10:30:125328 browser->window()->Show();
5329
5330 // The page transition below is only for the purpose of inserting the tab.
[email protected]2905f742011-10-13 03:51:585331 browser->AddTab(view_source_contents, content::PAGE_TRANSITION_LINK);
[email protected]77d8d622010-12-15 10:30:125332 }
5333
[email protected]92371eb2011-04-28 11:50:155334 SessionService* session_service =
5335 SessionServiceFactory::GetForProfileIfExisting(profile_);
5336 if (session_service)
[email protected]81898992011-06-14 22:15:005337 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:125338}
[email protected]b9163e02011-04-20 16:03:375339
5340int Browser::GetContentRestrictionsForSelectedTab() {
5341 int content_restrictions = 0;
[email protected]4ca15302012-01-03 05:53:205342 WebContents* current_tab = GetSelectedWebContents();
[email protected]b9163e02011-04-20 16:03:375343 if (current_tab) {
[email protected]0bfbf882011-12-22 18:19:275344 content_restrictions = current_tab->GetContentRestrictions();
[email protected]10f417c52011-12-28 21:04:235345 NavigationEntry* active_entry =
[email protected]f5fa20e2011-12-21 22:35:565346 current_tab->GetController().GetActiveEntry();
[email protected]b9163e02011-04-20 16:03:375347 // See comment in UpdateCommandsForTabState about why we call url().
[email protected]a53209b2012-01-20 16:48:165348 if (!download_util::IsSavableURL(
[email protected]36fc0392011-12-25 03:59:515349 active_entry ? active_entry->GetURL() : GURL())
[email protected]0bfbf882011-12-22 18:19:275350 || current_tab->ShowingInterstitialPage())
[email protected]4573fbd2011-10-31 20:25:185351 content_restrictions |= content::CONTENT_RESTRICTION_SAVE;
[email protected]0bfbf882011-12-22 18:19:275352 if (current_tab->ShowingInterstitialPage())
[email protected]e397a4472011-12-21 21:47:505353 content_restrictions |= content::CONTENT_RESTRICTION_PRINT;
[email protected]b9163e02011-04-20 16:03:375354 }
5355 return content_restrictions;
5356}
[email protected]09b29342011-06-24 19:18:485357
5358void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
5359 BookmarkBar::State state;
[email protected]227393e2011-06-29 21:28:395360 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
[email protected]3710d0002011-10-11 00:35:005361 if (browser_defaults::bookmarks_enabled &&
5362 profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
[email protected]227393e2011-06-29 21:28:395363 (!window_ || !window_->IsFullscreen())) {
[email protected]09b29342011-06-24 19:18:485364 state = BookmarkBar::SHOW;
5365 } else {
5366 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
5367 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
5368 state = BookmarkBar::DETACHED;
5369 else
5370 state = BookmarkBar::HIDDEN;
5371 }
5372 if (state == bookmark_bar_state_)
5373 return;
5374
5375 bookmark_bar_state_ = state;
5376
5377 if (!window_)
5378 return; // This is called from the constructor when window_ is NULL.
5379
5380 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
5381 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
5382 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
5383 // end up querying state once they process the tab switch.
5384 return;
5385 }
5386
5387 BookmarkBar::AnimateChangeType animate_type =
5388 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
5389 BookmarkBar::ANIMATE_STATE_CHANGE :
5390 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
5391 window_->BookmarkBarStateChanged(animate_type);
5392}
[email protected]2e2cacc2011-07-12 21:54:265393
[email protected]92655362012-04-20 21:33:175394void Browser::OpenBookmarkManagerWithHash(const std::string& action,
5395 int64 node_id) {
5396 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
5397 content::RecordAction(UserMetricsAction("ShowBookmarks"));
5398 browser::NavigateParams params(GetSingletonTabNavigateParams(
5399 GURL(chrome::kChromeUIBookmarksURL).Resolve(
5400 StringPrintf("/#%s%s", action.c_str(),
5401 base::Int64ToString(node_id).c_str()))));
5402 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
5403 ShowSingletonTabOverwritingNTP(params);
[email protected]2e2cacc2011-07-12 21:54:265404}
[email protected]afcb43562011-09-02 23:33:385405
[email protected]92655362012-04-20 21:33:175406bool Browser::MaybeCreateBackgroundContents(int route_id,
5407 WebContents* opener_web_contents,
5408 const string16& frame_name,
5409 const GURL& target_url) {
5410 GURL opener_url = opener_web_contents->GetURL();
5411 ExtensionService* extensions_service = profile_->GetExtensionService();
5412
5413 if (!opener_url.is_valid() ||
5414 frame_name.empty() ||
5415 !extensions_service ||
5416 !extensions_service->is_ready())
5417 return false;
5418
5419 // Only hosted apps have web extents, so this ensures that only hosted apps
5420 // can create BackgroundContents. We don't have to check for background
5421 // permission as that is checked in RenderMessageFilter when the CreateWindow
5422 // message is processed.
5423 const Extension* extension =
5424 extensions_service->extensions()->GetHostedAppByURL(
5425 ExtensionURLInfo(opener_url));
5426 if (!extension)
5427 return false;
5428
5429 // No BackgroundContents allowed if BackgroundContentsService doesn't exist.
5430 BackgroundContentsService* service =
5431 BackgroundContentsServiceFactory::GetForProfile(profile_);
5432 if (!service)
5433 return false;
5434
5435 // Ensure that we're trying to open this from the extension's process.
5436 SiteInstance* opener_site_instance = opener_web_contents->GetSiteInstance();
5437 extensions::ProcessMap* process_map = extensions_service->process_map();
5438 if (!opener_site_instance->GetProcess() ||
5439 !process_map->Contains(
5440 extension->id(), opener_site_instance->GetProcess()->GetID())) {
5441 return false;
5442 }
5443
5444 // Only allow a single background contents per app.
5445 bool allow_js_access = extension->allow_background_js_access();
5446 BackgroundContents* existing =
5447 service->GetAppBackgroundContents(ASCIIToUTF16(extension->id()));
5448 if (existing) {
5449 // For non-scriptable background contents, ignore the request altogether,
5450 // (returning true, so that a regular WebContents isn't created either).
5451 if (!allow_js_access)
5452 return true;
5453 // For scriptable background pages, if one already exists, close it (even
5454 // if it was specified in the manifest).
5455 DLOG(INFO) << "Closing existing BackgroundContents for " << opener_url;
5456 delete existing;
5457 }
5458
5459 // If script access is not allowed, create the the background contents in a
5460 // new SiteInstance, so that a separate process is used.
5461 scoped_refptr<content::SiteInstance> site_instance =
5462 allow_js_access ?
5463 opener_site_instance :
5464 content::SiteInstance::Create(opener_web_contents->GetBrowserContext());
5465
5466 // Passed all the checks, so this should be created as a BackgroundContents.
5467 BackgroundContents* contents = service->CreateBackgroundContents(
5468 site_instance,
5469 route_id,
5470 profile_,
5471 frame_name,
5472 ASCIIToUTF16(extension->id()));
5473
5474 // When a separate process is used, the original renderer cannot access the
5475 // new window later, thus we need to navigate the window now.
5476 if (contents && !allow_js_access) {
5477 contents->web_contents()->GetController().LoadURL(
5478 target_url,
5479 content::Referrer(),
5480 content::PAGE_TRANSITION_LINK,
5481 std::string()); // No extra headers.
5482 }
5483
5484 return contents != NULL;
[email protected]afcb43562011-09-02 23:33:385485}