blob: e6b402a555da5b89acaaded0f0c8ef70d03da88b [file] [log] [blame]
[email protected]35d06152011-01-10 22:19:421// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]7b5dc002010-11-16 23:08:105#include "chrome/browser/ui/browser.h"
[email protected]c61db1d2009-02-06 03:39:186
[email protected]aca02cf2010-05-03 18:56:017#if defined(OS_WIN)
8#include <shellapi.h>
9#include <windows.h>
10#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]8a53ee042009-01-21 16:41:3316#include "base/command_line.h"
[email protected]8a53ee042009-01-21 16:41:3317#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3818#include "base/metrics/histogram.h"
[email protected]b02d0382009-11-30 21:19:5019#include "base/path_service.h"
[email protected]8a53ee042009-01-21 16:41:3320#include "base/string_util.h"
[email protected]34b99632011-01-01 01:01:0621#include "base/threading/thread.h"
22#include "base/threading/thread_restrictions.h"
[email protected]7f070d42011-03-09 20:25:3223#include "base/time.h"
[email protected]6524385ef2010-08-18 06:34:1324#include "base/utf_string_conversions.h"
[email protected]1a3aba82010-11-08 23:52:5425#include "chrome/app/chrome_command_ids.h"
[email protected]cf28ec52010-04-09 22:56:3426#include "chrome/browser/autofill/autofill_manager.h"
[email protected]2c4fb7b2011-04-02 06:33:2927#include "chrome/browser/background_contents_service.h"
[email protected]a9afddb2009-02-12 17:49:4228#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5429#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]5c238752009-06-13 10:29:0730#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1831#include "chrome/browser/browser_shutdown.h"
[email protected]1518b0d2010-04-02 18:38:5332#include "chrome/browser/browser_url_handler.h"
[email protected]40d59ce52009-03-06 23:20:1433#include "chrome/browser/character_encoding.h"
[email protected]40ecc902009-03-16 13:42:4734#include "chrome/browser/debugger/devtools_manager.h"
[email protected]2a8a98122010-07-16 11:58:4835#include "chrome/browser/debugger/devtools_toggle_action.h"
[email protected]8e48e982009-12-25 11:22:4636#include "chrome/browser/debugger/devtools_window.h"
[email protected]6c69796d2010-07-16 21:41:1637#include "chrome/browser/download/download_item.h"
[email protected]59560e0b2009-06-04 03:30:2238#include "chrome/browser/download/download_item_model.h"
[email protected]69444cc2009-04-09 20:40:0639#include "chrome/browser/download/download_manager.h"
[email protected]59560e0b2009-06-04 03:30:2240#include "chrome/browser/download/download_shelf.h"
41#include "chrome/browser/download/download_started_animation.h"
[email protected]3ea60632011-04-08 18:25:4242#include "chrome/browser/download/save_package.h"
[email protected]bb461532010-11-26 21:50:2343#include "chrome/browser/extensions/crx_installer.h"
[email protected]9fd542df2009-09-30 07:32:0144#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]0c6da502009-08-14 22:32:3945#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
[email protected]6d7a6042010-08-12 20:12:4246#include "chrome/browser/extensions/extension_host.h"
[email protected]10abd192010-09-30 02:03:4947#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0048#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0849#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5950#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0451#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]820735792010-07-29 23:40:0152#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4953#include "chrome/browser/google/google_url_tracker.h"
54#include "chrome/browser/google/google_util.h"
[email protected]6b723f82010-10-05 20:14:2755#include "chrome/browser/instant/instant_controller.h"
[email protected]5aab5e22010-12-08 22:13:2956#include "chrome/browser/instant/instant_unload_handler.h"
[email protected]90f39902009-10-03 04:25:3757#include "chrome/browser/net/browser_url_util.h"
[email protected]a239c3f2009-02-17 22:13:1958#include "chrome/browser/net/url_fixer_upper.h"
[email protected]2c4fb7b2011-04-02 06:33:2959#include "chrome/browser/notifications/notification_ui_manager.h"
[email protected]14a000d2010-04-29 21:44:2460#include "chrome/browser/platform_util.h"
[email protected]37858e52010-08-26 00:22:0261#include "chrome/browser/prefs/pref_service.h"
[email protected]02337592010-09-27 18:38:2562#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]8ecad5e2010-12-02 21:18:3363#include "chrome/browser/profiles/profile.h"
[email protected]85e921fb82009-02-11 23:19:4464#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1565#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1866#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0667#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1568#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1369#include "chrome/browser/sync/profile_sync_service.h"
[email protected]40f047972009-11-25 03:54:4070#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0471#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2972#include "chrome/browser/tab_contents/background_contents.h"
[email protected]7cceebac2011-03-03 00:32:2173#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]07d490bc2011-03-07 17:05:2674#include "chrome/browser/tabs/tab_finder.h"
[email protected]c848d3d92010-09-16 21:57:4575#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]3ab9cb82011-06-03 18:02:0776#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:3777#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:1478#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]55452902011-06-01 21:57:4779#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:0480#include "chrome/browser/ui/browser_list.h"
[email protected]fb7da4132011-03-15 15:51:0081#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]00070c732011-04-09 15:31:3382#include "chrome/browser/ui/browser_window.h"
[email protected]3ea60632011-04-08 18:25:4283#include "chrome/browser/ui/download/download_tab_helper.h"
[email protected]45300ad42010-12-02 15:51:1484#include "chrome/browser/ui/find_bar/find_bar.h"
85#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:3886#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1987#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:4388#include "chrome/browser/ui/panels/panel.h"
89#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:1290#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1991#include "chrome/browser/ui/status_bubble.h"
92#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:4493#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:1994#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]f847e6082011-03-24 00:08:2695#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]edc37b42011-04-18 20:43:3996#include "chrome/browser/ui/webui/active_downloads_ui.h"
[email protected]265a1492011-02-27 05:58:0797#include "chrome/browser/ui/webui/bug_report_ui.h"
[email protected]5c557f372011-02-26 15:09:2098#include "chrome/browser/ui/webui/options/content_settings_handler.h"
[email protected]692c5342011-05-25 19:16:2199#include "chrome/browser/ui/webui/web_ui_util.h"
[email protected]9a800652010-12-02 17:08:44100#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54101#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50102#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33103#include "chrome/common/chrome_constants.h"
104#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:58105#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33106#include "chrome/common/extensions/extension_constants.h"
[email protected]15b2c6a2011-05-16 23:54:40107#include "chrome/common/extensions/extension_messages.h"
[email protected]8a53ee042009-01-21 16:41:33108#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25109#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34110#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23111#include "chrome/common/web_apps.h"
[email protected]b6021d32011-02-26 01:25:54112#include "content/browser/host_zoom_map.h"
[email protected]a01efd22011-03-01 00:38:32113#include "content/browser/renderer_host/render_view_host.h"
114#include "content/browser/site_instance.h"
[email protected]a01efd22011-03-01 00:38:32115#include "content/browser/tab_contents/interstitial_page.h"
116#include "content/browser/tab_contents/navigation_controller.h"
117#include "content/browser/tab_contents/navigation_entry.h"
[email protected]a01efd22011-03-01 00:38:32118#include "content/browser/tab_contents/tab_contents_view.h"
[email protected]afd1e522011-04-27 23:29:59119#include "content/browser/user_metrics.h"
[email protected]763ec4ca2011-04-29 15:48:12120#include "content/common/content_restriction.h"
[email protected]7f070d42011-03-09 20:25:32121#include "content/common/notification_service.h"
[email protected]4dd57932011-03-17 06:06:12122#include "content/common/page_transition_types.h"
[email protected]216813952011-05-19 22:21:26123#include "content/common/page_zoom.h"
124#include "content/common/view_messages.h"
[email protected]a3e18c42009-03-04 23:36:05125#include "grit/chromium_strings.h"
126#include "grit/generated_resources.h"
127#include "grit/locale_settings.h"
[email protected]8a53ee042009-01-21 16:41:33128#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33129#include "net/base/net_util.h"
130#include "net/base/registry_controlled_domain.h"
131#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39132#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17133#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38134#include "ui/gfx/point.h"
[email protected]1436beff2010-12-16 19:47:04135#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33136#include "webkit/glue/window_open_disposition.h"
[email protected]8a53ee042009-01-21 16:41:33137
138#if defined(OS_WIN)
[email protected]b99603c2010-12-30 22:13:32139#include "app/win/shell.h"
[email protected]36d5e5592010-11-15 20:45:59140#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15141#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59142#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12143#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19144#include "chrome/browser/ui/view_ids.h"
145#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]8a53ee042009-01-21 16:41:33146#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33147
[email protected]6a4f5af22009-09-23 22:43:00148#if defined(OS_MACOSX)
[email protected]7d791652010-12-01 16:34:49149#include "chrome/browser/ui/cocoa/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00150#endif
151
[email protected]b7969202010-05-14 21:29:26152#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35153#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]ec2fd5a2011-04-30 06:16:05154#include "chrome/browser/extensions/file_manager_util.h"
[email protected]b7969202010-05-14 21:29:26155#endif
156
[email protected]8a53ee042009-01-21 16:41:33157using base::TimeDelta;
initial.commit09911bf2008-07-26 23:55:29158
[email protected]36b6dcb2008-11-12 01:19:57159///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29160
[email protected]505323e22009-01-24 02:47:58161namespace {
162
[email protected]91a79232010-11-10 18:15:08163// The URL to be loaded to display Help.
[email protected]8332c162011-01-26 12:01:54164const char kHelpContentUrl[] =
[email protected]91a79232010-11-10 18:15:08165#if defined(OS_CHROMEOS)
[email protected]8332c162011-01-26 12:01:54166 #if defined(OFFICIAL_BUILD)
167 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html";
168 #else
[email protected]95fc6f92011-04-13 00:37:20169 "https://www.google.com/support/chromeos/";
[email protected]8332c162011-01-26 12:01:54170 #endif
[email protected]91a79232010-11-10 18:15:08171#else
[email protected]95fc6f92011-04-13 00:37:20172 "https://www.google.com/support/chrome/";
[email protected]91a79232010-11-10 18:15:08173#endif
174
175// The URL to be opened when the Help link on the Autofill dialog is clicked.
176const char kAutofillHelpUrl[] =
177#if defined(OS_CHROMEOS)
[email protected]95fc6f92011-04-13 00:37:20178 "https://www.google.com/support/chromeos/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08179#else
[email protected]95fc6f92011-04-13 00:37:20180 "https://www.google.com/support/chrome/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08181#endif
182
183// The URL to be loaded to display the "Report a broken page" form.
184const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20185 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08186 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
187
188// The URL for the privacy dashboard.
189const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
190
191// How long we wait before updating the browser chrome while loading a page.
192const int kUIUpdateCoalescingTimeMS = 200;
193
194const char kHashMark[] = "#";
195
[email protected]505323e22009-01-24 02:47:58196} // namespace
197
[email protected]e838eaf2010-10-13 18:53:33198extern bool g_log_bug53991;
199
[email protected]b35b26b32011-05-05 20:35:14200////////////////////////////////////////////////////////////////////////////////
201// Browser, CreateParams:
202
203Browser::CreateParams::CreateParams(Type type, Profile* profile)
204 : type(type),
205 profile(profile) {
206}
207
[email protected]36b6dcb2008-11-12 01:19:57208///////////////////////////////////////////////////////////////////////////////
209// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29210
[email protected]299dabd2008-11-19 02:27:16211Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05212 : type_(type),
213 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39214 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40215 ALLOW_THIS_IN_INITIALIZER_LIST(
216 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14217 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29218 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05219 chrome_updater_factory_(this),
220 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06221 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]2e716622009-03-09 21:11:01222 maximized_state_(MAXIMIZED_STATE_DEFAULT),
[email protected]867125a02009-12-10 06:01:48223 method_factory_(this),
224 block_command_execution_(false),
225 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51226 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00227 pending_web_app_action_(NONE),
228 ALLOW_THIS_IN_INITIALIZER_LIST(
229 tab_restore_service_delegate_(
230 new BrowserTabRestoreServiceDelegate(this))) {
[email protected]0cb94102009-05-22 19:51:21231 registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED,
232 NotificationService::AllSources());
[email protected]0c6da502009-08-14 22:32:39233 registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
234 NotificationService::AllSources());
[email protected]ad0c2e1b2010-01-30 00:00:10235 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
236 NotificationService::AllSources());
[email protected]0cb94102009-05-22 19:51:21237 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
238 NotificationService::AllSources());
[email protected]0dfe05c2011-02-23 23:03:36239 registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
240 NotificationService::AllSources());
[email protected]a4ed6282009-12-14 20:51:16241 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED,
[email protected]371ed7a2009-08-25 15:22:46242 NotificationService::AllSources());
[email protected]e001d412009-06-26 20:53:25243 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
244 NotificationService::AllSources());
[email protected]9a9a9e22011-05-13 22:20:35245 registrar_.Add(this, NotificationType::TAB_CONTENT_SETTINGS_CHANGED,
246 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29247
[email protected]91e1bd82009-09-03 22:04:40248 // Need to know when to alert the user of theme install delay.
249 registrar_.Add(this, NotificationType::EXTENSION_READY_FOR_INSTALL,
250 NotificationService::AllSources());
251
[email protected]9e823662010-10-13 23:36:00252 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04253 if (local_state) {
254 local_pref_registrar_.Init(local_state);
255 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
256 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
257 }
258
259 profile_pref_registrar_.Init(profile_->GetPrefs());
260 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
261 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
262 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]9e823662010-10-13 23:36:00263
initial.commit09911bf2008-07-26 23:55:29264 InitCommandState();
265 BrowserList::AddBrowser(this);
266
[email protected]97b46382011-05-02 13:23:04267 // NOTE: These prefs all need to be explicitly destroyed in the destructor
268 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29269 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
270 profile_->GetPrefs(), NULL);
[email protected]b9c505b2010-04-30 15:05:10271 use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
[email protected]ac86c982011-05-11 13:26:05272 use_compact_navigation_bar_.Init(prefs::kUseCompactNavigationBar,
273 profile_->GetPrefs(),
274 this);
[email protected]97b46382011-05-02 13:23:04275
[email protected]b9c505b2010-04-30 15:05:10276 if (!TabMenuModel::AreVerticalTabsEnabled()) {
277 // If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
278 // might show vertical tabs but not show an option to turn them off.
279 use_vertical_tabs_.SetValue(false);
280 }
[email protected]ac86c982011-05-11 13:26:05281 if (!TabMenuModel::IsCompactNavigationModeEnabled()) {
282 // If the compact navigation bar isn't enabled, explicitly turn it off.
283 // Otherwise we might show the compact navigation bar but not show an option
284 // to turn it off.
285 use_compact_navigation_bar_.SetValue(false);
286 }
287
[email protected]b3344872010-05-03 15:52:29288 UpdateTabStripModelInsertionPolicy();
[email protected]281918912010-05-27 22:05:13289
[email protected]92371eb2011-04-28 11:50:15290 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13291 if (tab_restore_service_) {
292 tab_restore_service_->AddObserver(this);
293 TabRestoreServiceChanged(tab_restore_service_);
294 }
[email protected]d3b98c82010-07-14 07:45:59295
296 if (profile_->GetProfileSyncService())
297 profile_->GetProfileSyncService()->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30298
[email protected]2031cf9d2010-10-12 05:05:37299 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26300
301 // Make sure TabFinder has been created. This does nothing if TabFinder is
302 // not enabled.
303 TabFinder::GetInstance();
initial.commit09911bf2008-07-26 23:55:29304}
305
306Browser::~Browser() {
[email protected]5044da82010-10-27 01:09:16307 VLOG_IF(1, g_log_bug53991) << "~Browser: " << profile_->IsOffTheRecord()
308 << "; stillActive="
309 << BrowserList::IsOffTheRecordSessionActive();
[email protected]e838eaf2010-10-13 18:53:33310
[email protected]d3b98c82010-07-14 07:45:59311 if (profile_->GetProfileSyncService())
312 profile_->GetProfileSyncService()->RemoveObserver(this);
313
initial.commit09911bf2008-07-26 23:55:29314 BrowserList::RemoveBrowser(this);
315
[email protected]7be64502011-05-03 17:51:47316#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29317 if (!BrowserList::HasBrowserWithProfile(profile_)) {
318 // We're the last browser window with this profile. We need to nuke the
319 // TabRestoreService, which will start the shutdown of the
320 // NavigationControllers and allow for proper shutdown. If we don't do this
321 // chrome won't shutdown cleanly, and may end up crashing when some
322 // thread tries to use the IO thread (or another thread) that is no longer
323 // valid.
[email protected]fbc947b2009-06-19 13:28:24324 // This isn't a valid assumption for Mac OS, as it stays running after
325 // the last browser has closed. The Mac equivalent is in its app
326 // controller.
[email protected]92371eb2011-04-28 11:50:15327 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29328 }
[email protected]fbc947b2009-06-19 13:28:24329#endif
initial.commit09911bf2008-07-26 23:55:29330
[email protected]92371eb2011-04-28 11:50:15331 SessionService* session_service =
332 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29333 if (session_service)
334 session_service->WindowClosed(session_id_);
335
[email protected]92371eb2011-04-28 11:50:15336 TabRestoreService* tab_restore_service =
337 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]d8375fd2008-11-25 22:45:39338 if (tab_restore_service)
[email protected]fb7da4132011-03-15 15:51:00339 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39340
[email protected]97b46382011-05-02 13:23:04341 profile_pref_registrar_.RemoveAll();
342 local_pref_registrar_.RemoveAll();
343
[email protected]9a8c4022011-01-25 14:25:33344 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33345 use_vertical_tabs_.Destroy();
[email protected]ac86c982011-05-11 13:26:05346 use_compact_navigation_bar_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33347
initial.commit09911bf2008-07-26 23:55:29348 if (profile_->IsOffTheRecord() &&
349 !BrowserList::IsOffTheRecordSessionActive()) {
[email protected]0d1add32011-04-07 00:06:50350 // An incognito profile is no longer needed, this indirectly
[email protected]860f55492009-03-27 19:50:59351 // frees its cache and cookies.
352 profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
initial.commit09911bf2008-07-26 23:55:29353 }
354
355 // There may be pending file dialogs, we need to tell them that we've gone
356 // away so they don't try and call back to us.
357 if (select_file_dialog_.get())
358 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13359
360 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29361}
362
[email protected]15952e462008-11-14 00:29:05363// static
364Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14365 Browser* browser = new Browser(TYPE_TABBED, profile);
366 browser->InitBrowserWindow();
367 return browser;
368}
369
370// static
371Browser* Browser::CreateWithParams(const CreateParams& params) {
372 Browser* browser = new Browser(params.type, params.profile);
373 browser->app_name_ = params.app_name;
374 if (!params.initial_bounds.IsEmpty())
375 browser->set_override_bounds(params.initial_bounds);
[email protected]9800de5e2011-03-11 18:19:49376 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05377 return browser;
378}
[email protected]6104acf2008-11-11 22:27:34379
[email protected]15952e462008-11-14 00:29:05380// static
[email protected]9ee17e8c2010-08-10 19:17:31381Browser* Browser::CreateForType(Type type, Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14382 CreateParams params(type, profile);
383 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05384}
385
386// static
[email protected]b35b26b32011-05-05 20:35:14387Browser* Browser::CreateForApp(Type type,
388 const std::string& app_name,
[email protected]94ce7252010-12-20 21:46:33389 const gfx::Size& window_size,
[email protected]b35b26b32011-05-05 20:35:14390 Profile* profile) {
391 DCHECK(type != TYPE_TABBED);
392 DCHECK(!app_name.empty());
[email protected]f075fe0a22010-04-26 04:06:43393
[email protected]b35b26b32011-05-05 20:35:14394 RegisterAppPrefs(app_name, profile);
395
396#if !defined(OS_CHROMEOS)
397 if (type == TYPE_PANEL &&
398 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
399 // The panel UI is not fully implemented, so we default to TYPE_POPUP when
400 // the panel switch is not enabled. See crbug/55943.
401 type = TYPE_POPUP;
[email protected]5530ac652010-09-25 05:35:49402 }
[email protected]b35b26b32011-05-05 20:35:14403#endif
[email protected]f075fe0a22010-04-26 04:06:43404
[email protected]b35b26b32011-05-05 20:35:14405 CreateParams params(type, profile);
406 params.app_name = app_name;
407 if (!window_size.IsEmpty())
408 params.initial_bounds.set_size(window_size);
[email protected]605cfad2010-06-22 20:49:35409
[email protected]b35b26b32011-05-05 20:35:14410 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05411}
412
[email protected]8e48e982009-12-25 11:22:46413// static
414Browser* Browser::CreateForDevTools(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14415 CreateParams params(TYPE_POPUP, profile);
416 params.app_name = DevToolsWindow::kDevToolsApp;
417 return CreateWithParams(params);
[email protected]8e48e982009-12-25 11:22:46418}
419
[email protected]9800de5e2011-03-11 18:19:49420void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05421 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43422
[email protected]9800de5e2011-03-11 18:19:49423 window_ = CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:05424
[email protected]80cf3562009-11-17 08:17:24425#if defined(OS_WIN)
[email protected]45446a52010-11-04 17:41:00426 {
427 // TODO: This might hit the disk
428 // http://code.google.com/p/chromium/issues/detail?id=61638
429 base::ThreadRestrictions::ScopedAllowIO allow_io;
430
431 // Set the app user model id for this application to that of the application
432 // name. See http://crbug.com/7028.
[email protected]b99603c2010-12-30 22:13:32433 app::win::SetAppIdForWindow(
[email protected]b35b26b32011-05-05 20:35:14434 is_app() ?
[email protected]45446a52010-11-04 17:41:00435 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
436 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
437 window()->GetNativeHandle());
438 }
[email protected]80cf3562009-11-17 08:17:24439#endif
440
[email protected]14d8c66e2009-09-22 00:32:52441 NotificationService::current()->Notify(
442 NotificationType::BROWSER_WINDOW_READY,
443 Source<Browser>(this),
444 NotificationService::NoDetails());
445
[email protected]ac86c982011-05-11 13:26:05446 if (use_compact_navigation_bar_.GetValue()) {
447 // This enables the compact navigation bar host.
448 UseCompactNavigationBarChanged();
449 }
450
[email protected]15952e462008-11-14 00:29:05451 // Show the First Run information bubble if we've been told to.
452 PrefService* local_state = g_browser_process->local_state();
[email protected]be3877f2009-01-14 15:51:10453 if (!local_state)
454 return;
[email protected]da6ce5602009-12-07 23:09:32455 if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
[email protected]15952e462008-11-14 00:29:05456 local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50457 FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07458 if (local_state->
[email protected]da6ce5602009-12-07 23:09:32459 FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
[email protected]adfe1882010-04-13 23:01:07460 local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50461 bubble_type = FirstRun::OEM_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07462 } else if (local_state->
463 FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
464 local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50465 bubble_type = FirstRun::MINIMAL_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07466 }
[email protected]15952e462008-11-14 00:29:05467 // Reset the preference so we don't show the bubble for subsequent windows.
468 local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
[email protected]adfe1882010-04-13 23:01:07469 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
initial.commit09911bf2008-07-26 23:55:29470 }
[email protected]f69c8852010-10-12 02:36:46471 if (local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01472 prefs::kAutofillPersonalDataManagerFirstRun) &&
473 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46474 // Notify PDM that this is a first run.
475#if defined(OS_WIN)
476 ImportAutofillDataWin(profile_->GetPersonalDataManager());
477#endif // defined(OS_WIN)
478 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01479 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46480 }
initial.commit09911bf2008-07-26 23:55:29481}
482
[email protected]36b6dcb2008-11-12 01:19:57483///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07484// Getters & Setters
485
486const std::vector<std::wstring>& Browser::user_data_dir_profiles() const {
487 return g_browser_process->user_data_dir_profiles();
488}
489
490void Browser::set_user_data_dir_profiles(
491 const std::vector<std::wstring>& profiles) {
492 g_browser_process->user_data_dir_profiles() = profiles;
493}
494
[email protected]b77cb302009-10-29 04:09:17495FindBarController* Browser::GetFindBarController() {
496 if (!find_bar_controller_.get()) {
497 FindBar* find_bar = BrowserWindow::CreateFindBar(this);
498 find_bar_controller_.reset(new FindBarController(find_bar));
499 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24500 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17501 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
502 }
503 return find_bar_controller_.get();
504}
505
[email protected]24db8a072009-10-29 20:35:37506bool Browser::HasFindBarController() const {
507 return find_bar_controller_.get() != NULL;
508}
509
[email protected]b35b26b32011-05-05 20:35:14510bool Browser::is_app() const {
511 return !app_name_.empty();
512}
513
514bool Browser::is_devtools() const {
515 return app_name_ == DevToolsWindow::kDevToolsApp;
516}
517
[email protected]5c238752009-06-13 10:29:07518///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57519// Browser, Creation Helpers:
520
521// static
[email protected]15952e462008-11-14 00:29:05522void Browser::OpenEmptyWindow(Profile* profile) {
523 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57524 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05525 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29526}
527
[email protected]36b6dcb2008-11-12 01:19:57528// static
[email protected]fbc947b2009-06-19 13:28:24529void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15530 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24531 if (service)
532 service->RestoreMostRecentEntry(NULL);
533}
534
535// static
[email protected]36b6dcb2008-11-12 01:19:57536void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55537 Browser* browser = GetOrCreateTabbedBrowser(
538 profile->GetOffTheRecordProfile());
539 browser->AddSelectedTabWithURL(url, PageTransition::LINK);
[email protected]15952e462008-11-14 00:29:05540 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17541}
542
[email protected]36b6dcb2008-11-12 01:19:57543// static
[email protected]d83a5602010-09-16 00:22:48544TabContents* Browser::OpenApplication(
545 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02546 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39547 extension_misc::LaunchContainer container,
[email protected]7e41c2b2011-05-06 10:31:16548 WindowOpenDisposition disposition) {
[email protected]56869382010-05-11 21:45:46549 TabContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04550 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
551 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37552
[email protected]9b217652010-10-08 22:04:23553 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
554
[email protected]bbadaa782010-04-28 21:21:53555 switch (container) {
[email protected]d83a5602010-09-16 00:22:48556 case extension_misc::LAUNCH_WINDOW:
557 case extension_misc::LAUNCH_PANEL:
[email protected]bbadaa782010-04-28 21:21:53558 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]0e71e4152010-12-07 04:16:26559 GURL(), NULL);
[email protected]c28071ad2010-03-12 17:28:56560 break;
[email protected]d83a5602010-09-16 00:22:48561 case extension_misc::LAUNCH_TAB: {
[email protected]7e41c2b2011-05-06 10:31:16562 tab = Browser::OpenApplicationTab(profile, extension, disposition);
[email protected]c28071ad2010-03-12 17:28:56563 break;
564 }
565 default:
566 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53567 break;
[email protected]c28071ad2010-03-12 17:28:56568 }
[email protected]bbadaa782010-04-28 21:21:53569 return tab;
[email protected]c28071ad2010-03-12 17:28:56570}
571
572// static
[email protected]bbadaa782010-04-28 21:21:53573TabContents* Browser::OpenApplicationWindow(
574 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02575 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48576 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26577 const GURL& url_input,
578 Browser** app_browser) {
[email protected]f381dfa2010-04-29 04:41:37579 GURL url;
580 if (!url_input.is_empty()) {
581 if (extension)
[email protected]cced75a2011-05-20 08:31:12582 DCHECK(extension->web_extent().MatchesURL(url_input));
[email protected]f381dfa2010-04-29 04:41:37583 url = url_input;
584 } else {
[email protected]ae5909e2011-02-23 14:34:18585 DCHECK(extension); // Empty url and no extension. Nothing to open.
[email protected]f381dfa2010-04-29 04:41:37586 url = extension->GetFullLaunchURL();
587 }
588
[email protected]2f1c09d2011-01-14 14:58:14589 std::string app_name;
590 if (extension)
591 app_name =
592 web_app::GenerateApplicationNameFromExtensionId(extension->id());
593 else
594 app_name = web_app::GenerateApplicationNameFromURL(url);
595
[email protected]b35b26b32011-05-05 20:35:14596 Type type = extension && (container == extension_misc::LAUNCH_PANEL) ?
597 TYPE_PANEL : TYPE_POPUP;
[email protected]94ce7252010-12-20 21:46:33598
599 gfx::Size window_size;
600 if (extension)
601 window_size.SetSize(extension->launch_width(),
602 extension->launch_height());
603
[email protected]b35b26b32011-05-05 20:35:14604 Browser* browser = Browser::CreateForApp(type, app_name, window_size,
605 profile);
[email protected]011396a2011-04-13 23:35:28606
[email protected]0e71e4152010-12-07 04:16:26607 if (app_browser)
608 *app_browser = browser;
609
[email protected]3c9e1872010-11-18 16:17:49610 TabContentsWrapper* wrapper =
[email protected]cecc93a2010-10-05 15:58:55611 browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
[email protected]3c9e1872010-11-18 16:17:49612 TabContents* contents = wrapper->tab_contents();
[email protected]cecc93a2010-10-05 15:58:55613 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
614 contents->render_view_host()->SyncRendererPrefs();
615 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53616
[email protected]68f009f2009-02-26 19:43:35617 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
618 // focus explicitly.
[email protected]cecc93a2010-10-05 15:58:55619 contents->view()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26620 return contents;
621}
[email protected]eabfdae92009-12-11 06:13:51622
[email protected]0e71e4152010-12-07 04:16:26623TabContents* Browser::OpenAppShortcutWindow(Profile* profile,
624 const GURL& url,
625 bool update_shortcut) {
626 Browser* app_browser;
627 TabContents* tab = OpenApplicationWindow(
628 profile,
629 NULL, // this is a URL app. No extension.
630 extension_misc::LAUNCH_WINDOW,
631 url,
632 &app_browser);
633
634 if (!tab)
635 return NULL;
636
637 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35638 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
639 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
640 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46641 // OnDidGetApplicationInfo, which calls
642 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
643 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26644 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35645 }
[email protected]0e71e4152010-12-07 04:16:26646 return tab;
[email protected]c28071ad2010-03-12 17:28:56647}
648
649// static
[email protected]bbadaa782010-04-28 21:21:53650TabContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02651 const Extension* extension,
[email protected]7e41c2b2011-05-06 10:31:16652 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14653 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]cecc93a2010-10-05 15:58:55654 TabContents* contents = NULL;
[email protected]ea86bfb2011-02-08 18:15:44655 if (!browser)
[email protected]cecc93a2010-10-05 15:58:55656 return contents;
[email protected]c28071ad2010-03-12 17:28:56657
[email protected]10abd192010-09-30 02:03:49658 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36659 ExtensionService* extension_service = profile->GetExtensionService();
660 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59661
[email protected]10abd192010-09-30 02:03:49662 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36663 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02664 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23665 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]eaca0ad12011-04-18 15:53:41666 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49667 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
668 add_type |= TabStripModel::ADD_PINNED;
669
[email protected]37fcf262011-01-26 19:39:15670 // For extensions lacking launch urls, determine a reasonable fallback.
671 GURL extension_url = extension->GetFullLaunchURL();
672 if (!extension_url.is_valid()) {
673 extension_url = extension->options_url();
674 if (!extension_url.is_valid())
675 extension_url = GURL(chrome::kChromeUIExtensionsURL);
676 }
677
[email protected]10abd192010-09-30 02:03:49678 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
679 // cases.
[email protected]37fcf262011-01-26 19:39:15680 browser::NavigateParams params(browser, extension_url,
[email protected]616381f02010-11-02 15:15:33681 PageTransition::START_PAGE);
682 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16683 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39684
[email protected]7e41c2b2011-05-06 10:31:16685 if (disposition == CURRENT_TAB) {
686 TabContents* existing_tab = browser->GetSelectedTabContents();
[email protected]24bf2022010-10-14 16:34:39687 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49688 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39689
690 existing_tab->OpenURL(extension->GetFullLaunchURL(), existing_tab->GetURL(),
[email protected]7e41c2b2011-05-06 10:31:16691 disposition, PageTransition::LINK);
[email protected]616381f02010-11-02 15:15:33692 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39693 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49694 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26695 }
[email protected]eaca0ad12011-04-18 15:53:41696 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
697 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39698
699 contents = existing_tab;
700 } else {
[email protected]616381f02010-11-02 15:15:33701 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:49702 contents = params.target_contents->tab_contents();
[email protected]24bf2022010-10-14 16:34:39703 }
704
[email protected]7bd42fc2011-02-09 17:32:42705 // TODO(skerner): If we are already in full screen mode, and the user
706 // set the app to open as a regular or pinned tab, what should happen?
707 // Today we open the tab, but stay in full screen mode. Should we leave
708 // full screen mode in this case?
709 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
710 !browser->window()->IsFullscreen())
711 browser->ToggleFullscreenMode();
[email protected]10abd192010-09-30 02:03:49712
[email protected]cecc93a2010-10-05 15:58:55713 return contents;
[email protected]c28071ad2010-03-12 17:28:56714}
715
716// static
[email protected]90a8bf252010-03-12 00:09:47717void Browser::OpenBookmarkManagerWindow(Profile* profile) {
718 Browser* browser = Browser::Create(profile);
719 browser->ShowBookmarkManagerTab();
720 browser->window()->Show();
721}
722
[email protected]057d959a2010-03-12 02:56:20723#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47724// static
[email protected]91a5b3e2009-10-30 19:32:22725void Browser::OpenHistoryWindow(Profile* profile) {
726 Browser* browser = Browser::Create(profile);
727 browser->ShowHistoryTab();
728 browser->window()->Show();
729}
730
731// static
732void Browser::OpenDownloadsWindow(Profile* profile) {
733 Browser* browser = Browser::Create(profile);
734 browser->ShowDownloadsTab();
735 browser->window()->Show();
736}
737
738// static
[email protected]1fdff702009-10-22 00:36:18739void Browser::OpenHelpWindow(Profile* profile) {
740 Browser* browser = Browser::Create(profile);
741 browser->OpenHelpTab();
742 browser->window()->Show();
743}
[email protected]4a42d272010-06-18 01:29:42744
[email protected]eca258132010-11-15 23:33:08745// static
[email protected]4a42d272010-06-18 01:29:42746void Browser::OpenOptionsWindow(Profile* profile) {
747 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49748 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42749 browser->window()->Show();
750}
[email protected]c8de64a2011-01-25 17:10:23751
752// static
753void Browser::OpenClearBrowingDataDialogWindow(Profile* profile) {
754 Browser* browser = Browser::Create(profile);
755 browser->OpenClearBrowsingDataDialog();
756 browser->window()->Show();
757}
758
759// static
760void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
761 Browser* browser = Browser::Create(profile);
762 browser->OpenImportSettingsDialog();
763 browser->window()->Show();
764}
[email protected]b99081b2011-03-10 17:43:47765
766// static
767void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
768 Browser* browser = Browser::Create(profile);
769 browser->OpenInstantConfirmDialog();
770 browser->window()->Show();
771}
[email protected]1fdff702009-10-22 00:36:18772#endif
773
[email protected]ccb55cf52010-03-06 22:02:04774// static
775void Browser::OpenExtensionsWindow(Profile* profile) {
776 Browser* browser = Browser::Create(profile);
777 browser->ShowExtensionsTab();
778 browser->window()->Show();
779}
780
[email protected]29d70252011-04-28 02:16:58781// static
782void Browser::NewWindowWithProfile(Profile* profile) {
783 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
784 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:15785 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
[email protected]29d70252011-04-28 02:16:58786 if (!session_service ||
787 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
788 Browser::OpenEmptyWindow(profile->GetOriginalProfile());
789 }
790}
[email protected]ccb55cf52010-03-06 22:02:04791
[email protected]36b6dcb2008-11-12 01:19:57792///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57793// Browser, State Storage and Retrieval for UI:
794
[email protected]57ecc4b2010-08-11 03:02:51795std::string Browser::GetWindowPlacementKey() const {
796 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57797 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51798 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57799 name.append(app_name_);
800 }
[email protected]bc9a5152008-11-15 00:32:04801 return name;
802}
[email protected]36b6dcb2008-11-12 01:19:57803
[email protected]bc9a5152008-11-15 00:32:04804bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14805 switch (type_) {
806 case TYPE_TABBED:
807 return true;
808 case TYPE_POPUP:
809 // Only save the window placement of popups if they are restored.
810 return browser_defaults::kRestorePopups;
811 case TYPE_PANEL:
812 // Do not save the window placement of panels.
813 return false;
814 default:
815 return false;
816 }
[email protected]bc9a5152008-11-15 00:32:04817}
[email protected]36b6dcb2008-11-12 01:19:57818
[email protected]bc9a5152008-11-15 00:32:04819void Browser::SaveWindowPlacement(const gfx::Rect& bounds, bool maximized) {
820 // Save to the session storage service, used when reloading a past session.
821 // Note that we don't want to be the ones who cause lazy initialization of
822 // the session service. This function gets called during initial window
823 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:15824 SessionService* session_service =
825 SessionServiceFactory::GetForProfileIfExisting(profile());
826 if (session_service)
827 session_service->SetWindowBounds(session_id_, bounds, maximized);
[email protected]36b6dcb2008-11-12 01:19:57828}
829
[email protected]15952e462008-11-14 00:29:05830gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]bb975362009-01-21 01:00:22831 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05832 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
833 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
834 if (record_mode || playback_mode) {
835 // In playback/record mode we always fix the size of the browser and
836 // move it to (0,0). The reason for this is two reasons: First we want
837 // resize/moves in the playback to still work, and Second we want
838 // playbacks to work (as much as possible) on machines w/ different
839 // screen sizes.
840 return gfx::Rect(0, 0, 800, 600);
841 }
842
843 gfx::Rect restored_bounds = override_bounds_;
844 bool maximized;
[email protected]f87919d72011-02-02 18:46:16845 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05846 &restored_bounds, &maximized);
847 return restored_bounds;
848}
849
850// TODO(beng): obtain maximized state some other way so we don't need to go
851// through all this hassle.
852bool Browser::GetSavedMaximizedState() const {
[email protected]bb975362009-01-21 01:00:22853 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]15952e462008-11-14 00:29:05854 return true;
855
[email protected]2e716622009-03-09 21:11:01856 if (maximized_state_ == MAXIMIZED_STATE_MAXIMIZED)
857 return true;
858 if (maximized_state_ == MAXIMIZED_STATE_UNMAXIMIZED)
859 return false;
860
861 // An explicit maximized state was not set. Query the window sizer.
[email protected]15952e462008-11-14 00:29:05862 gfx::Rect restored_bounds;
[email protected]2e716622009-03-09 21:11:01863 bool maximized = false;
[email protected]f87919d72011-02-02 18:46:16864 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05865 &restored_bounds, &maximized);
866 return maximized;
[email protected]36b6dcb2008-11-12 01:19:57867}
868
869SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:04870 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:23871 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
872 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:04873 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57874}
875
[email protected]731f8a42009-07-20 22:07:32876string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3c9e1872010-11-18 16:17:49877 TabContents* contents = GetSelectedTabContents();
[email protected]dda5dfa32009-07-10 00:33:29878 string16 title;
[email protected]c7c42332008-11-15 01:10:54879
[email protected]731f8a42009-07-20 22:07:32880 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
881 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57882 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29883 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57884 FormatTitleForDisplay(&title);
885 }
886 if (title.empty())
[email protected]0dd3a0ab2011-02-18 08:17:44887 title = TabContentsWrapper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57888
[email protected]16779842009-07-08 23:45:29889#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:33890 // On Mac or ChromeOS, we don't want to suffix the page title with
891 // the application name.
[email protected]d904bc82009-07-07 00:41:04892 return title;
[email protected]7be64502011-05-03 17:51:47893#else
[email protected]edb5e6a2009-04-08 23:46:17894 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55895 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:14896 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:17897 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29898 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50899#endif
[email protected]36b6dcb2008-11-12 01:19:57900}
901
902// static
[email protected]dda5dfa32009-07-10 00:33:29903void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57904 size_t current_index = 0;
905 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:51906 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:15907 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:57908 current_index = match_index;
909 }
910}
911
912///////////////////////////////////////////////////////////////////////////////
913// Browser, OnBeforeUnload handling:
914
[email protected]460a2942010-12-15 19:43:15915bool Browser::TabsNeedBeforeUnloadFired() {
916 if (tabs_needing_before_unload_fired_.empty()) {
917 for (int i = 0; i < tab_count(); ++i) {
918 TabContents* contents = GetTabContentsAt(i);
919 if (contents->NeedToFireBeforeUnload())
920 tabs_needing_before_unload_fired_.insert(contents);
921 }
922 }
923 return !tabs_needing_before_unload_fired_.empty();
924}
925
[email protected]36b6dcb2008-11-12 01:19:57926bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:06927 if (!CanCloseWithInProgressDownloads())
928 return false;
929
930 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:04931 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:06932
[email protected]36b6dcb2008-11-12 01:19:57933 is_attempting_to_close_browser_ = true;
934
[email protected]460a2942010-12-15 19:43:15935 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:04936 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:57937
938 ProcessPendingTabs();
939 return false;
940}
941
942void Browser::OnWindowClosing() {
943 if (!ShouldCloseWindow())
944 return;
945
[email protected]911f8152010-03-18 16:46:40946 bool exiting = false;
947
[email protected]c984d9f2010-07-20 20:52:20948 // Application should shutdown on last window close if the user is explicitly
949 // trying to quit, or if there is nothing keeping the browser alive (such as
950 // AppController on the Mac, or BackgroundContentsService for background
951 // pages).
952 bool should_quit_if_last_browser =
953 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:50954
955 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:57956 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:40957 exiting = true;
958 }
[email protected]36b6dcb2008-11-12 01:19:57959
[email protected]92371eb2011-04-28 11:50:15960 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:57961 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:15962 SessionService* session_service =
963 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:57964 if (session_service)
965 session_service->WindowClosing(session_id());
966
[email protected]92371eb2011-04-28 11:50:15967 TabRestoreService* tab_restore_service =
968 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]b35b26b32011-05-05 20:35:14969 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:00970 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39971
[email protected]911f8152010-03-18 16:46:40972 // TODO(sky): convert session/tab restore to use notification.
973 NotificationService::current()->Notify(
974 NotificationType::BROWSER_CLOSING,
975 Source<Browser>(this),
976 Details<bool>(&exiting));
977
[email protected]36b6dcb2008-11-12 01:19:57978 CloseAllTabs();
979}
980
[email protected]28788c7d2011-05-20 23:03:45981void Browser::OnWindowActivated() {
982 // On some platforms we want to automatically reload tabs that are
983 // killed when the user selects them.
984 TabContents* contents = GetSelectedTabContents();
985 if (contents && contents->crashed_status() ==
986 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
987 if (CommandLine::ForCurrentProcess()->HasSwitch(
988 switches::kReloadKilledTabs)) {
989 Reload(CURRENT_TAB);
990 }
991 }
992}
993
[email protected]69444cc2009-04-09 20:40:06994////////////////////////////////////////////////////////////////////////////////
995// In-progress download termination handling:
996
997void Browser::InProgressDownloadResponse(bool cancel_downloads) {
998 if (cancel_downloads) {
999 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1000 CloseWindow();
1001 return;
1002 }
1003
1004 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1005 // close again we'll show the warning again.
1006 cancel_download_confirmation_state_ = NOT_PROMPTED;
1007
1008 // Show the download page so the user can figure-out what downloads are still
1009 // in-progress.
1010 ShowDownloadsTab();
1011}
1012
[email protected]69444cc2009-04-09 20:40:061013////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451014// Browser, TabStripModel pass-thrus:
1015
1016int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:401017 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:451018}
1019
[email protected]1ea49d52011-04-12 17:44:441020int Browser::active_index() const {
1021 return tab_handler_->GetTabStripModel()->active_index();
[email protected]c848d3d92010-09-16 21:57:451022}
1023
1024int Browser::GetIndexOfController(
1025 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:401026 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451027}
1028
[email protected]3c9e1872010-11-18 16:17:491029TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
1030 return tabstrip_model()->GetSelectedTabContents();
1031}
[email protected]b375c5d2011-05-03 21:15:041032
[email protected]3c9e1872010-11-18 16:17:491033TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
1034 return tabstrip_model()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451035}
1036
1037TabContents* Browser::GetSelectedTabContents() const {
[email protected]3c9e1872010-11-18 16:17:491038 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1039 if (wrapper)
1040 return wrapper->tab_contents();
1041 return NULL;
1042}
1043
1044TabContents* Browser::GetTabContentsAt(int index) const {
1045 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
1046 if (wrapper)
1047 return wrapper->tab_contents();
1048 return NULL;
[email protected]c848d3d92010-09-16 21:57:451049}
1050
[email protected]eaca0ad12011-04-18 15:53:411051void Browser::ActivateTabAt(int index, bool user_gesture) {
1052 tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451053}
1054
[email protected]fb7da4132011-03-15 15:51:001055bool Browser::IsTabPinned(int index) const {
1056 return tabstrip_model()->IsTabPinned(index);
1057}
1058
[email protected]c848d3d92010-09-16 21:57:451059void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:401060 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451061}
1062
1063////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571064// Browser, Tab adding/showing functions:
1065
[email protected]95bf8a5b2010-12-22 16:04:071066bool Browser::IsTabStripEditable() const {
1067 return window()->IsTabStripEditable();
1068}
1069
[email protected]b3344872010-05-03 15:52:291070int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:401071 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
1072 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291073}
1074
[email protected]3c9e1872010-11-18 16:17:491075TabContentsWrapper* Browser::AddSelectedTabWithURL(const GURL& url,
[email protected]cecc93a2010-10-05 15:58:551076 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:331077 browser::NavigateParams params(this, url, transition);
1078 params.disposition = NEW_FOREGROUND_TAB;
1079 browser::Navigate(&params);
1080 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571081}
1082
[email protected]3c9e1872010-11-18 16:17:491083TabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]d99cdfd2009-10-08 18:58:111084 PageTransition::Type type) {
[email protected]ecc523f62010-09-28 22:45:401085 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]eaca0ad12011-04-18 15:53:411086 tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
[email protected]3c9e1872010-11-18 16:17:491087 return tab_contents->tab_contents();
[email protected]36b6dcb2008-11-12 01:19:571088}
1089
[email protected]e0c7c262009-04-23 23:09:431090void Browser::AddTabContents(TabContents* new_contents,
1091 WindowOpenDisposition disposition,
1092 const gfx::Rect& initial_pos,
1093 bool user_gesture) {
1094 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1095}
1096
1097void Browser::CloseTabContents(TabContents* contents) {
1098 CloseContents(contents);
1099}
1100
1101void Browser::BrowserShowHtmlDialog(HtmlDialogUIDelegate* delegate,
[email protected]322f3ff2009-05-22 16:19:541102 gfx::NativeWindow parent_window) {
[email protected]66b0967e2011-05-10 17:55:561103 window_->ShowHTMLDialog(delegate, parent_window);
[email protected]e0c7c262009-04-23 23:09:431104}
1105
1106void Browser::BrowserRenderWidgetShowing() {
1107 RenderWidgetShowing();
1108}
1109
[email protected]c9bd2e82011-04-15 23:28:191110void Browser::BookmarkBarSizeChanged(bool is_animating) {
1111 window_->ToolbarSizeChanged(is_animating);
[email protected]e0c7c262009-04-23 23:09:431112}
1113
[email protected]ce3fa3c2009-04-20 19:55:571114TabContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571115 const std::vector<TabNavigation>& navigations,
1116 int tab_index,
1117 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081118 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091119 bool select,
[email protected]5e369672009-11-03 23:48:301120 bool pin,
[email protected]6ee12c42010-09-14 09:36:071121 bool from_last_session,
1122 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:491123 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
1124 MSG_ROUTING_NONE,
1125 GetSelectedTabContents(),
[email protected]ecc523f62010-09-28 22:45:401126 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:491127 TabContents* new_tab = wrapper->tab_contents();
[email protected]36fb2c7c2011-04-04 15:49:081128 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]5e369672009-11-03 23:48:301129 new_tab->controller().RestoreFromState(navigations, selected_navigation,
1130 from_last_session);
[email protected]36b6dcb2008-11-12 01:19:571131
[email protected]eaca0ad12011-04-18 15:53:411132 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211133 TabStripModel::ADD_NONE;
1134 if (pin) {
1135 tab_index = std::min(tab_index, tabstrip_model()->IndexOfFirstNonMiniTab());
1136 add_types |= TabStripModel::ADD_PINNED;
1137 }
1138 tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1139 add_types);
[email protected]c93a9dd2010-04-22 20:25:181140 if (select) {
[email protected]77bc6732009-04-20 22:01:031141 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181142 } else {
1143 // We set the size of the view here, before WebKit does its initial
1144 // layout. If we don't, the initial layout of background tabs will be
1145 // performed with a view width of 0, which may cause script outputs and
1146 // anchor link location calculations to be incorrect even after a new
1147 // layout with proper view dimensions. TabStripModel::AddTabContents()
1148 // contains similar logic.
1149 new_tab->view()->SizeContents(window_->GetRestoredBounds().size());
1150 new_tab->HideContents();
1151 }
[email protected]92371eb2011-04-28 11:50:151152 SessionService* session_service =
1153 SessionServiceFactory::GetForProfileIfExisting(profile_);
1154 if (session_service)
1155 session_service->TabRestored(&new_tab->controller(), pin);
[email protected]ce3fa3c2009-04-20 19:55:571156 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571157}
1158
1159void Browser::ReplaceRestoredTab(
1160 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301161 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101162 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071163 const std::string& extension_app_id,
1164 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:491165 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
[email protected]ecc523f62010-09-28 22:45:401166 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:491167 GetSelectedTabContents(),
[email protected]6ee12c42010-09-14 09:36:071168 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081169 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]3c9e1872010-11-18 16:17:491170 TabContents* replacement = wrapper->tab_contents();
[email protected]5e369672009-11-03 23:48:301171 replacement->controller().RestoreFromState(navigations, selected_navigation,
1172 from_last_session);
[email protected]36b6dcb2008-11-12 01:19:571173
[email protected]ecc523f62010-09-28 22:45:401174 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
[email protected]1ea49d52011-04-12 17:44:441175 tab_handler_->GetTabStripModel()->active_index(),
[email protected]3c9e1872010-11-18 16:17:491176 wrapper);
[email protected]36b6dcb2008-11-12 01:19:571177}
1178
[email protected]a8eff102009-04-14 15:23:431179bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131180 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431181}
1182
[email protected]3698f172010-03-17 20:50:291183bool Browser::NavigateToIndexWithDisposition(int index,
1184 WindowOpenDisposition disp) {
1185 NavigationController& controller =
[email protected]cb84d642010-06-10 00:56:281186 GetOrCloneTabForDisposition(disp)->controller();
1187 if (index < 0 || index >= controller.entry_count())
[email protected]3698f172010-03-17 20:50:291188 return false;
[email protected]cb84d642010-06-10 00:56:281189 controller.GoToIndex(index);
1190 return true;
[email protected]3698f172010-03-17 20:50:291191}
1192
[email protected]fee320542011-03-02 01:30:491193browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1194 const GURL& url) {
[email protected]616381f02010-11-02 15:15:331195 browser::NavigateParams params(this, url, PageTransition::AUTO_BOOKMARK);
1196 params.disposition = SINGLETON_TAB;
[email protected]7d329992011-04-15 18:20:021197 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:351198 params.user_gesture = true;
[email protected]fee320542011-03-02 01:30:491199 return params;
1200}
1201
1202void Browser::ShowSingletonTab(const GURL& url) {
1203 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331204 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571205}
[email protected]d938aed92009-01-22 19:49:331206
[email protected]ae2622c2009-07-30 23:47:581207void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
[email protected]326464d2010-02-16 22:21:101208#if !defined(OS_MACOSX)
[email protected]b35b26b32011-05-05 20:35:141209 const bool show_main_ui = is_type_tabbed() && !is_fullscreen;
[email protected]326464d2010-02-16 22:21:101210#else
[email protected]b35b26b32011-05-05 20:35:141211 const bool show_main_ui = is_type_tabbed();
[email protected]326464d2010-02-16 22:21:101212#endif
[email protected]ae2622c2009-07-30 23:47:581213
[email protected]b35b26b32011-05-05 20:35:141214 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
[email protected]83548a42010-06-18 13:53:371215
[email protected]ae2622c2009-07-30 23:47:581216 // Navigation commands
1217 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
1218
1219 // Window management commands
[email protected]ae2622c2009-07-30 23:47:581220 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
[email protected]b35b26b32011-05-05 20:35:141221 type_ != TYPE_TABBED && !is_fullscreen);
[email protected]ae2622c2009-07-30 23:47:581222
1223 // Focus various bits of UI
1224 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
1225 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
1226 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
[email protected]cc824372010-03-31 15:33:011227 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141228 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371229 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141230 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371231 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141232 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371233 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141234 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371235 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141236 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
[email protected]ae2622c2009-07-30 23:47:581237
1238 // Show various bits of UI
1239 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
[email protected]1c41a932010-11-22 23:41:231240 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]4a4180a52010-08-23 06:39:481241 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
1242 browser_defaults::bookmarks_enabled && show_main_ui);
[email protected]ae2622c2009-07-30 23:47:581243 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
[email protected]d3b98c82010-07-14 07:45:591244 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
1245 show_main_ui && profile_->IsSyncAccessible());
[email protected]da96e54c2010-08-12 00:18:321246
[email protected]ae2622c2009-07-30 23:47:581247 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
1248 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
1249 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
1250 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
[email protected]fdb98512009-08-26 01:37:101251 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]c8b59f92010-05-28 21:45:471252 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
[email protected]ac86c982011-05-11 13:26:051253 command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
[email protected]7664ab32011-02-01 23:35:251254#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
1255 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
1256#endif
[email protected]ae2622c2009-07-30 23:47:581257}
1258
[email protected]36b6dcb2008-11-12 01:19:571259///////////////////////////////////////////////////////////////////////////////
1260// Browser, Assorted browser commands:
1261
[email protected]d497b0782010-03-29 19:19:061262bool Browser::ShouldOpenNewTabForWindowDisposition(
1263 WindowOpenDisposition disposition) {
1264 return (disposition == NEW_FOREGROUND_TAB ||
1265 disposition == NEW_BACKGROUND_TAB);
1266}
1267
[email protected]cb84d642010-06-10 00:56:281268TabContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291269 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491270 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]d497b0782010-03-29 19:19:061271 if (ShouldOpenNewTabForWindowDisposition(disposition)) {
[email protected]cb84d642010-06-10 00:56:281272 current_tab = current_tab->Clone();
[email protected]ecc523f62010-09-28 22:45:401273 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]4a1665442010-06-28 16:09:391274 current_tab, -1, PageTransition::LINK,
[email protected]eaca0ad12011-04-18 15:53:411275 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
[email protected]4a1665442010-06-28 16:09:391276 TabStripModel::ADD_NONE);
[email protected]3698f172010-03-17 20:50:291277 }
[email protected]3c9e1872010-11-18 16:17:491278 return current_tab->tab_contents();
[email protected]3698f172010-03-17 20:50:291279}
1280
[email protected]b3344872010-05-03 15:52:291281void Browser::UpdateTabStripModelInsertionPolicy() {
[email protected]ecc523f62010-09-28 22:45:401282 tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
[email protected]b3344872010-05-03 15:52:291283 TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
1284}
1285
1286void Browser::UseVerticalTabsChanged() {
1287 UpdateTabStripModelInsertionPolicy();
1288 window()->ToggleTabStripMode();
1289}
1290
[email protected]ac86c982011-05-11 13:26:051291void Browser::UseCompactNavigationBarChanged() {
1292 window_->ToggleUseCompactNavigationBar();
1293}
1294
[email protected]018cf362010-05-05 22:43:221295bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1296 bool check_fullscreen) const {
1297 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1298 // other platforms, we hide some controls when in fullscreen mode.
1299 bool hide_ui_for_fullscreen = false;
1300#if !defined(OS_MACOSX)
1301 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1302 window_->IsFullscreen();
1303#endif
1304
[email protected]8b8e7c92010-08-19 18:05:561305 unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
[email protected]018cf362010-05-05 22:43:221306
1307#if !defined(OS_CHROMEOS)
1308 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1309 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1310 features |= FEATURE_DOWNLOADSHELF;
1311#endif // !defined(OS_CHROMEOS)
1312
[email protected]b35b26b32011-05-05 20:35:141313 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221314 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221315
1316 if (!hide_ui_for_fullscreen) {
[email protected]b35b26b32011-05-05 20:35:141317 if (!is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221318 features |= FEATURE_TITLEBAR;
1319
[email protected]b35b26b32011-05-05 20:35:141320 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221321 features |= FEATURE_TABSTRIP;
1322
[email protected]b35b26b32011-05-05 20:35:141323 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221324 features |= FEATURE_TOOLBAR;
1325
[email protected]b35b26b32011-05-05 20:35:141326 if (!is_app())
[email protected]018cf362010-05-05 22:43:221327 features |= FEATURE_LOCATIONBAR;
1328 }
1329 return !!(features & feature);
1330}
1331
[email protected]0b4d3382010-07-14 16:13:041332bool Browser::IsClosingPermitted() {
1333 TabCloseableStateWatcher* watcher =
1334 g_browser_process->tab_closeable_state_watcher();
1335 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1336 if (!can_close && is_attempting_to_close_browser_)
1337 CancelWindowClose();
1338 return can_close;
1339}
1340
[email protected]485fba42009-03-24 23:27:291341void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591342 UserMetrics::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271343
[email protected]3c9e1872010-11-18 16:17:491344 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]ce3fa3c2009-04-20 19:55:571345 if (current_tab->controller().CanGoBack()) {
[email protected]cb84d642010-06-10 00:56:281346 TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061347 // If we are on an interstitial page and clone the tab, it won't be copied
1348 // to the new tab, so we don't need to go back.
[email protected]3c9e1872010-11-18 16:17:491349 if (current_tab->tab_contents()->showing_interstitial_page() &&
1350 (new_tab != current_tab->tab_contents()))
[email protected]d497b0782010-03-29 19:19:061351 return;
[email protected]cb84d642010-06-10 00:56:281352 new_tab->controller().GoBack();
[email protected]485fba42009-03-24 23:27:291353 }
[email protected]36b6dcb2008-11-12 01:19:571354}
1355
[email protected]3698f172010-03-17 20:50:291356void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591357 UserMetrics::RecordAction(UserMetricsAction("Forward"));
[email protected]3c9e1872010-11-18 16:17:491358 if (GetSelectedTabContentsWrapper()->controller().CanGoForward())
[email protected]cb84d642010-06-10 00:56:281359 GetOrCloneTabForDisposition(disposition)->controller().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571360}
1361
[email protected]cb84d642010-06-10 00:56:281362void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591363 UserMetrics::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281364 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161365}
[email protected]fbd77592008-11-12 20:50:271366
[email protected]cb84d642010-06-10 00:56:281367void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591368 UserMetrics::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281369 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161370}
1371
[email protected]cb84d642010-06-10 00:56:281372void Browser::ReloadInternal(WindowOpenDisposition disposition,
1373 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571374 // If we are showing an interstitial, treat this as an OpenURL.
1375 TabContents* current_tab = GetSelectedTabContents();
[email protected]cb84d642010-06-10 00:56:281376 if (current_tab && current_tab->showing_interstitial_page()) {
1377 NavigationEntry* entry = current_tab->controller().GetActiveEntry();
1378 DCHECK(entry); // Should exist if interstitial is showing.
1379 OpenURL(entry->url(), GURL(), disposition, PageTransition::RELOAD);
1380 return;
[email protected]36b6dcb2008-11-12 01:19:571381 }
[email protected]cb84d642010-06-10 00:56:281382
1383 // As this is caused by a user action, give the focus to the page.
[email protected]3c9e1872010-11-18 16:17:491384 TabContents* tab = GetOrCloneTabForDisposition(disposition);
1385 if (!tab->FocusLocationBarByDefault())
1386 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281387 if (ignore_cache)
[email protected]3c9e1872010-11-18 16:17:491388 tab->controller().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281389 else
[email protected]3c9e1872010-11-18 16:17:491390 tab->controller().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571391}
1392
[email protected]485fba42009-03-24 23:27:291393void Browser::Home(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591394 UserMetrics::RecordAction(UserMetricsAction("Home"));
[email protected]485fba42009-03-24 23:27:291395 OpenURL(GetHomePage(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
[email protected]36b6dcb2008-11-12 01:19:571396}
1397
[email protected]fbd77592008-11-12 20:50:271398void Browser::OpenCurrentURL() {
[email protected]afd1e522011-04-27 23:29:591399 UserMetrics::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351400 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491401 if (!location_bar)
1402 return;
1403
[email protected]9d0306ea2009-09-02 19:38:391404 WindowOpenDisposition open_disposition =
1405 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271406 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301407 return;
[email protected]03bb953d2010-09-14 21:38:301408
[email protected]83bf2d142009-11-06 18:19:301409 GURL url(WideToUTF8(location_bar->GetInputString()));
[email protected]07d490bc2011-03-07 17:05:261410
1411 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1412 Browser* existing_browser = NULL;
1413 TabContents* existing_tab = TabFinder::GetInstance()->FindTab(
1414 this, url, &existing_browser);
1415 if (existing_tab) {
1416 existing_browser->ActivateContents(existing_tab);
1417 return;
1418 }
1419 }
1420
[email protected]616381f02010-11-02 15:15:331421 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1422 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251423 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1424 // inherit the opener. In some cases the tabstrip will determine the group
1425 // should be inherited, in which case the group is inherited instead of the
1426 // opener.
[email protected]616381f02010-11-02 15:15:331427 params.tabstrip_add_types =
1428 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1429 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331430
[email protected]6e37fe32011-03-02 09:06:521431 DCHECK(profile_->GetExtensionService());
1432 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:331433 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1434 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1435 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1436 }
[email protected]fbd77592008-11-12 20:50:271437}
1438
[email protected]84214982008-12-10 18:49:101439void Browser::Stop() {
[email protected]afd1e522011-04-27 23:29:591440 UserMetrics::RecordAction(UserMetricsAction("Stop"));
[email protected]3c9e1872010-11-18 16:17:491441 GetSelectedTabContentsWrapper()->tab_contents()->Stop();
[email protected]84214982008-12-10 18:49:101442}
1443
1444void Browser::NewWindow() {
[email protected]047e7272010-06-03 19:53:351445 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
[email protected]6e6f6cb2011-01-27 13:26:551446 CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito) &&
[email protected]97b46382011-05-02 13:23:041447 profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled)) {
[email protected]047e7272010-06-03 19:53:351448 NewIncognitoWindow();
1449 return;
1450 }
[email protected]afd1e522011-04-27 23:29:591451 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
[email protected]c9b19942010-03-26 15:58:081452 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:151453 SessionServiceFactory::GetForProfile(profile_->GetOriginalProfile());
[email protected]c9b19942010-03-26 15:58:081454 if (!session_service ||
1455 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1456 Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1457 }
[email protected]84214982008-12-10 18:49:101458}
1459
1460void Browser::NewIncognitoWindow() {
[email protected]97b46382011-05-02 13:23:041461 if (!profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled)) {
[email protected]6e6f6cb2011-01-27 13:26:551462 NewWindow();
1463 return;
1464 }
1465
[email protected]afd1e522011-04-27 23:29:591466 UserMetrics::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]84214982008-12-10 18:49:101467 Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1468}
1469
[email protected]84214982008-12-10 18:49:101470void Browser::CloseWindow() {
[email protected]afd1e522011-04-27 23:29:591471 UserMetrics::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101472 window_->Close();
1473}
1474
[email protected]fbd77592008-11-12 20:50:271475void Browser::NewTab() {
[email protected]afd1e522011-04-27 23:29:591476 UserMetrics::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261477
[email protected]b35b26b32011-05-05 20:35:141478 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271479 AddBlankTab(true);
[email protected]49bb7ea32011-02-02 17:58:061480 GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271481 } else {
[email protected]1a6b30a2009-08-19 03:52:111482 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271483 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051484 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111485 // The call to AddBlankTab above did not set the focus to the tab as its
1486 // window was not active, so we have to do it explicitly.
1487 // See http://crbug.com/6380.
[email protected]3c9e1872010-11-18 16:17:491488 b->GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271489 }
1490}
1491
1492void Browser::CloseTab() {
[email protected]afd1e522011-04-27 23:29:591493 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211494 if (CanCloseTab())
1495 tab_handler_->GetTabStripModel()->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271496}
1497
[email protected]fbd77592008-11-12 20:50:271498void Browser::SelectNextTab() {
[email protected]afd1e522011-04-27 23:29:591499 UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]ecc523f62010-09-28 22:45:401500 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271501}
1502
1503void Browser::SelectPreviousTab() {
[email protected]afd1e522011-04-27 23:29:591504 UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]ecc523f62010-09-28 22:45:401505 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271506}
1507
[email protected]91ac9202010-07-30 18:32:351508void Browser::OpenTabpose() {
1509#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031510 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1511 switches::kEnableExposeForTabs)) {
1512 return;
1513 }
1514
[email protected]afd1e522011-04-27 23:29:591515 UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351516 window()->OpenTabpose();
1517#else
1518 NOTREACHED();
1519#endif
1520}
1521
[email protected]9ac7fcb2009-09-14 18:22:521522void Browser::MoveTabNext() {
[email protected]afd1e522011-04-27 23:29:591523 UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]ecc523f62010-09-28 22:45:401524 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521525}
1526
1527void Browser::MoveTabPrevious() {
[email protected]afd1e522011-04-27 23:29:591528 UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]ecc523f62010-09-28 22:45:401529 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521530}
1531
[email protected]fbd77592008-11-12 20:50:271532void Browser::SelectNumberedTab(int index) {
1533 if (index < tab_count()) {
[email protected]afd1e522011-04-27 23:29:591534 UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]eaca0ad12011-04-18 15:53:411535 tab_handler_->GetTabStripModel()->ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271536 }
1537}
1538
1539void Browser::SelectLastTab() {
[email protected]afd1e522011-04-27 23:29:591540 UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]ecc523f62010-09-28 22:45:401541 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271542}
1543
1544void Browser::DuplicateTab() {
[email protected]afd1e522011-04-27 23:29:591545 UserMetrics::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441546 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271547}
1548
1549void Browser::RestoreTab() {
[email protected]afd1e522011-04-27 23:29:591550 UserMetrics::RecordAction(UserMetricsAction("RestoreTab"));
[email protected]92371eb2011-04-28 11:50:151551 TabRestoreService* service =
1552 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]fbd77592008-11-12 20:50:271553 if (!service)
1554 return;
1555
[email protected]fb7da4132011-03-15 15:51:001556 service->RestoreMostRecentEntry(tab_restore_service_delegate());
[email protected]fbd77592008-11-12 20:50:271557}
1558
[email protected]0c4c3882009-10-01 21:42:141559void Browser::WriteCurrentURLToClipboard() {
1560 // TODO(ericu): There isn't currently a metric for this. Should there be?
1561 // We don't appear to track the action when it comes from the
1562 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141563
1564 TabContents* contents = GetSelectedTabContents();
1565 if (!contents->ShouldDisplayURL())
1566 return;
1567
[email protected]90f39902009-10-03 04:25:371568 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141569 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171570 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141571 g_browser_process->clipboard());
1572}
1573
[email protected]fbd77592008-11-12 20:50:271574void Browser::ConvertPopupToTabbedBrowser() {
[email protected]afd1e522011-04-27 23:29:591575 UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]1ea49d52011-04-12 17:44:441576 int tab_strip_index = tab_handler_->GetTabStripModel()->active_index();
[email protected]3c9e1872010-11-18 16:17:491577 TabContentsWrapper* contents =
[email protected]ecc523f62010-09-28 22:45:401578 tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
[email protected]15952e462008-11-14 00:29:051579 Browser* browser = Browser::Create(profile_);
1580 browser->tabstrip_model()->AppendTabContents(contents, true);
1581 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271582}
1583
[email protected]9282cea2009-02-18 18:49:001584void Browser::ToggleFullscreenMode() {
[email protected]34930432009-11-09 00:12:091585#if !defined(OS_MACOSX)
1586 // In kiosk mode, we always want to be fullscreen. When the browser first
1587 // starts we're not yet fullscreen, so let the initial toggle go through.
1588 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
1589 window_->IsFullscreen())
1590 return;
1591#endif
1592
[email protected]afd1e522011-04-27 23:29:591593 UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
[email protected]9282cea2009-02-18 18:49:001594 window_->SetFullscreen(!window_->IsFullscreen());
[email protected]7be64502011-05-03 17:51:471595 // On X11, setting fullscreen mode is an async call to the X server, which
[email protected]ae2622c2009-07-30 23:47:581596 // may or may not support fullscreen mode.
[email protected]7be64502011-05-03 17:51:471597#if !defined(USE_X11)
[email protected]9282cea2009-02-18 18:49:001598 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
[email protected]ae2622c2009-07-30 23:47:581599#endif
[email protected]9282cea2009-02-18 18:49:001600}
1601
[email protected]da17b372010-01-22 23:37:221602#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331603void Browser::Search() {
1604 // If the NTP is showing, close it.
[email protected]692c5342011-05-25 19:16:211605 const GURL& url = GetSelectedTabContents()->GetURL();
1606 if (web_ui_util::ChromeURLHostEquals(url, chrome::kChromeUINewTabHost)) {
[email protected]f97d7f632010-06-01 21:08:331607 CloseTab();
1608 return;
1609 }
[email protected]64559862010-09-23 19:00:161610
1611 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101612 if (window_->IsFullscreen()) {
[email protected]64559862010-09-23 19:00:161613 ToggleFullscreenMode();
[email protected]ebdda9092010-10-22 17:59:101614 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1615 // visible at this point. Wait for next event cycle which toggles
1616 // the visibility of omnibox before creating new tab.
1617 MessageLoop::current()->PostTask(
1618 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search));
1619 return;
1620 }
[email protected]64559862010-09-23 19:00:161621
[email protected]f97d7f632010-06-01 21:08:331622 // Otherwise just open it.
1623 NewTab();
1624}
[email protected]d14af522010-12-02 03:54:501625
1626void Browser::ShowKeyboardOverlay() {
1627 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1628}
[email protected]20d17242009-10-26 20:21:051629#endif
1630
[email protected]fbd77592008-11-12 20:50:271631void Browser::Exit() {
[email protected]afd1e522011-04-27 23:29:591632 UserMetrics::RecordAction(UserMetricsAction("Exit"));
[email protected]965e4c42010-09-07 21:23:351633#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:351634 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
1635 // Write /tmp/uptime-logout-started as well.
1636 const char kLogoutStarted[] = "logout-started";
1637 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted);
[email protected]db3abe62011-02-09 15:13:251638
1639 // Login screen should show up in owner's locale.
1640 PrefService* state = g_browser_process->local_state();
1641 if (state) {
1642 std::string owner_locale = state->GetString(prefs::kOwnerLocale);
1643 if (!owner_locale.empty() &&
1644 state->GetString(prefs::kApplicationLocale) != owner_locale &&
1645 !state->IsManagedPreference(prefs::kApplicationLocale)) {
1646 state->SetString(prefs::kApplicationLocale, owner_locale);
1647 state->ScheduleSavePersistentPrefs();
1648 }
1649 }
[email protected]965e4c42010-09-07 21:23:351650#endif
[email protected]460a2942010-12-15 19:43:151651 BrowserList::Exit();
[email protected]fbd77592008-11-12 20:50:271652}
1653
[email protected]36b6dcb2008-11-12 01:19:571654void Browser::BookmarkCurrentPage() {
[email protected]afd1e522011-04-27 23:29:591655 UserMetrics::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271656
[email protected]76624fde2009-10-09 18:13:231657 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571658 if (!model || !model->IsLoaded())
1659 return; // Ignore requests until bookmarks are loaded.
1660
[email protected]76624fde2009-10-09 18:13:231661 GURL url;
[email protected]261cd762010-08-20 05:45:371662 string16 title;
[email protected]b375c5d2011-05-03 21:15:041663 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
1664 bookmark_utils::GetURLAndTitleToBookmark(tab->tab_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441665 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211666 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321667 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211668 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041669 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211670 }
[email protected]261cd762010-08-20 05:45:371671 model->SetURLStarred(url, title, true);
[email protected]11dbbd22009-11-06 18:55:041672 // Make sure the model actually added a bookmark before showing the star. A
1673 // bookmark isn't created if the url is invalid.
1674 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271675 // Only show the bubble if the window is active, otherwise we may get into
1676 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441677 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271678 }
[email protected]36b6dcb2008-11-12 01:19:571679}
1680
[email protected]40bdb6d92009-02-25 00:22:271681void Browser::SavePage() {
[email protected]afd1e522011-04-27 23:29:591682 UserMetrics::RecordAction(UserMetricsAction("SavePage"));
[email protected]15d04ae2010-10-30 01:04:501683 TabContents* current_tab = GetSelectedTabContents();
1684 if (current_tab && current_tab->contents_mime_type() == "application/pdf")
[email protected]afd1e522011-04-27 23:29:591685 UserMetrics::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]3ea60632011-04-08 18:25:421686 GetSelectedTabContentsWrapper()->download_tab_helper()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271687}
1688
[email protected]77d8d622010-12-15 10:30:121689void Browser::ViewSelectedSource() {
1690 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571691}
initial.commit09911bf2008-07-26 23:55:291692
[email protected]4801ecc2009-04-05 04:52:581693void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171694 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581695}
1696
[email protected]a3e18c42009-03-04 23:36:051697bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221698 return SupportsWindowFeatureImpl(feature, true);
1699}
[email protected]f5bf8ccf2010-02-05 18:19:251700
[email protected]018cf362010-05-05 22:43:221701bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1702 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051703}
1704
[email protected]89d6e6e2009-12-03 23:06:511705void Browser::EmailPageLocation() {
[email protected]afd1e522011-04-27 23:29:591706 UserMetrics::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]d221a392011-05-24 14:34:241707 TabContents* tc = GetSelectedTabContents();
1708 DCHECK(tc);
1709
1710 std::string title = EscapeQueryParamValue(UTF16ToUTF8(tc->GetTitle()), false);
1711 std::string page_url = EscapeQueryParamValue(tc->GetURL().spec(), false);
1712 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1713 title + "&body=%0A%0A" + page_url;
1714 platform_util::OpenExternal(GURL(mailto));
[email protected]89d6e6e2009-12-03 23:06:511715}
1716
[email protected]fbd77592008-11-12 20:50:271717void Browser::Print() {
[email protected]8980e0d2011-05-27 19:16:231718 if (switches::IsPrintPreviewEnabled())
1719 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1720 else
[email protected]49fe2262011-04-15 20:56:151721 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]fbd77592008-11-12 20:50:271722}
1723
[email protected]fbd77592008-11-12 20:50:271724void Browser::ToggleEncodingAutoDetect() {
[email protected]afd1e522011-04-27 23:29:591725 UserMetrics::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271726 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181727 // If "auto detect" is turned on, then any current override encoding
1728 // is cleared. This also implicitly performs a reload.
1729 // OTOH, if "auto detect" is turned off, we don't change the currently
1730 // active encoding.
1731 if (encoding_auto_detect_.GetValue()) {
1732 TabContents* contents = GetSelectedTabContents();
1733 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081734 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181735 }
[email protected]fbd77592008-11-12 20:50:271736}
1737
1738void Browser::OverrideEncoding(int encoding_id) {
[email protected]afd1e522011-04-27 23:29:591739 UserMetrics::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401740 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271741 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]57c6a652009-05-04 07:58:341742 TabContents* contents = GetSelectedTabContents();
1743 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081744 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271745 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401746 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191747 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1748 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401749 encoding_id,
1750 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271751 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191752 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271753 }
[email protected]36b6dcb2008-11-12 01:19:571754}
1755
[email protected]84214982008-12-10 18:49:101756void Browser::Cut() {
[email protected]afd1e522011-04-27 23:29:591757 UserMetrics::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231758 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571759}
1760
[email protected]84214982008-12-10 18:49:101761void Browser::Copy() {
[email protected]afd1e522011-04-27 23:29:591762 UserMetrics::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231763 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571764}
1765
[email protected]84214982008-12-10 18:49:101766void Browser::Paste() {
[email protected]afd1e522011-04-27 23:29:591767 UserMetrics::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231768 window()->Paste();
[email protected]84214982008-12-10 18:49:101769}
1770
1771void Browser::Find() {
[email protected]afd1e522011-04-27 23:29:591772 UserMetrics::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291773 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101774}
1775
1776void Browser::FindNext() {
[email protected]afd1e522011-04-27 23:29:591777 UserMetrics::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291778 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101779}
1780
1781void Browser::FindPrevious() {
[email protected]afd1e522011-04-27 23:29:591782 UserMetrics::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291783 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101784}
1785
[email protected]40bd6582009-12-04 23:49:511786void Browser::Zoom(PageZoom::Function zoom_function) {
[email protected]896220042010-03-23 18:14:281787 static const UserMetricsAction kActions[] = {
[email protected]216813952011-05-19 22:21:261788 UserMetricsAction("ZoomMinus"),
1789 UserMetricsAction("ZoomNormal"),
1790 UserMetricsAction("ZoomPlus")
1791 };
[email protected]896220042010-03-23 18:14:281792
[email protected]afd1e522011-04-27 23:29:591793 UserMetrics::RecordAction(kActions[zoom_function - PageZoom::ZOOM_OUT]);
[email protected]3c9e1872010-11-18 16:17:491794 TabContentsWrapper* tab_contents = GetSelectedTabContentsWrapper();
[email protected]216813952011-05-19 22:21:261795 RenderViewHost* host = tab_contents->render_view_host();
1796 host->Send(new ViewMsg_Zoom(host->routing_id(), zoom_function));
[email protected]84214982008-12-10 18:49:101797}
1798
1799void Browser::FocusToolbar() {
[email protected]afd1e522011-04-27 23:29:591800 UserMetrics::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:101801 window_->FocusToolbar();
1802}
1803
[email protected]bdb7ff62010-07-20 01:56:521804void Browser::FocusAppMenu() {
[email protected]afd1e522011-04-27 23:29:591805 UserMetrics::RecordAction(UserMetricsAction("FocusAppMenu"));
[email protected]bdb7ff62010-07-20 01:56:521806 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:011807}
1808
[email protected]84214982008-12-10 18:49:101809void Browser::FocusLocationBar() {
[email protected]afd1e522011-04-27 23:29:591810 UserMetrics::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:581811 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:101812}
1813
[email protected]83548a42010-06-18 13:53:371814void Browser::FocusBookmarksToolbar() {
[email protected]afd1e522011-04-27 23:29:591815 UserMetrics::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:371816 window_->FocusBookmarksToolbar();
1817}
1818
1819void Browser::FocusChromeOSStatus() {
[email protected]afd1e522011-04-27 23:29:591820 UserMetrics::RecordAction(UserMetricsAction("FocusChromeOSStatus"));
[email protected]83548a42010-06-18 13:53:371821 window_->FocusChromeOSStatus();
1822}
1823
1824void Browser::FocusNextPane() {
[email protected]afd1e522011-04-27 23:29:591825 UserMetrics::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:371826 window_->RotatePaneFocus(true);
1827}
1828
1829void Browser::FocusPreviousPane() {
[email protected]afd1e522011-04-27 23:29:591830 UserMetrics::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:371831 window_->RotatePaneFocus(false);
1832}
1833
[email protected]84214982008-12-10 18:49:101834void Browser::FocusSearch() {
1835 // TODO(beng): replace this with FocusLocationBar
[email protected]afd1e522011-04-27 23:29:591836 UserMetrics::RecordAction(UserMetricsAction("FocusSearch"));
[email protected]7745b822009-01-27 20:15:351837 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:101838}
1839
1840void Browser::OpenFile() {
[email protected]afd1e522011-04-27 23:29:591841 UserMetrics::RecordAction(UserMetricsAction("OpenFile"));
[email protected]9d1d8ad52011-03-11 22:58:171842#if defined(OS_CHROMEOS) && !defined(FILE_MANAGER_EXTENSION)
[email protected]f59f1162010-04-23 21:19:291843 FileBrowseUI::OpenPopup(profile_,
1844 "",
1845 FileBrowseUI::kPopupWidth,
1846 FileBrowseUI::kPopupHeight);
1847#else
[email protected]84214982008-12-10 18:49:101848 if (!select_file_dialog_.get())
1849 select_file_dialog_ = SelectFileDialog::Create(this);
1850
[email protected]35896a32010-06-09 08:42:511851 const FilePath directory = profile_->last_selected_directory();
1852
[email protected]84214982008-12-10 18:49:101853 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:561854 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:101855 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:511856 string16(), directory,
[email protected]b949f1112009-04-12 20:03:081857 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]d9898912011-04-15 21:10:001858 GetSelectedTabContents(),
[email protected]d56bcd22009-03-16 19:51:561859 parent_window, NULL);
[email protected]f59f1162010-04-23 21:19:291860#endif
[email protected]84214982008-12-10 18:49:101861}
1862
1863void Browser::OpenCreateShortcutsDialog() {
[email protected]afd1e522011-04-27 23:29:591864 UserMetrics::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:471865#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:491866 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1867 DCHECK(current_tab &&
1868 web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
1869 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:511870
1871 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
1872 if (!entry)
1873 return;
1874
[email protected]eabfdae92009-12-11 06:13:511875 // RVH's GetApplicationInfo should not be called before it returns.
1876 DCHECK(pending_web_app_action_ == NONE);
1877 pending_web_app_action_ = CREATE_SHORTCUT;
1878
[email protected]a2cf65eb2010-01-18 08:20:381879 // Start fetching web app info for CreateApplicationShortcut dialog and show
1880 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]553602e12011-04-05 17:01:181881 current_tab->extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]98f6e022009-06-05 22:49:531882#else
1883 NOTIMPLEMENTED();
1884#endif
[email protected]36b6dcb2008-11-12 01:19:571885}
1886
[email protected]2a8a98122010-07-16 11:58:481887void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
1888 std::string uma_string;
1889 switch (action) {
1890 case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
1891 uma_string = "DevTools_ToggleConsole";
1892 break;
1893 case DEVTOOLS_TOGGLE_ACTION_NONE:
1894 case DEVTOOLS_TOGGLE_ACTION_INSPECT:
1895 default:
1896 uma_string = "DevTools_ToggleWindow";
1897 break;
1898 }
[email protected]afd1e522011-04-27 23:29:591899 UserMetrics::RecordAction(UserMetricsAction(uma_string.c_str()));
[email protected]3061ccf32009-07-13 14:17:491900 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
[email protected]3c9e1872010-11-18 16:17:491901 GetSelectedTabContentsWrapper()->render_view_host(), action);
[email protected]fbd77592008-11-12 20:50:271902}
1903
[email protected]adb6a84d2011-02-07 16:58:401904void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]afd1e522011-04-27 23:29:591905 UserMetrics::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:401906 if (highlight_background_resources)
1907 window_->ShowBackgroundPages();
1908 else
1909 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:101910}
1911
[email protected]84214982008-12-10 18:49:101912void Browser::OpenBugReportDialog() {
[email protected]afd1e522011-04-27 23:29:591913 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]35d06152011-01-10 22:19:421914 browser::ShowHtmlBugReportView(this);
[email protected]84214982008-12-10 18:49:101915}
[email protected]44b2c8852009-03-18 00:57:491916
[email protected]84214982008-12-10 18:49:101917void Browser::ToggleBookmarkBar() {
[email protected]afd1e522011-04-27 23:29:591918 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:101919 window_->ToggleBookmarkBar();
1920}
1921
[email protected]84214982008-12-10 18:49:101922void Browser::OpenBookmarkManager() {
[email protected]afd1e522011-04-27 23:29:591923 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"));
[email protected]47e532b2010-04-23 17:46:401924 ShowBookmarkManagerTab();
[email protected]84214982008-12-10 18:49:101925}
[email protected]8bf80e922009-03-09 20:56:361926
[email protected]fdb98512009-08-26 01:37:101927void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:121928 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:101929 window_->ShowAppMenu();
1930}
1931
[email protected]6404197b2010-03-03 00:40:401932void Browser::ShowBookmarkManagerTab() {
[email protected]afd1e522011-04-27 23:29:591933 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]fee320542011-03-02 01:30:491934 ShowSingletonTab(GURL(chrome::kChromeUIBookmarksURL));
[email protected]6404197b2010-03-03 00:40:401935}
1936
[email protected]8bf80e922009-03-09 20:56:361937void Browser::ShowHistoryTab() {
[email protected]afd1e522011-04-27 23:29:591938 UserMetrics::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]fee320542011-03-02 01:30:491939 ShowSingletonTab(GURL(chrome::kChromeUIHistoryURL));
[email protected]8bf80e922009-03-09 20:56:361940}
[email protected]84214982008-12-10 18:49:101941
1942void Browser::ShowDownloadsTab() {
[email protected]afd1e522011-04-27 23:29:591943 UserMetrics::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]3d037ce72011-04-04 17:43:451944 if (window()) {
1945 DownloadShelf* shelf = window()->GetDownloadShelf();
1946 if (shelf->IsShowing())
1947 shelf->Close();
1948 }
[email protected]fee320542011-03-02 01:30:491949 ShowSingletonTab(GURL(chrome::kChromeUIDownloadsURL));
[email protected]84214982008-12-10 18:49:101950}
1951
[email protected]34085a32009-11-06 22:49:481952void Browser::ShowExtensionsTab() {
[email protected]afd1e522011-04-27 23:29:591953 UserMetrics::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]fee320542011-03-02 01:30:491954 ShowSingletonTab(GURL(chrome::kChromeUIExtensionsURL));
[email protected]34085a32009-11-06 22:49:481955}
1956
[email protected]c1bbaa82010-11-08 11:17:051957void Browser::ShowAboutConflictsTab() {
[email protected]afd1e522011-04-27 23:29:591958 UserMetrics::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:491959 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:051960}
1961
[email protected]10e457c2010-04-29 03:35:231962void Browser::ShowBrokenPageTab(TabContents* contents) {
[email protected]afd1e522011-04-27 23:29:591963 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]10e457c2010-04-29 03:35:231964 string16 page_title = contents->GetTitle();
1965 NavigationEntry* entry = contents->controller().GetActiveEntry();
1966 if (!entry)
1967 return;
1968 std::string page_url = entry->url().spec();
1969 std::vector<std::string> subst;
1970 subst.push_back(UTF16ToASCII(page_title));
1971 subst.push_back(page_url);
1972 std::string report_page_url =
1973 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:491974 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:231975}
1976
[email protected]12e816bde2010-09-14 19:59:291977void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]e50eeee2010-09-22 00:33:301978 GURL url(chrome::kChromeUISettingsURL + sub_page);
[email protected]fee320542011-03-02 01:30:491979 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1980 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1981 browser::Navigate(&params);
[email protected]4a42d272010-06-18 01:29:421982}
1983
[email protected]84214982008-12-10 18:49:101984void Browser::OpenClearBrowsingDataDialog() {
[email protected]afd1e522011-04-27 23:29:591985 UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:051986 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:101987}
1988
[email protected]84214982008-12-10 18:49:101989void Browser::OpenOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:591990 UserMetrics::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]445177652011-03-09 02:04:051991 GURL url(chrome::kChromeUISettingsURL);
1992 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1993 params.path_behavior = browser::NavigateParams::IGNORE_AND_STAY_PUT;
1994 browser::Navigate(&params);
[email protected]fbd77592008-11-12 20:50:271995}
1996
1997void Browser::OpenPasswordManager() {
[email protected]afd1e522011-04-27 23:29:591998 UserMetrics::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:041999 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272000}
2001
[email protected]1bdf29e2009-05-11 23:45:252002void Browser::OpenImportSettingsDialog() {
[email protected]afd1e522011-04-27 23:29:592003 UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052004 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252005}
[email protected]1bdf29e2009-05-11 23:45:252006
[email protected]b99081b2011-03-10 17:43:472007void Browser::OpenInstantConfirmDialog() {
2008 ShowOptionsTab(chrome::kInstantConfirmPage);
2009}
2010
[email protected]ca38d8e2009-08-20 18:08:162011void Browser::OpenSyncMyBookmarksDialog() {
[email protected]40f047972009-11-25 03:54:402012 sync_ui_util::OpenSyncMyBookmarksDialog(
[email protected]c8de64a2011-01-25 17:10:232013 profile_, this, ProfileSyncService::START_FROM_WRENCH);
[email protected]ca38d8e2009-08-20 18:08:162014}
[email protected]ca38d8e2009-08-20 18:08:162015
[email protected]fbd77592008-11-12 20:50:272016void Browser::OpenAboutChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592017 UserMetrics::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]976e69f2010-08-13 18:28:172018#if defined(OS_CHROMEOS)
[email protected]fee320542011-03-02 01:30:492019 ShowSingletonTab(GURL(chrome::kChromeUIAboutURL));
[email protected]976e69f2010-08-13 18:28:172020#else
[email protected]2d46c842008-11-14 19:24:312021 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:172022#endif
[email protected]fbd77592008-11-12 20:50:272023}
2024
[email protected]b1b73942010-05-26 20:11:542025void Browser::OpenUpdateChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592026 UserMetrics::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542027 window_->ShowUpdateChromeDialog();
2028}
2029
[email protected]fbd77592008-11-12 20:50:272030void Browser::OpenHelpTab() {
[email protected]0a4a0be2010-11-09 10:42:472031 GURL help_url(kHelpContentUrl);
[email protected]0a4a0be2010-11-09 10:42:472032 GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
2033 AddSelectedTabWithURL(localized_help_url, PageTransition::AUTO_BOOKMARK);
[email protected]fbd77592008-11-12 20:50:272034}
2035
[email protected]403c14862009-10-28 00:00:492036void Browser::OpenThemeGalleryTabAndActivate() {
[email protected]616381f02010-11-02 15:15:332037 AddSelectedTabWithURL(GURL(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)),
2038 PageTransition::LINK);
[email protected]403c14862009-10-28 00:00:492039}
2040
[email protected]31cc1c022010-10-15 20:03:472041void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]3e0505452010-11-02 21:45:242042 OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
2043 NEW_FOREGROUND_TAB, PageTransition::LINK);
[email protected]31cc1c022010-10-15 20:03:472044 window_->Activate();
2045}
2046
[email protected]663bd9e2011-03-21 01:07:012047void Browser::OpenAutofillHelpTabAndActivate() {
[email protected]91a79232010-11-10 18:15:082048 GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
2049 AddSelectedTabWithURL(help_url, PageTransition::LINK);
[email protected]bb8fe2d2010-06-28 20:04:222050}
2051
[email protected]024617a2010-08-20 05:08:052052void Browser::OpenSearchEngineOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592053 UserMetrics::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052054 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052055}
2056
[email protected]16779842009-07-08 23:45:292057#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:052058void Browser::OpenFileManager() {
2059 UserMetrics::RecordAction(UserMetricsAction("OpenFileManager"));
2060 ShowSingletonTab(FileManagerUtil::GetFileBrowserUrl());
2061}
2062
[email protected]5dcbc02f2010-01-26 22:32:062063void Browser::OpenSystemOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592064 UserMetrics::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"));
[email protected]445177652011-03-09 02:04:052065 ShowOptionsTab(chrome::kSystemOptionsSubPage);
[email protected]5dcbc02f2010-01-26 22:32:062066}
2067
2068void Browser::OpenInternetOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592069 UserMetrics::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"));
[email protected]445177652011-03-09 02:04:052070 ShowOptionsTab(chrome::kInternetOptionsSubPage);
[email protected]024617a2010-08-20 05:08:052071}
2072
2073void Browser::OpenLanguageOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592074 UserMetrics::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"));
[email protected]445177652011-03-09 02:04:052075 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
[email protected]be715072009-07-07 15:43:202076}
[email protected]46b92f852010-10-06 13:12:052077
2078void Browser::OpenSystemTabAndActivate() {
2079 OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
2080 NEW_FOREGROUND_TAB, PageTransition::LINK);
2081 window_->Activate();
2082}
2083
[email protected]38017612010-10-13 18:46:002084void Browser::OpenMobilePlanTabAndActivate() {
2085 OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
2086 NEW_FOREGROUND_TAB, PageTransition::LINK);
2087 window_->Activate();
2088}
[email protected]be715072009-07-07 15:43:202089#endif
2090
[email protected]a003d8e2010-10-02 21:03:352091void Browser::OpenPluginsTabAndActivate() {
2092 OpenURL(GURL(chrome::kAboutPluginsURL), GURL(),
2093 NEW_FOREGROUND_TAB, PageTransition::LINK);
2094 window_->Activate();
2095}
2096
[email protected]36b6dcb2008-11-12 01:19:572097///////////////////////////////////////////////////////////////////////////////
2098
2099// static
[email protected]79117172009-08-28 16:11:442100void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542101 const PrefService::Preference* home_page_pref =
2102 prefs->FindPreference(prefs::kHomePage);
2103 if (home_page_pref &&
2104 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192105 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:332106 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:192107 GoogleURLTracker::kDefaultGoogleHomepage);
2108 }
[email protected]8fe6e1c2010-05-27 08:21:542109 const PrefService::Preference* home_page_is_new_tab_page_pref =
2110 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2111 if (home_page_is_new_tab_page_pref &&
2112 !home_page_is_new_tab_page_pref->IsManaged() &&
2113 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332114 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442115}
2116
2117// static
[email protected]36b6dcb2008-11-12 01:19:572118void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572119 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]8b8e7c92010-08-19 18:05:562120 prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
[email protected]f87919d72011-02-02 18:46:162121 prefs->RegisterIntegerPref(prefs::kMultipleProfilePrefMigration, 0);
[email protected]d9898912011-04-15 21:10:002122 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]09d81f82010-12-15 16:46:422123 // Educated guess: Chrome has a bundled Flash version supporting
2124 // clearing LSO data, Chromium hasn't.
2125#if defined(GOOGLE_CHROME_BUILD)
2126 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, true);
2127#else
2128 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, false);
2129#endif
[email protected]36b6dcb2008-11-12 01:19:572130}
2131
2132// static
2133void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182134 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]d36f941b2011-05-09 06:19:162135 chrome::kChromeUINewTabURL,
2136 PrefService::SYNCABLE_PREF);
2137 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2138 true,
2139 PrefService::SYNCABLE_PREF);
2140 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2141 false,
2142 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092143#if defined(OS_MACOSX)
2144 // This really belongs in platform code, but there's no good place to
2145 // initialize it between the time when the AppController is created
2146 // (where there's no profile) and the time the controller gets another
2147 // crack at the start of the main event loop. By that time, BrowserInit
2148 // has already created the browser window, and it's too late: we need the
2149 // pref to be already initialized. Doing it here also saves us from having
2150 // to hard-code pref registration in the several unit tests that use
2151 // this preference.
[email protected]d36f941b2011-05-09 06:19:162152 prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
2153 false,
2154 PrefService::SYNCABLE_PREF);
2155 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2156 true,
2157 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092158#endif
[email protected]d36f941b2011-05-09 06:19:162159 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2160 true,
2161 PrefService::SYNCABLE_PREF);
2162 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2163 true,
2164 PrefService::SYNCABLE_PREF);
2165 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2166 true,
2167 PrefService::SYNCABLE_PREF);
2168 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2169 true,
2170 PrefService::SYNCABLE_PREF);
2171 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2172 false,
2173 PrefService::SYNCABLE_PREF);
2174 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2175 false,
2176 PrefService::SYNCABLE_PREF);
2177 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2178 0,
2179 PrefService::SYNCABLE_PREF);
2180 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2181 true,
2182 PrefService::UNSYNCABLE_PREF);
2183 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2184 true,
2185 PrefService::UNSYNCABLE_PREF);
2186 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2187 true,
2188 PrefService::UNSYNCABLE_PREF);
2189 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2190 true,
2191 PrefService::UNSYNCABLE_PREF);
2192 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2193 true,
2194 PrefService::UNSYNCABLE_PREF);
2195 prefs->RegisterBooleanPref(prefs::kUseVerticalTabs,
2196 false,
2197 PrefService::UNSYNCABLE_PREF);
[email protected]ac86c982011-05-11 13:26:052198 prefs->RegisterBooleanPref(prefs::kUseCompactNavigationBar,
2199 false,
2200 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162201 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2202 true,
2203 PrefService::SYNCABLE_PREF);
2204 prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar,
2205 true,
2206 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162207 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2208 std::string(),
2209 PrefService::UNSYNCABLE_PREF);
2210 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2211 true,
2212 PrefService::UNSYNCABLE_PREF);
2213 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2214 false,
2215 PrefService::UNSYNCABLE_PREF);
2216 prefs->RegisterBooleanPref(prefs::kIncognitoEnabled,
2217 true,
2218 PrefService::UNSYNCABLE_PREF);
2219 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
2220 -1,
2221 PrefService::UNSYNCABLE_PREF);
2222 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2223 PrefService::UNSYNCABLE_PREF);
2224 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2225 PrefService::UNSYNCABLE_PREF);
[email protected]2bf2bd92011-03-31 07:12:442226 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162227 // them even though they're only typically controlled via policy.
2228 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2229 false,
2230 PrefService::UNSYNCABLE_PREF);
2231 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2232 false,
2233 PrefService::UNSYNCABLE_PREF);
2234 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2235 false,
2236 PrefService::UNSYNCABLE_PREF);
2237 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2238 true,
2239 PrefService::UNSYNCABLE_PREF);
2240 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2241 true,
2242 PrefService::UNSYNCABLE_PREF);
2243 prefs->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent,
[email protected]f43fd974d2011-06-01 18:53:192244 false,
[email protected]d36f941b2011-05-09 06:19:162245 PrefService::UNSYNCABLE_PREF);
[email protected]839fee772011-05-05 03:21:372246 prefs->RegisterBooleanPref(prefs::kWebKitAllowDisplayingInsecureContent,
[email protected]d36f941b2011-05-09 06:19:162247 true,
2248 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572249}
2250
2251// static
[email protected]ecc523f62010-09-28 22:45:402252bool Browser::RunUnloadEventsHelper(TabContents* contents) {
2253 // If the TabContents is not connected yet, then there's no unload
2254 // handler we can fire even if the TabContents has an unload listener.
2255 // One case where we hit this is in a tab that has an infinite loop
2256 // before load.
[email protected]5aab5e22010-12-08 22:13:292257 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402258 // If the page has unload listeners, then we tell the renderer to fire
2259 // them. Once they have fired, we'll get a message back saying whether
2260 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292261 // with the NeedToFireBeforeUnload bit cleared.
[email protected]ecc523f62010-09-28 22:45:402262 contents->render_view_host()->FirePageBeforeUnload(false);
2263 return true;
2264 }
2265 return false;
2266}
2267
2268// static
[email protected]36b6dcb2008-11-12 01:19:572269Browser* Browser::GetBrowserForController(
2270 const NavigationController* controller, int* index_result) {
2271 BrowserList::const_iterator it;
2272 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]ecc523f62010-09-28 22:45:402273 int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
2274 controller);
[email protected]36b6dcb2008-11-12 01:19:572275 if (index != TabStripModel::kNoTab) {
2276 if (index_result)
2277 *index_result = index;
2278 return *it;
2279 }
2280 }
2281
2282 return NULL;
2283}
2284
[email protected]485fba42009-03-24 23:27:292285void Browser::ExecuteCommandWithDisposition(
2286 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142287 // No commands are enabled if there is not yet any selected tab.
2288 // TODO(pkasting): It seems like we should not need this, because either
2289 // most/all commands should not have been enabled yet anyway or the ones that
2290 // are enabled should be global, or safe themselves against having no selected
2291 // tab. However, Ben says he tried removing this before and got lots of
2292 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2293 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492294 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142295 return;
2296
[email protected]59c9f002010-11-19 00:38:052297 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2298 << id;
[email protected]36b6dcb2008-11-12 01:19:572299
[email protected]867125a02009-12-10 06:01:482300 // If command execution is blocked then just record the command and return.
2301 if (block_command_execution_) {
2302 // We actually only allow no more than one blocked command, otherwise some
2303 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062304 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482305 last_blocked_command_id_ = id;
2306 last_blocked_command_disposition_ = disposition;
2307 return;
2308 }
2309
[email protected]fbd77592008-11-12 20:50:272310 // The order of commands in this switch statement must match the function
2311 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572312 switch (id) {
[email protected]84214982008-12-10 18:49:102313 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282314 case IDC_BACK: GoBack(disposition); break;
2315 case IDC_FORWARD: GoForward(disposition); break;
2316 case IDC_RELOAD: Reload(disposition); break;
2317 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2318 case IDC_HOME: Home(disposition); break;
2319 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282320 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572321
[email protected]84214982008-12-10 18:49:102322 // Window management commands
[email protected]cb84d642010-06-10 00:56:282323 case IDC_NEW_WINDOW: NewWindow(); break;
2324 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282325 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2326 case IDC_NEW_TAB: NewTab(); break;
2327 case IDC_CLOSE_TAB: CloseTab(); break;
2328 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2329 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352330 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282331 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2332 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572333 case IDC_SELECT_TAB_0:
2334 case IDC_SELECT_TAB_1:
2335 case IDC_SELECT_TAB_2:
2336 case IDC_SELECT_TAB_3:
2337 case IDC_SELECT_TAB_4:
2338 case IDC_SELECT_TAB_5:
2339 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542340 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282341 break;
2342 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2343 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2344 case IDC_RESTORE_TAB: RestoreTab(); break;
2345 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2346 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
2347 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
2348 case IDC_EXIT: Exit(); break;
2349 case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break;
[email protected]ac86c982011-05-11 13:26:052350 case IDC_COMPACT_NAVBAR: ToggleUseCompactNavigationBar(); break;
[email protected]da17b372010-01-22 23:37:222351#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282352 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:502353 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052354#endif
[email protected]36b6dcb2008-11-12 01:19:572355
[email protected]84214982008-12-10 18:49:102356 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282357 case IDC_SAVE_PAGE: SavePage(); break;
2358 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2359 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122360 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282361 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2362 case IDC_PRINT: Print(); break;
2363 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572364 case IDC_ENCODING_UTF8:
2365 case IDC_ENCODING_UTF16LE:
2366 case IDC_ENCODING_ISO88591:
2367 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492368 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572369 case IDC_ENCODING_GB18030:
2370 case IDC_ENCODING_BIG5HKSCS:
2371 case IDC_ENCODING_BIG5:
2372 case IDC_ENCODING_KOREAN:
2373 case IDC_ENCODING_SHIFTJIS:
2374 case IDC_ENCODING_ISO2022JP:
2375 case IDC_ENCODING_EUCJP:
2376 case IDC_ENCODING_THAI:
2377 case IDC_ENCODING_ISO885915:
2378 case IDC_ENCODING_MACINTOSH:
2379 case IDC_ENCODING_ISO88592:
2380 case IDC_ENCODING_WINDOWS1250:
2381 case IDC_ENCODING_ISO88595:
2382 case IDC_ENCODING_WINDOWS1251:
2383 case IDC_ENCODING_KOI8R:
2384 case IDC_ENCODING_KOI8U:
2385 case IDC_ENCODING_ISO88597:
2386 case IDC_ENCODING_WINDOWS1253:
2387 case IDC_ENCODING_ISO88594:
2388 case IDC_ENCODING_ISO885913:
2389 case IDC_ENCODING_WINDOWS1257:
2390 case IDC_ENCODING_ISO88593:
2391 case IDC_ENCODING_ISO885910:
2392 case IDC_ENCODING_ISO885914:
2393 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572394 case IDC_ENCODING_WINDOWS1254:
2395 case IDC_ENCODING_ISO88596:
2396 case IDC_ENCODING_WINDOWS1256:
2397 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002398 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572399 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282400 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572401
[email protected]84214982008-12-10 18:49:102402 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282403 case IDC_CUT: Cut(); break;
2404 case IDC_COPY: Copy(); break;
2405 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102406
2407 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282408 case IDC_FIND: Find(); break;
2409 case IDC_FIND_NEXT: FindNext(); break;
2410 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102411
2412 // Zoom
[email protected]cb84d642010-06-10 00:56:282413 case IDC_ZOOM_PLUS: Zoom(PageZoom::ZOOM_IN); break;
2414 case IDC_ZOOM_NORMAL: Zoom(PageZoom::RESET); break;
2415 case IDC_ZOOM_MINUS: Zoom(PageZoom::ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102416
2417 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282418 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2419 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2420 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522421 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372422 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
2423 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
2424 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2425 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102426
2427 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282428 case IDC_OPEN_FILE: OpenFile(); break;
2429 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482430 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2431 DEVTOOLS_TOGGLE_ACTION_NONE);
2432 break;
2433 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2434 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2435 break;
2436 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2437 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2438 break;
[email protected]adb6a84d2011-02-07 16:58:402439 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2440 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]1c41a932010-11-22 23:41:232441 case IDC_FEEDBACK: OpenBugReportDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492442
[email protected]cb84d642010-06-10 00:56:282443 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252444 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492445
[email protected]cb84d642010-06-10 00:56:282446 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2447 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]cb84d642010-06-10 00:56:282448 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2449 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2450 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
2451 case IDC_SYNC_BOOKMARKS: OpenSyncMyBookmarksDialog(); break;
2452 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052453 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282454 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2455 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2456 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412457 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2458 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052459 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]cb84d642010-06-10 00:56:282460 case IDC_HELP_PAGE: OpenHelpTab(); break;
[email protected]16779842009-07-08 23:45:292461#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:052462 case IDC_FILE_MANAGER: OpenFileManager(); break;
[email protected]cb84d642010-06-10 00:56:282463 case IDC_SYSTEM_OPTIONS: OpenSystemOptionsDialog(); break;
2464 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:052465 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:202466#endif
[email protected]d938aed92009-01-22 19:49:332467
[email protected]36b6dcb2008-11-12 01:19:572468 default:
[email protected]84214982008-12-10 18:49:102469 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272470 break;
[email protected]36b6dcb2008-11-12 01:19:572471 }
2472}
2473
[email protected]3ab6796d32010-12-21 23:56:072474bool Browser::ExecuteCommandIfEnabled(int id) {
2475 if (command_updater_.SupportsCommand(id) &&
2476 command_updater_.IsCommandEnabled(id)) {
2477 ExecuteCommand(id);
2478 return true;
2479 }
2480 return false;
2481}
2482
[email protected]06181422011-02-09 17:44:212483bool Browser::IsReservedCommandOrKey(int command_id,
2484 const NativeWebKeyboardEvent& event) {
[email protected]06181422011-02-09 17:44:212485#if defined(OS_CHROMEOS)
2486 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
2487 // aren't able to block Chrome from performing the standard actions for F1-F4
2488 // (F5-7 are grabbed by other X clients and hence don't need this protection,
2489 // and F8-10 are handled separately in Chrome via a GDK event filter, but
2490 // let's future-proof this).
2491 ui::KeyboardCode key_code =
[email protected]6a1ae6cd2011-02-11 20:06:092492 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]06181422011-02-09 17:44:212493 if (key_code == ui::VKEY_F1 ||
2494 key_code == ui::VKEY_F2 ||
2495 key_code == ui::VKEY_F3 ||
2496 key_code == ui::VKEY_F4 ||
2497 key_code == ui::VKEY_F5 ||
2498 key_code == ui::VKEY_F6 ||
2499 key_code == ui::VKEY_F7 ||
2500 key_code == ui::VKEY_F8 ||
2501 key_code == ui::VKEY_F9 ||
2502 key_code == ui::VKEY_F10) {
[email protected]6a1ae6cd2011-02-11 20:06:092503 return true;
[email protected]06181422011-02-09 17:44:212504 }
2505#endif
2506
[email protected]6a1ae6cd2011-02-11 20:06:092507 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:482508 command_id == IDC_CLOSE_WINDOW ||
2509 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2510 command_id == IDC_NEW_TAB ||
2511 command_id == IDC_NEW_WINDOW ||
2512 command_id == IDC_RESTORE_TAB ||
2513 command_id == IDC_SELECT_NEXT_TAB ||
2514 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:552515 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:332516 command_id == IDC_EXIT ||
2517 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:482518}
2519
2520void Browser::SetBlockCommandExecution(bool block) {
2521 block_command_execution_ = block;
2522 if (block) {
2523 last_blocked_command_id_ = -1;
2524 last_blocked_command_disposition_ = CURRENT_TAB;
2525 }
2526}
2527
2528int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2529 if (disposition)
2530 *disposition = last_blocked_command_disposition_;
2531 return last_blocked_command_id_;
2532}
2533
[email protected]3c9e1872010-11-18 16:17:492534void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]19d9f3a2010-10-14 21:49:362535 PageTransition::Type transition,
2536 bool user_initiated) {
2537 tabstrip_model()->TabNavigating(contents, transition);
2538
[email protected]3c9e1872010-11-18 16:17:492539 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:362540 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2541 // Forcibly reset the location bar if the url is going to change in the
2542 // current tab, since otherwise it won't discard any ongoing user edits,
2543 // since it doesn't realize this is a user-initiated action.
2544 window()->GetLocationBar()->Revert();
2545 }
2546
2547 if (GetStatusBubble())
2548 GetStatusBubble()->Hide();
2549
2550 // Update the location bar. This is synchronous. We specifically don't
2551 // update the load state since the load hasn't started yet and updating it
2552 // will put it out of sync with the actual state like whether we're
2553 // displaying a favicon, which controls the throbber. If we updated it here,
2554 // the throbber will show the default favicon for a split second when
2555 // navigating away from the new tab page.
[email protected]3c9e1872010-11-18 16:17:492556 ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
[email protected]19d9f3a2010-10-14 21:49:362557
2558 if (contents_is_selected)
[email protected]3c9e1872010-11-18 16:17:492559 contents->tab_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:362560}
2561
2562GURL Browser::GetHomePage() const {
2563 // --homepage overrides any preferences.
2564 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2565 if (command_line.HasSwitch(switches::kHomePage)) {
[email protected]a8e4b5a82010-10-27 00:05:472566 // TODO(evanm): clean up usage of DIR_CURRENT.
2567 // http://code.google.com/p/chromium/issues/detail?id=60630
2568 // For now, allow this code to call getcwd().
2569 base::ThreadRestrictions::ScopedAllowIO allow_io;
2570
[email protected]19d9f3a2010-10-14 21:49:362571 FilePath browser_directory;
2572 PathService::Get(base::DIR_CURRENT, &browser_directory);
2573 GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory,
2574 command_line.GetSwitchValuePath(switches::kHomePage)));
2575 if (home_page.is_valid())
2576 return home_page;
2577 }
2578
2579 if (profile_->GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
2580 return GURL(chrome::kChromeUINewTabURL);
2581 GURL home_page(URLFixerUpper::FixupURL(
2582 profile_->GetPrefs()->GetString(prefs::kHomePage),
2583 std::string()));
2584 if (!home_page.is_valid())
2585 return GURL(chrome::kChromeUINewTabURL);
2586 return home_page;
2587}
2588
[email protected]36b6dcb2008-11-12 01:19:572589///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402590// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:362591
[email protected]ecc523f62010-09-28 22:45:402592void Browser::OpenURL(const GURL& url, const GURL& referrer,
2593 WindowOpenDisposition disposition,
2594 PageTransition::Type transition) {
2595 OpenURLFromTab(NULL, url, referrer, disposition, transition);
2596}
2597
2598///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:292599// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2600
2601void Browser::ExecuteCommand(int id) {
2602 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2603}
2604
2605///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402606// Browser, TabHandlerDelegate implementation:
2607
2608Profile* Browser::GetProfile() const {
2609 return profile();
2610}
2611
2612Browser* Browser::AsBrowser() {
2613 return this;
2614}
2615
2616///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572617// Browser, TabStripModelDelegate implementation:
2618
[email protected]3c9e1872010-11-18 16:17:492619TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582620 return AddBlankTabAt(-1, foreground);
2621}
2622
[email protected]3c9e1872010-11-18 16:17:492623TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052624 // Time new tab page creation time. We keep track of the timing data in
2625 // TabContents, but we want to include the time it takes to create the
2626 // TabContents object too.
2627 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332628 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
2629 PageTransition::TYPED);
[email protected]616381f02010-11-02 15:15:332630 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2631 params.tabstrip_index = index;
2632 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:492633 params.target_contents->tab_contents()->set_new_tab_start_time(
2634 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332635 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052636}
2637
[email protected]3c9e1872010-11-18 16:17:492638Browser* Browser::CreateNewStripWithContents(
2639 TabContentsWrapper* detached_contents,
2640 const gfx::Rect& window_bounds,
2641 const DockInfo& dock_info,
2642 bool maximize) {
[email protected]018cf362010-05-05 22:43:222643 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:062644
[email protected]5e495462008-11-20 23:07:412645 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:412646 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2647 dock_info.AdjustOtherWindowBounds();
2648
[email protected]36b6dcb2008-11-12 01:19:572649 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:142650 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:412651 browser->set_override_bounds(new_window_bounds);
[email protected]2e716622009-03-09 21:11:012652 browser->set_maximized_state(
2653 maximize ? MAXIMIZED_STATE_MAXIMIZED : MAXIMIZED_STATE_UNMAXIMIZED);
[email protected]9800de5e2011-03-11 18:19:492654 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:052655 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:272656 // Make sure the loading state is updated correctly, otherwise the throbber
2657 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492658 browser->LoadingStateChanged(detached_contents->tab_contents());
[email protected]3d1104f2009-03-26 15:30:282659 return browser;
[email protected]36b6dcb2008-11-12 01:19:572660}
2661
2662int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:402663 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
2664 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:572665}
2666
[email protected]3c9e1872010-11-18 16:17:492667TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]36b6dcb2008-11-12 01:19:572668 const GURL& url, const GURL& referrer, Profile* profile,
2669 PageTransition::Type transition, bool defer_load,
2670 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:492671 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:402672 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:492673 GetSelectedTabContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:572674 if (!defer_load) {
2675 // Load the initial URL before adding the new tab contents to the tab strip
2676 // so that the tab contents has navigation state.
[email protected]ce3fa3c2009-04-20 19:55:572677 contents->controller().LoadURL(url, referrer, transition);
[email protected]36b6dcb2008-11-12 01:19:572678 }
2679
2680 return contents;
2681}
2682
2683bool Browser::CanDuplicateContentsAt(int index) {
[email protected]ce3fa3c2009-04-20 19:55:572684 NavigationController& nc = GetTabContentsAt(index)->controller();
2685 return nc.tab_contents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:572686}
2687
2688void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:492689 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:332690 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:122691 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:562692 TabContents* new_contents = contents_dupe->tab_contents();
2693
2694 bool pinned = false;
2695 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2696 // If this is a tabbed browser, just create a duplicate tab inside the same
2697 // window next to the tab being duplicated.
2698 int index = tab_handler_->GetTabStripModel()->
2699 GetIndexOfTabContents(contents);
2700 pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:412701 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:562702 TabStripModel::ADD_INHERIT_GROUP |
2703 (pinned ? TabStripModel::ADD_PINNED : 0);
2704 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
2705 contents_dupe,
2706 add_types);
2707 } else {
2708 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:142709 if (is_app()) {
2710 CHECK(!is_type_popup());
2711 CHECK(!is_type_panel());
2712 browser = Browser::CreateForApp(TYPE_POPUP, app_name_, gfx::Size(),
2713 profile_);
2714 } else if (is_type_popup()) {
[email protected]47b309f2010-12-28 17:35:562715 browser = Browser::CreateForType(TYPE_POPUP, profile_);
2716 }
2717
2718 // Preserve the size of the original window. The new window has already
2719 // been given an offset by the OS, so we shouldn't copy the old bounds.
2720 BrowserWindow* new_window = browser->window();
2721 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
2722 window()->GetRestoredBounds().size()));
2723
[email protected]4e595682011-02-09 17:07:022724 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]47b309f2010-12-28 17:35:562725 // TabContents is invisible and won't size it.
2726 browser->window()->Show();
2727
2728 // The page transition below is only for the purpose of inserting the tab.
2729 browser->AddTab(contents_dupe, PageTransition::LINK);
2730 }
2731
[email protected]92371eb2011-04-28 11:50:152732 SessionService* session_service =
2733 SessionServiceFactory::GetForProfileIfExisting(profile_);
2734 if (session_service)
2735 session_service->TabRestored(&new_contents->controller(), pinned);
[email protected]36b6dcb2008-11-12 01:19:572736}
2737
[email protected]36b6dcb2008-11-12 01:19:572738void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:472739#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:572740 // This is scheduled to run after we return to the message loop because
2741 // otherwise the frame will think the drag session is still active and ignore
2742 // the request.
[email protected]d6a3c772009-01-27 19:41:202743 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:372744 MessageLoop::current()->PostTask(
2745 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]d6a3c772009-01-27 19:41:202746#endif
initial.commit09911bf2008-07-26 23:55:292747}
2748
[email protected]3c9e1872010-11-18 16:17:492749void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:582750 // We don't create historical tabs for incognito windows or windows without
2751 // profiles.
[email protected]92371eb2011-04-28 11:50:152752 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:582753 return;
[email protected]92371eb2011-04-28 11:50:152754
[email protected]0d4ef7f2011-05-12 22:38:572755 // We don't create historical tabs for print preview tabs.
2756 if (contents->tab_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
2757 return;
2758
[email protected]92371eb2011-04-28 11:50:152759 TabRestoreService* service =
2760 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:582761
[email protected]fb5ff422010-05-03 20:46:102762 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:152763 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2764 service->CreateHistoricalTab(&contents->controller(),
[email protected]fb7da4132011-03-15 15:51:002765 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:582766 }
2767}
2768
[email protected]3c9e1872010-11-18 16:17:492769bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
2770 return Browser::RunUnloadEventsHelper(contents->tab_contents());
[email protected]505323e22009-01-24 02:47:582771}
2772
[email protected]8e48e982009-12-25 11:22:462773bool Browser::CanReloadContents(TabContents* source) const {
[email protected]b35b26b32011-05-05 20:35:142774 return !is_devtools();
[email protected]8e48e982009-12-25 11:22:462775}
2776
[email protected]2db5a2042011-04-26 17:13:472777bool Browser::CanCloseContents(std::vector<int>* indices) {
2778 DCHECK(!indices->empty());
2779 TabCloseableStateWatcher* watcher =
2780 g_browser_process->tab_closeable_state_watcher();
2781 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
2782 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:042783 return false;
[email protected]2db5a2042011-04-26 17:13:472784 // Now, handle cases where at least one tab can be closed.
2785 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:102786 // in-progress downloads.
2787 // Note that the next call when it returns false will ask the user for
2788 // confirmation before closing the browser if the user decides so.
[email protected]2db5a2042011-04-26 17:13:472789 if (tab_handler_->GetTabStripModel()->count() ==
2790 static_cast<int>(indices->size()) &&
2791 !CanCloseWithInProgressDownloads()) {
2792 indices->clear();
2793 can_close_all = false;
2794 }
2795 return can_close_all;
[email protected]940ccb22009-04-30 17:11:102796}
[email protected]d6a3c772009-01-27 19:41:202797
[email protected]a206b442009-10-08 23:20:202798bool Browser::CanBookmarkAllTabs() const {
2799 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:582800 return (model && model->IsLoaded()) &&
2801 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:042802 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:202803}
2804
[email protected]b3ac5c82009-10-08 20:56:542805void Browser::BookmarkAllTabs() {
[email protected]ec12ffe2009-10-16 22:28:442806 BookmarkModel* model = profile()->GetBookmarkModel();
2807 DCHECK(model && model->IsLoaded());
2808
2809 BookmarkEditor::EditDetails details;
2810 details.type = BookmarkEditor::EditDetails::NEW_FOLDER;
2811 bookmark_utils::GetURLsForOpenTabs(this, &(details.urls));
2812 DCHECK(!details.urls.empty());
[email protected]b3ac5c82009-10-08 20:56:542813
[email protected]b3ac5c82009-10-08 20:56:542814 BookmarkEditor::Show(window()->GetNativeHandle(), profile_,
[email protected]ec12ffe2009-10-16 22:28:442815 model->GetParentForNewNodes(), details,
[email protected]97a056462010-04-28 16:46:352816 BookmarkEditor::SHOW_TREE);
[email protected]b3ac5c82009-10-08 20:56:542817}
2818
[email protected]0b4d3382010-07-14 16:13:042819bool Browser::CanCloseTab() const {
2820 TabCloseableStateWatcher* watcher =
2821 g_browser_process->tab_closeable_state_watcher();
2822 return !watcher || watcher->CanCloseTab(this);
2823}
2824
[email protected]b9c505b2010-04-30 15:05:102825void Browser::ToggleUseVerticalTabs() {
2826 use_vertical_tabs_.SetValue(!UseVerticalTabs());
[email protected]b3344872010-05-03 15:52:292827 UseVerticalTabsChanged();
[email protected]b9c505b2010-04-30 15:05:102828}
2829
[email protected]ac86c982011-05-11 13:26:052830void Browser::ToggleUseCompactNavigationBar() {
2831 use_compact_navigation_bar_.SetValue(!UseCompactNavigationBar());
2832 UseCompactNavigationBarChanged();
2833}
2834
[email protected]b283a7532010-08-12 21:24:592835bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:442836 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
2837 // for those windows, we already have a big icon in the top-left outside any
2838 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:332839 return true;
[email protected]b283a7532010-08-12 21:24:592840}
2841
[email protected]2d46c842008-11-14 19:24:312842///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572843// Browser, TabStripModelObserver implementation:
2844
[email protected]3c9e1872010-11-18 16:17:492845void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572846 int index,
2847 bool foreground) {
[email protected]9219d262011-02-15 21:05:122848 SetAsDelegate(contents, this);
[email protected]ce3fa3c2009-04-20 19:55:572849 contents->controller().SetWindowID(session_id());
[email protected]36b6dcb2008-11-12 01:19:572850
[email protected]15b2c6a2011-05-16 23:54:402851 // Extension code in the renderer holds the ID of the window that hosts it.
2852 // Notify it that the window ID changed.
2853 contents->render_view_host()->Send(new ExtensionMsg_UpdateBrowserWindowId(
2854 contents->render_view_host()->routing_id(),
2855 contents->controller().window_id().id()));
[email protected]e524ff92011-03-30 13:26:582856
[email protected]c37e3b62010-01-22 00:15:172857 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:572858
[email protected]159f7762008-12-19 14:58:272859 // Make sure the loading state is updated correctly, otherwise the throbber
2860 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492861 LoadingStateChanged(contents->tab_contents());
[email protected]159f7762008-12-19 14:58:272862
[email protected]36b6dcb2008-11-12 01:19:572863 // If the tab crashes in the beforeunload or unload handler, it won't be
2864 // able to ack. But we know we can close it.
[email protected]0cb94102009-05-22 19:51:212865 registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:052866 Source<TabContents>(contents->tab_contents()));
[email protected]93f230e02011-06-01 14:40:002867
2868 registrar_.Add(this, NotificationType::INTERSTITIAL_ATTACHED,
2869 Source<TabContents>(contents->tab_contents()));
[email protected]36b6dcb2008-11-12 01:19:572870}
2871
[email protected]f2cc7382010-10-15 18:03:052872void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:492873 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:052874 int index) {
[email protected]bfd04a62009-02-01 18:16:562875 NotificationService::current()->Notify(
2876 NotificationType::TAB_CLOSING,
[email protected]ce3fa3c2009-04-20 19:55:572877 Source<NavigationController>(&contents->controller()),
[email protected]bfd04a62009-02-01 18:16:562878 NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:572879
2880 // Sever the TabContents' connection back to us.
[email protected]9219d262011-02-15 21:05:122881 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:572882}
2883
[email protected]3c9e1872010-11-18 16:17:492884void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:172885 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:572886}
2887
[email protected]2ab3fa92011-02-27 21:46:512888void Browser::TabDeselected(TabContentsWrapper* contents) {
[email protected]6b723f82010-10-05 20:14:272889 if (instant())
2890 instant()->DestroyPreviewContents();
[email protected]03bb953d2010-09-14 21:38:302891
[email protected]85ff2c42009-05-29 21:22:032892 // Save what the user's currently typing, so it can be restored when we
2893 // switch back to this tab.
[email protected]3c9e1872010-11-18 16:17:492894 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]85ff2c42009-05-29 21:22:032895}
2896
[email protected]3aca95d42011-05-24 22:06:542897void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
2898 TabContentsWrapper* new_contents,
2899 int index,
2900 bool user_gesture) {
[email protected]02cd2bf2011-03-02 21:45:562901 if (old_contents == new_contents)
2902 return;
[email protected]36b6dcb2008-11-12 01:19:572903
[email protected]a8f024392011-01-13 21:50:162904 // On some platforms we want to automatically reload tabs that are
2905 // killed when the user selects them.
2906 if (user_gesture && new_contents->tab_contents()->crashed_status() ==
2907 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
2908 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:562909 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]a8f024392011-01-13 21:50:162910 Reload(CURRENT_TAB);
[email protected]f8a35772011-02-02 23:17:562911 return;
2912 }
[email protected]a8f024392011-01-13 21:50:162913 }
2914
[email protected]36b6dcb2008-11-12 01:19:572915 // If we have any update pending, do it now.
2916 if (!chrome_updater_factory_.empty() && old_contents)
2917 ProcessPendingUIUpdates();
2918
[email protected]36b6dcb2008-11-12 01:19:572919 // Propagate the profile to the location bar.
2920 UpdateToolbar(true);
2921
[email protected]943d8122010-06-11 02:13:452922 // Update reload/stop state.
[email protected]3c9e1872010-11-18 16:17:492923 UpdateReloadStopState(new_contents->tab_contents()->is_loading(), true);
[email protected]36b6dcb2008-11-12 01:19:572924
[email protected]84214982008-12-10 18:49:102925 // Update commands to reflect current state.
2926 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:572927
2928 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:102929 StatusBubble* status_bubble = GetStatusBubble();
2930 if (status_bubble) {
2931 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:572932
[email protected]be3877f2009-01-14 15:51:102933 // Show the loading state (if any).
[email protected]0dd3a0ab2011-02-18 08:17:442934 status_bubble->SetStatus(GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:102935 }
[email protected]36b6dcb2008-11-12 01:19:572936
[email protected]24db8a072009-10-29 20:35:372937 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:242938 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:172939 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:582940 }
2941
[email protected]36b6dcb2008-11-12 01:19:572942 // Update sessions. Don't force creation of sessions. If sessions doesn't
2943 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:152944 SessionService* session_service =
2945 SessionServiceFactory::GetForProfileIfExisting(profile_);
2946 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
2947 session_service->SetSelectedTabInWindow(
2948 session_id(), tab_handler_->GetTabStripModel()->active_index());
[email protected]36b6dcb2008-11-12 01:19:572949 }
2950}
2951
[email protected]3c9e1872010-11-18 16:17:492952void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572953 int from_index,
[email protected]1a242c32010-02-02 21:20:542954 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:572955 DCHECK(from_index >= 0 && to_index >= 0);
2956 // Notify the history service.
2957 SyncHistoryWithTabs(std::min(from_index, to_index));
2958}
2959
[email protected]da25dd52011-01-11 19:06:302960void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
2961 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:492962 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:432963 int index) {
[email protected]c37e3b62010-01-22 00:15:172964 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
2965 TabInsertedAt(new_contents, index,
[email protected]1ea49d52011-04-12 17:44:442966 (index == tab_handler_->GetTabStripModel()->active_index()));
[email protected]c37e3b62010-01-22 00:15:172967
2968 int entry_count = new_contents->controller().entry_count();
2969 if (entry_count > 0) {
2970 // Send out notification so that observers are updated appropriately.
2971 new_contents->controller().NotifyEntryChanged(
2972 new_contents->controller().GetEntryAtIndex(entry_count - 1),
2973 entry_count - 1);
2974 }
[email protected]47e020a2010-10-15 14:43:372975
[email protected]92371eb2011-04-28 11:50:152976 SessionService* session_service =
2977 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:372978 if (session_service) {
2979 // The new_contents may end up with a different navigation stack. Force
2980 // the session service to update itself.
2981 session_service->TabRestored(
2982 &new_contents->controller(),
2983 tab_handler_->GetTabStripModel()->IsTabPinned(index));
2984 }
[email protected]2914600d2011-01-31 23:25:142985
2986 DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
2987 if (devtools_manager) // NULL in unit tests.
2988 devtools_manager->TabReplaced(old_contents, new_contents);
[email protected]c37e3b62010-01-22 00:15:172989}
2990
[email protected]3c9e1872010-11-18 16:17:492991void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:152992 SessionService* session_service =
2993 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:092994 if (session_service) {
2995 session_service->SetPinnedState(
2996 session_id(),
2997 GetTabContentsAt(index)->controller().session_id(),
[email protected]ecc523f62010-09-28 22:45:402998 tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:092999 }
3000}
3001
[email protected]36b6dcb2008-11-12 01:19:573002void Browser::TabStripEmpty() {
3003 // Close the frame after we return to the message loop (not immediately,
3004 // otherwise it will destroy this object before the stack has a chance to
3005 // cleanly unwind.)
3006 // Note: This will be called several times if TabStripEmpty is called several
3007 // times. This is because it does not close the window if tabs are
3008 // still present.
3009 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3010 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373011 MessageLoop::current()->PostTask(
3012 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]36b6dcb2008-11-12 01:19:573013}
3014
3015///////////////////////////////////////////////////////////////////////////////
3016// Browser, TabContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293017
3018void Browser::OpenURLFromTab(TabContents* source,
[email protected]1f7d7e92009-06-02 20:55:043019 const GURL& url,
3020 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:293021 WindowOpenDisposition disposition,
[email protected]e38f40152008-09-12 23:08:303022 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:333023 browser::NavigateParams params(this, url, transition);
[email protected]3c9e1872010-11-18 16:17:493024 params.source_contents =
3025 tabstrip_model()->GetTabContentsAt(
3026 tabstrip_model()->GetWrapperIndex(source));
[email protected]616381f02010-11-02 15:15:333027 params.referrer = referrer;
3028 params.disposition = disposition;
3029 params.tabstrip_add_types = TabStripModel::ADD_NONE;
[email protected]7d329992011-04-15 18:20:023030 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:353031 params.user_gesture = true;
[email protected]616381f02010-11-02 15:15:333032 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293033}
3034
3035void Browser::NavigationStateChanged(const TabContents* source,
3036 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293037 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403038 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293039 ScheduleUIUpdate(source, changed_flags);
3040
[email protected]84214982008-12-10 18:49:103041 // We don't schedule updates to commands since they will only change once per
3042 // navigation, so we don't have to worry about flickering.
[email protected]e83f1682008-09-07 23:57:403043 if (changed_flags & TabContents::INVALIDATE_URL)
[email protected]84214982008-12-10 18:49:103044 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293045}
3046
initial.commit09911bf2008-07-26 23:55:293047void Browser::AddNewContents(TabContents* source,
3048 TabContents* new_contents,
3049 WindowOpenDisposition disposition,
3050 const gfx::Rect& initial_pos,
3051 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373052 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333053 DCHECK(disposition != SAVE_TO_DISK);
3054 // Can't create a new contents for the current tab - invalid case.
3055 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293056
[email protected]e7cfdbd2011-04-22 14:41:373057 TabContentsWrapper* source_wrapper = NULL;
3058 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453059 TabContentsWrapper* new_wrapper =
3060 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
3061 if (!new_wrapper)
3062 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]e7cfdbd2011-04-22 14:41:373063 if (source) {
3064 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3065 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3066 }
3067
3068 if (source_wrapper) {
3069 // Handle blocking of all contents.
3070 if (source_blocked_content->all_contents_blocked()) {
3071 source_blocked_content->AddTabContents(new_wrapper,
3072 disposition,
3073 initial_pos,
3074 user_gesture);
3075 return;
3076 }
3077
3078 // Handle blocking of popups.
3079 if ((disposition == NEW_POPUP) && !user_gesture &&
3080 !CommandLine::ForCurrentProcess()->HasSwitch(
3081 switches::kDisablePopupBlocking)) {
3082 // Unrequested popups from normal pages are constrained unless they're in
3083 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363084 GetConstrainingContentsWrapper(source_wrapper)->
3085 blocked_content_tab_helper()->
3086 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373087 return;
3088 }
3089
[email protected]216813952011-05-19 22:21:263090 RenderViewHost* view = new_contents->render_view_host();
3091 view->Send(new ViewMsg_DisassociateFromPopupCount(view->routing_id()));
[email protected]e7cfdbd2011-04-22 14:41:373092 }
3093
[email protected]e7cfdbd2011-04-22 14:41:373094 browser::NavigateParams params(this, new_wrapper);
[email protected]3c9e1872010-11-18 16:17:493095 params.source_contents =
[email protected]e7cfdbd2011-04-22 14:41:373096 source ? tabstrip_model()->GetTabContentsAt(
3097 tabstrip_model()->GetWrapperIndex(source))
3098 : NULL;
[email protected]3c9e1872010-11-18 16:17:493099 params.disposition = disposition;
3100 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353101 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3102 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493103 browser::Navigate(&params);
[email protected]e7cfdbd2011-04-22 14:41:373104
3105 if (source) {
3106 NotificationService::current()->Notify(
3107 NotificationType::TAB_ADDED,
3108 Source<TabContentsDelegate>(source->delegate()),
3109 Details<TabContents>(source));
3110 }
initial.commit09911bf2008-07-26 23:55:293111}
3112
initial.commit09911bf2008-07-26 23:55:293113void Browser::ActivateContents(TabContents* contents) {
[email protected]eaca0ad12011-04-18 15:53:413114 tab_handler_->GetTabStripModel()->ActivateTabAt(
[email protected]3c9e1872010-11-18 16:17:493115 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393116 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293117}
3118
[email protected]ea42e7782010-08-23 23:58:123119void Browser::DeactivateContents(TabContents* contents) {
3120 window_->Deactivate();
3121}
3122
initial.commit09911bf2008-07-26 23:55:293123void Browser::LoadingStateChanged(TabContents* source) {
[email protected]ecc523f62010-09-28 22:45:403124 window_->UpdateLoadingAnimations(
3125 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393126 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293127
[email protected]3c9e1872010-11-18 16:17:493128 TabContents* selected_contents = GetSelectedTabContents();
3129 if (source == selected_contents) {
[email protected]943d8122010-06-11 02:13:453130 UpdateReloadStopState(source->is_loading(), false);
[email protected]43d259d2010-09-03 21:37:463131 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443132 GetStatusBubble()->SetStatus(
3133 GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463134 }
[email protected]eabfdae92009-12-11 06:13:513135
3136 if (!source->is_loading() &&
3137 pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333138 // Schedule a shortcut update when web application info is available if
3139 // last committed entry is not NULL. Last committed entry could be NULL
3140 // when an interstitial page is injected (e.g. bad https certificate,
3141 // malware site etc). When this happens, we abort the shortcut update.
[email protected]eabfdae92009-12-11 06:13:513142 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3143 if (entry) {
[email protected]553602e12011-04-05 17:01:183144 TabContentsWrapper::GetCurrentWrapperForContents(source)->
3145 extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]eabfdae92009-12-11 06:13:513146 } else {
3147 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513148 }
3149 }
initial.commit09911bf2008-07-26 23:55:293150 }
3151}
3152
3153void Browser::CloseContents(TabContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473154 if (is_attempting_to_close_browser_) {
3155 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063156 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473157 // will go down the slow shutdown path instead of the fast path of killing
3158 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213159 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473160 return;
3161 }
3162
[email protected]3c9e1872010-11-18 16:17:493163 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293164 if (index == TabStripModel::kNoTab) {
3165 NOTREACHED() << "CloseContents called for tab not in our strip";
3166 return;
3167 }
[email protected]ecc523f62010-09-28 22:45:403168 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:393169 index,
3170 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293171}
3172
[email protected]15e8abe2008-08-20 22:40:403173void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143174 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293175 NOTREACHED() << "moving invalid browser type";
3176 return;
3177 }
[email protected]e561e202010-03-24 17:57:123178 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293179}
3180
[email protected]b6c874582009-05-08 19:38:313181void Browser::DetachContents(TabContents* source) {
[email protected]3c9e1872010-11-18 16:17:493182 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313183 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:403184 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313185}
3186
[email protected]b35b26b32011-05-05 20:35:143187bool Browser::IsPopupOrPanel(const TabContents* source) const {
initial.commit09911bf2008-07-26 23:55:293188 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143189 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293190}
3191
[email protected]b8595e92009-11-14 01:18:003192void Browser::ContentsMouseEvent(
3193 TabContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:103194 if (!GetStatusBubble())
3195 return;
3196
[email protected]36b6dcb2008-11-12 01:19:573197 if (source == GetSelectedTabContents()) {
[email protected]b8595e92009-11-14 01:18:003198 GetStatusBubble()->MouseMoved(location, !motion);
3199 if (!motion)
[email protected]43d259d2010-09-03 21:37:463200 GetStatusBubble()->SetURL(GURL(), string16());
[email protected]36b6dcb2008-11-12 01:19:573201 }
3202}
3203
3204void Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
[email protected]be3877f2009-01-14 15:51:103205 if (!GetStatusBubble())
3206 return;
3207
[email protected]36b6dcb2008-11-12 01:19:573208 if (source == GetSelectedTabContents()) {
3209 PrefService* prefs = profile_->GetPrefs();
[email protected]ddd231e2010-06-29 20:35:193210 GetStatusBubble()->SetURL(
[email protected]43d259d2010-09-03 21:37:463211 url, UTF8ToUTF16(prefs->GetString(prefs::kAcceptLanguages)));
[email protected]36b6dcb2008-11-12 01:19:573212 }
3213}
3214
[email protected]3a6a3b62009-05-27 21:36:203215void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:233216 if (GetStatusBubble())
3217 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:203218}
3219
[email protected]aa02fff12010-07-21 19:55:253220bool Browser::UseVerticalTabs() const {
3221 return use_vertical_tabs_.GetValue();
3222}
3223
[email protected]ac86c982011-05-11 13:26:053224bool Browser::UseCompactNavigationBar() const {
3225 return use_compact_navigation_bar_.GetValue();
3226}
3227
[email protected]36b6dcb2008-11-12 01:19:573228void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253229 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573230}
3231
[email protected]fa1cf0b82010-01-15 21:49:443232void Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
[email protected]3c9e1872010-11-18 16:17:493233 int index = tabstrip_model()->GetWrapperIndex(contents);
[email protected]fa1cf0b82010-01-15 21:49:443234 if (index == TabStripModel::kNoTab) {
3235 NOTREACHED();
3236 return;
3237 }
3238 tabstrip_model()->SetTabBlocked(index, blocked);
3239}
3240
[email protected]7e383692009-06-12 19:14:543241void Browser::TabContentsFocused(TabContents* tab_content) {
3242 window_->TabContentsFocused(tab_content);
3243}
3244
[email protected]130efb02009-09-18 18:54:353245bool Browser::TakeFocus(bool reverse) {
3246 NotificationService::current()->Notify(
3247 NotificationType::FOCUS_RETURNED_TO_BROWSER,
3248 Source<Browser>(this),
3249 NotificationService::NoDetails());
3250 return false;
3251}
3252
[email protected]36b6dcb2008-11-12 01:19:573253bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143254 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573255}
3256
3257void Browser::ConvertContentsToApplication(TabContents* contents) {
[email protected]ce3fa3c2009-04-20 19:55:573258 const GURL& url = contents->controller().GetActiveEntry()->url();
[email protected]57ecc4b2010-08-11 03:02:513259 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573260
[email protected]b6c874582009-05-08 19:38:313261 DetachContents(contents);
[email protected]94ce7252010-12-20 21:46:333262 Browser* app_browser = Browser::CreateForApp(
[email protected]b35b26b32011-05-05 20:35:143263 TYPE_POPUP, app_name, gfx::Size(), profile_);
[email protected]ae2f2a772011-05-04 16:30:273264 TabContentsWrapper* wrapper =
3265 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3266 if (!wrapper)
3267 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323268 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3269
3270 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
3271 contents->render_view_host()->SyncRendererPrefs();
3272 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573273}
3274
[email protected]36b6dcb2008-11-12 01:19:573275bool Browser::ShouldDisplayURLField() {
3276 return !IsApplication();
3277}
3278
3279void Browser::BeforeUnloadFired(TabContents* tab,
3280 bool proceed,
3281 bool* proceed_to_fire_unload) {
3282 if (!is_attempting_to_close_browser_) {
3283 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393284 if (!proceed)
3285 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573286 return;
3287 }
3288
3289 if (!proceed) {
3290 CancelWindowClose();
3291 *proceed_to_fire_unload = false;
[email protected]0cce15f2010-05-21 16:58:393292 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573293 return;
3294 }
3295
[email protected]06b42f032008-12-03 18:43:053296 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313297 // Now that beforeunload has fired, put the tab on the queue to fire
3298 // unload.
[email protected]06b42f032008-12-03 18:43:053299 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573300 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063301 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573302 // fire all the beforeunload events before attempting to fire the unload
3303 // events should the user cancel closing the browser.
3304 *proceed_to_fire_unload = false;
3305 return;
3306 }
3307
3308 *proceed_to_fire_unload = true;
3309}
3310
[email protected]a26dc362010-04-23 01:48:583311void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133312 // Two differences between this and FocusLocationBar():
3313 // (1) This doesn't get recorded in user metrics, since it's called
3314 // internally.
3315 // (2) This checks whether the location bar can be focused, and if not, clears
3316 // the focus. FocusLocationBar() is only reached when the location bar is
3317 // focusable, but this may be reached at other times, e.g. while in
3318 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583319 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573320}
3321
[email protected]7d5925a2009-03-03 02:59:123322void Browser::RenderWidgetShowing() {
3323 window_->DisableInactiveFrame();
3324}
[email protected]a239c3f2009-02-17 22:13:193325
[email protected]0a2aeb82009-05-15 21:52:483326int Browser::GetExtraRenderViewHeight() const {
3327 return window_->GetExtraRenderViewHeight();
3328}
3329
[email protected]bb678332009-07-21 00:15:503330void Browser::ShowPageInfo(Profile* profile,
[email protected]4d677202009-07-19 07:37:123331 const GURL& url,
3332 const NavigationEntry::SSLStatus& ssl,
3333 bool show_history) {
[email protected]bb678332009-07-21 00:15:503334 window()->ShowPageInfo(profile, url, ssl, show_history);
[email protected]4d677202009-07-19 07:37:123335}
3336
[email protected]1788e772010-12-15 16:40:503337void Browser::ViewSourceForTab(TabContents* source, const GURL& page_url) {
3338 DCHECK(source);
3339 int index = tabstrip_model()->GetWrapperIndex(source);
[email protected]77d8d622010-12-15 10:30:123340 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3341 ViewSource(wrapper);
3342}
3343
[email protected]932b7a12011-03-09 12:50:273344void Browser::ViewSourceForFrame(TabContents* source,
3345 const GURL& frame_url,
3346 const std::string& frame_content_state) {
3347 DCHECK(source);
3348 int index = tabstrip_model()->GetWrapperIndex(source);
3349 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3350 ViewSource(wrapper, frame_url, frame_content_state);
3351}
3352
[email protected]867125a02009-12-10 06:01:483353bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3354 bool* is_keyboard_shortcut) {
3355 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3356}
[email protected]97df4b332009-10-02 01:25:413357
[email protected]867125a02009-12-10 06:01:483358void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3359 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413360}
3361
[email protected]14f3408a2009-08-31 20:53:533362void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
3363 window()->ShowRepostFormWarningDialog(tab_contents);
3364}
3365
[email protected]579e3192011-03-11 22:37:453366void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
[email protected]445177652011-03-09 02:04:053367 ShowOptionsTab(
3368 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
3369 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
[email protected]63543142010-02-09 23:22:203370}
3371
[email protected]a503c97c2010-07-16 13:05:483372void Browser::ShowCollectedCookiesDialog(TabContents *tab_contents) {
3373 window()->ShowCollectedCookiesDialog(tab_contents);
3374}
3375
[email protected]ec0b6c42010-08-26 03:16:583376bool Browser::ShouldAddNavigationToHistory(
3377 const history::HistoryAddPageArgs& add_page_args,
3378 NavigationType::Type navigation_type) {
[email protected]2e29d922009-10-22 22:13:353379 // Don't update history if running as app.
3380 return !IsApplication();
3381}
3382
[email protected]9e823662010-10-13 23:36:003383void Browser::ContentRestrictionsChanged(TabContents* source) {
3384 UpdateCommandsForContentRestrictionState();
3385}
3386
[email protected]55452902011-06-01 21:57:473387void Browser::RendererUnresponsive(TabContents* source) {
3388 browser::ShowHungRendererDialog(source);
3389}
3390
3391void Browser::RendererResponsive(TabContents* source) {
3392 browser::HideHungRendererDialog(source);
3393}
3394
3395void Browser::WorkerCrashed(TabContents* source) {
3396 TabContentsWrapper* wrapper =
3397 TabContentsWrapper::GetCurrentWrapperForContents(source);
3398 wrapper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3399 source, NULL, l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
3400 true));
[email protected]0dd3a0ab2011-02-18 08:17:443401}
3402
[email protected]93f230e02011-06-01 14:40:003403TabContentsDelegate::MainFrameCommitDetails*
3404 Browser::CreateMainFrameCommitDetails(TabContents* tab) {
3405 if (tab != GetSelectedTabContents())
3406 return NULL;
3407
3408 BrowserMainFrameCommitDetails* details = new BrowserMainFrameCommitDetails;
3409 details->bookmark_bar_visible = GetSelectedTabContentsWrapper()->
3410 bookmark_tab_helper()->ShouldShowBookmarkBar();
3411 return details; // Caller takes ownership.
3412}
3413
3414void Browser::DidNavigateMainFramePostCommit(
3415 TabContents* tab,
3416 const MainFrameCommitDetails& details) {
3417 bool visible = static_cast<const BrowserMainFrameCommitDetails&>(details).
3418 bookmark_bar_visible;
3419 if (tab == GetSelectedTabContents() && visible !=
3420 GetSelectedTabContentsWrapper()->bookmark_tab_helper()->
3421 ShouldShowBookmarkBar()) {
3422 window()->ShelfVisibilityChanged();
3423 }
3424}
3425
[email protected]3ab9cb82011-06-03 18:02:073426content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
3427 return GetJavaScriptDialogCreatorInstance();
3428}
3429
[email protected]36b6dcb2008-11-12 01:19:573430///////////////////////////////////////////////////////////////////////////////
[email protected]a0366a52011-02-04 20:04:213431// Browser, TabContentsWrapperDelegate implementation:
3432
[email protected]553602e12011-04-05 17:01:183433void Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
3434 int32 page_id) {
3435 if (GetSelectedTabContentsWrapper() != source)
3436 return;
3437
3438 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3439 if (!entry || (entry->page_id() != page_id))
3440 return;
3441
3442 switch (pending_web_app_action_) {
3443 case CREATE_SHORTCUT: {
3444 window()->ShowCreateWebAppShortcutsDialog(source);
3445 break;
3446 }
3447 case UPDATE_SHORTCUT: {
3448 web_app::UpdateShortcutForTabContents(source);
3449 break;
3450 }
3451 default:
3452 NOTREACHED();
3453 break;
3454 }
3455
3456 pending_web_app_action_ = NONE;
3457}
3458
3459void Browser::OnInstallApplication(TabContentsWrapper* source,
3460 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:363461 ExtensionService* extension_service = profile()->GetExtensionService();
3462 if (!extension_service)
[email protected]553602e12011-04-05 17:01:183463 return;
3464
[email protected]14908b72011-04-20 06:54:363465 scoped_refptr<CrxInstaller> installer(extension_service->MakeCrxInstaller(
3466 extension_service->show_extensions_prompts() ?
3467 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:183468 installer->InstallWebApp(web_app);
3469}
3470
[email protected]c90c6ca2011-02-16 20:11:383471///////////////////////////////////////////////////////////////////////////////
3472// Browser, SearchEngineTabHelperDelegate implementation:
3473
[email protected]9219d262011-02-15 21:05:123474void Browser::ConfirmSetDefaultSearchProvider(
[email protected]b5a1d11c2011-02-17 03:09:423475 TabContents* tab_contents,
[email protected]9219d262011-02-15 21:05:123476 TemplateURL* template_url,
3477 TemplateURLModel* template_url_model) {
3478 window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
3479 template_url_model);
3480}
3481
3482void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
3483 Profile* profile) {
3484 window()->ConfirmAddSearchProvider(template_url, profile);
3485}
3486
[email protected]a0366a52011-02-04 20:04:213487///////////////////////////////////////////////////////////////////////////////
[email protected]e7cfdbd2011-04-22 14:41:373488// Browser, BlockedContentTabHelperDelegate implementation:
3489
[email protected]393c0ed02011-04-22 14:55:363490TabContentsWrapper* Browser::GetConstrainingContentsWrapper(
[email protected]e7cfdbd2011-04-22 14:41:373491 TabContentsWrapper* source) {
3492 return source;
3493}
3494
3495///////////////////////////////////////////////////////////////////////////////
[email protected]35699d572011-05-11 19:46:143496// Browser, BookmarkTabHelperDelegate implementation:
[email protected]52cc59b2011-05-06 14:42:383497
3498void Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
3499 if (source == GetSelectedTabContentsWrapper())
3500 window_->SetStarredState(starred);
3501}
3502
3503///////////////////////////////////////////////////////////////////////////////
[email protected]ddb85052011-05-18 14:40:273504// Browser, DownloadTabHelperDelegate implementation:
3505
3506bool Browser::CanDownload(int request_id) {
3507 return true;
3508}
3509
3510void Browser::OnStartDownload(DownloadItem* download, TabContentsWrapper* tab) {
3511 if (!window())
3512 return;
3513
3514#if defined(OS_CHROMEOS)
3515 // Don't show content browser for extension/theme downloads from gallery.
3516 if (download->is_extension_install()) {
3517 ExtensionService* service = profile_->GetExtensionService();
[email protected]4cd82f72011-05-23 19:15:013518 if (service && service->IsDownloadFromGallery(download->GetURL(),
[email protected]ddb85052011-05-18 14:40:273519 download->referrer_url())) {
3520 return;
3521 }
3522 }
3523 // Open the Active Downloads ui for chromeos.
3524 ActiveDownloadsUI::OpenPopup(profile_);
3525#else
3526 // GetDownloadShelf creates the download shelf if it was not yet created.
3527 window()->GetDownloadShelf()->AddDownload(new DownloadItemModel(download));
3528
3529 // Don't show the animation for "Save file" downloads.
3530 if (download->total_bytes() <= 0)
3531 return;
3532
3533 // For non-theme extensions, we don't show the download animation.
3534 if (download->is_extension_install() &&
[email protected]4cd82f72011-05-23 19:15:013535 !ExtensionService::IsDownloadFromMiniGallery(download->GetURL()))
[email protected]ddb85052011-05-18 14:40:273536 return;
3537
3538 TabContents* current_tab = GetSelectedTabContents();
3539 // We make this check for the case of minimized windows, unit tests, etc.
3540 if (platform_util::IsVisible(current_tab->GetNativeView()) &&
3541 ui::Animation::ShouldRenderRichAnimation()) {
3542 DownloadStartedAnimation::Show(current_tab);
3543 }
3544#endif
3545
3546 // If the download occurs in a new tab, close it.
3547 if (tab->tab_contents()->controller().IsInitialNavigation() &&
3548 GetConstrainingContentsWrapper(tab) == tab && tab_count() > 1) {
3549 CloseContents(tab->tab_contents());
3550 }
3551}
3552
3553///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573554// Browser, SelectFileDialog::Listener implementation:
3555
[email protected]561abe62009-04-06 18:08:343556void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:513557 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:123558 GURL file_url = net::FilePathToFileURL(path);
[email protected]36b6dcb2008-11-12 01:19:573559 if (!file_url.is_empty())
3560 OpenURL(file_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
3561}
3562
3563///////////////////////////////////////////////////////////////////////////////
3564// Browser, NotificationObserver implementation:
3565
initial.commit09911bf2008-07-26 23:55:293566void Browser::Observe(NotificationType type,
3567 const NotificationSource& source,
3568 const NotificationDetails& details) {
[email protected]bfd04a62009-02-01 18:16:563569 switch (type.value) {
[email protected]57c6a652009-05-04 07:58:343570 case NotificationType::TAB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:403571 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:213572 // Pass in false so that we delay processing. We need to delay the
3573 // processing as it may close the tab, which is currently on the call
3574 // stack above us.
3575 ClearUnloadState(Source<TabContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:403576 }
3577 break;
3578
[email protected]b4a19ea2009-03-17 10:08:243579 case NotificationType::SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:403580 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:323581 // bar to reflect the new state. Note that it's possible for the selected
3582 // tab contents to be NULL. This is because we listen for all sources
3583 // (NavigationControllers) for convenience, so the notification could
3584 // actually be for a different window while we're doing asynchronous
3585 // closing of this one.
3586 if (GetSelectedTabContents() &&
[email protected]ce3fa3c2009-04-20 19:55:573587 &GetSelectedTabContents()->controller() ==
[email protected]e83f1682008-09-07 23:57:403588 Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:573589 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:403590 break;
3591
[email protected]0c6da502009-08-14 22:32:393592 case NotificationType::EXTENSION_UPDATE_DISABLED: {
[email protected]e6090e42010-03-23 22:44:083593 // Show the UI if the extension was disabled for escalated permissions.
[email protected]24e7a9d2009-11-04 11:11:343594 Profile* profile = Source<Profile>(source).ptr();
[email protected]bc535ee52010-08-31 18:40:323595 if (profile_->IsSameProfile(profile)) {
[email protected]eaa7dd182010-12-14 11:09:003596 ExtensionService* service = profile->GetExtensionService();
[email protected]bc535ee52010-08-31 18:40:323597 DCHECK(service);
[email protected]9adb9692010-10-29 23:14:023598 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]bc535ee52010-08-31 18:40:323599 if (service->extension_prefs()->DidExtensionEscalatePermissions(
3600 extension->id()))
3601 ShowExtensionDisabledUI(service, profile_, extension);
3602 }
[email protected]0c6da502009-08-14 22:32:393603 break;
3604 }
3605
[email protected]a9f39a312010-12-23 22:14:273606 case NotificationType::EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:363607 if (window()->GetLocationBar())
3608 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:383609
[email protected]894bb502009-05-21 22:39:573610 // Close any tabs from the unloaded extension.
[email protected]a9f39a312010-12-23 22:14:273611 const Extension* extension =
3612 Details<UnloadedExtensionInfo>(details)->extension;
[email protected]ecc523f62010-09-28 22:45:403613 TabStripModel* model = tab_handler_->GetTabStripModel();
3614 for (int i = model->count() - 1; i >= 0; --i) {
[email protected]3c9e1872010-11-18 16:17:493615 TabContents* tc = model->GetTabContentsAt(i)->tab_contents();
[email protected]894bb502009-05-21 22:39:573616 if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
3617 tc->GetURL().host() == extension->id()) {
3618 CloseTabContents(tc);
[email protected]894bb502009-05-21 22:39:573619 }
3620 }
[email protected]9fd542df2009-09-30 07:32:013621
[email protected]894bb502009-05-21 22:39:573622 break;
3623 }
3624
[email protected]a4ed6282009-12-14 20:51:163625 case NotificationType::EXTENSION_PROCESS_TERMINATED: {
[email protected]ce696a452011-05-31 17:47:363626 if (window()->GetLocationBar())
3627 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:463628 break;
3629 }
3630
[email protected]7ec9b3d82011-04-13 17:19:213631 case NotificationType::EXTENSION_UNINSTALLED:
3632 case NotificationType::EXTENSION_LOADED:
[email protected]ce696a452011-05-31 17:47:363633 if (window()->GetLocationBar())
3634 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:363635 break;
[email protected]ad0c2e1b2010-01-30 00:00:103636
[email protected]e001d412009-06-26 20:53:253637 case NotificationType::BROWSER_THEME_CHANGED:
3638 window()->UserChangedTheme();
3639 break;
3640
[email protected]91e1bd82009-09-03 22:04:403641 case NotificationType::EXTENSION_READY_FOR_INSTALL: {
[email protected]b35b26b32011-05-05 20:35:143642 // Handle EXTENSION_READY_FOR_INSTALL for last active tabbed browser.
3643 if (BrowserList::FindTabbedBrowser(profile(), true) != this)
[email protected]91e1bd82009-09-03 22:04:403644 break;
[email protected]ac025282009-12-16 19:16:383645
3646 // We only want to show the loading dialog for themes, but we don't want
3647 // to wait until unpack to find out an extension is a theme, so we test
3648 // the download_url GURL instead. This means that themes in the extensions
3649 // gallery won't get the loading dialog.
3650 GURL download_url = *(Details<GURL>(details).ptr());
[email protected]eaa7dd182010-12-14 11:09:003651 if (ExtensionService::IsDownloadFromMiniGallery(download_url))
[email protected]ac025282009-12-16 19:16:383652 window()->ShowThemeInstallBubble();
[email protected]91e1bd82009-09-03 22:04:403653 break;
3654 }
3655
[email protected]b9c505b2010-04-30 15:05:103656 case NotificationType::PREF_CHANGED: {
[email protected]2a7e7c152010-10-01 20:12:093657 const std::string& pref_name = *Details<std::string>(details).ptr();
3658 if (pref_name == prefs::kUseVerticalTabs) {
[email protected]b3344872010-05-03 15:52:293659 UseVerticalTabsChanged();
[email protected]ac86c982011-05-11 13:26:053660 } else if (pref_name == prefs::kUseCompactNavigationBar) {
3661 UseCompactNavigationBarChanged();
[email protected]2a7e7c152010-10-01 20:12:093662 } else if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:373663 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]73de26a2010-10-17 03:23:253664 } else if (pref_name == prefs::kInstantEnabled) {
3665 if (!InstantController::IsEnabled(profile())) {
3666 if (instant()) {
3667 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:293668 instant_.reset();
3669 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:253670 }
3671 } else {
3672 CreateInstantIfNecessary();
3673 }
[email protected]543432ee2010-10-22 16:32:133674 } else if (pref_name == prefs::kDevToolsDisabled) {
3675 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:043676 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]543432ee2010-10-22 16:32:133677 g_browser_process->devtools_manager()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:583678 } else if (pref_name == prefs::kEditBookmarksEnabled) {
3679 UpdateCommandsForBookmarkEditing();
[email protected]97b46382011-05-02 13:23:043680 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
3681 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
3682 UpdateOpenFileState();
[email protected]2a7e7c152010-10-01 20:12:093683 } else {
[email protected]b9c505b2010-04-30 15:05:103684 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:093685 }
[email protected]b9c505b2010-04-30 15:05:103686 break;
3687 }
3688
[email protected]9a9a9e22011-05-13 22:20:353689 case NotificationType::TAB_CONTENT_SETTINGS_CHANGED: {
3690 TabContents* tab_contents = Source<TabContents>(source).ptr();
3691 if (tab_contents == GetSelectedTabContents()) {
3692 LocationBar* location_bar = window()->GetLocationBar();
3693 if (location_bar)
3694 location_bar->UpdateContentSettingsIcons();
3695 }
3696 break;
3697 }
3698
[email protected]93f230e02011-06-01 14:40:003699 case NotificationType::INTERSTITIAL_ATTACHED:
3700 window()->ShelfVisibilityChanged();
3701 break;
3702
[email protected]e83f1682008-09-07 23:57:403703 default:
3704 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:293705 }
3706}
3707
[email protected]d3b98c82010-07-14 07:45:593708///////////////////////////////////////////////////////////////////////////////
3709// Browser, ProfileSyncServiceObserver implementation:
3710
3711void Browser::OnStateChanged() {
3712 DCHECK(profile_->GetProfileSyncService());
3713
3714#if !defined(OS_MACOSX)
[email protected]b35b26b32011-05-05 20:35:143715 const bool show_main_ui = is_type_tabbed() && !window_->IsFullscreen();
[email protected]d3b98c82010-07-14 07:45:593716#else
[email protected]b35b26b32011-05-05 20:35:143717 const bool show_main_ui = is_type_tabbed();
[email protected]d3b98c82010-07-14 07:45:593718#endif
3719
3720 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
3721 show_main_ui && profile_->IsSyncAccessible());
3722}
[email protected]88d74942009-01-21 22:04:443723
[email protected]36b6dcb2008-11-12 01:19:573724///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:273725// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:303726
[email protected]36d5e5592010-11-15 20:45:593727void Browser::PrepareForInstant() {
3728 window_->PrepareForInstant();
3729}
3730
[email protected]3c9e1872010-11-18 16:17:493731void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
3732 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:143733 window_->ShowInstant(preview_contents);
[email protected]03bb953d2010-09-14 21:38:303734}
3735
[email protected]6b723f82010-10-05 20:14:273736void Browser::HideInstant() {
[email protected]1946c932010-12-15 00:07:383737 window_->HideInstant(instant_->is_active());
[email protected]03bb953d2010-09-14 21:38:303738}
3739
[email protected]3c9e1872010-11-18 16:17:493740void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
3741 TabContentsWrapper* tab_contents = instant_->tab_contents();
3742 int index =
3743 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
3744 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:303745 // TabStripModel takes ownership of preview_contents.
[email protected]43032342011-03-21 14:10:313746 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
3747 index, preview_contents);
3748 // InstantUnloadHandler takes ownership of tab_contents.
3749 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:333750
3751 GURL url = preview_contents->tab_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:523752 DCHECK(profile_->GetExtensionService());
3753 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:333754 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
3755 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
3756 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
3757 }
[email protected]03bb953d2010-09-14 21:38:303758}
3759
[email protected]c98fd5d82011-05-04 15:20:093760void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
3761 TabContentsWrapper* new_tab_contents) {
3762 int index =
3763 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(old_tab_contents);
[email protected]71b5d242011-04-30 02:27:203764 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]c98fd5d82011-05-04 15:20:093765 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(index,
3766 new_tab_contents);
[email protected]71b5d242011-04-30 02:27:203767 // TODO(tburkard): Run unload handlers like Instant does in
3768 // InstantUnloadHandler::RunUnloadListenersOrDestroy
[email protected]71b5d242011-04-30 02:27:203769}
3770
[email protected]33b8b8e2011-03-15 14:51:553771void Browser::SetSuggestedText(const string16& text,
3772 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:363773 if (window()->GetLocationBar())
3774 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:303775}
3776
[email protected]6b723f82010-10-05 20:14:273777gfx::Rect Browser::GetInstantBounds() {
3778 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:473779}
3780
[email protected]03bb953d2010-09-14 21:38:303781///////////////////////////////////////////////////////////////////////////////
[email protected]9800de5e2011-03-11 18:19:493782// Browser, protected:
3783
3784BrowserWindow* Browser::CreateBrowserWindow() {
[email protected]b35b26b32011-05-05 20:35:143785 if (type_ == TYPE_PANEL &&
[email protected]011396a2011-04-13 23:35:283786 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels))
3787 return PanelManager::GetInstance()->CreatePanel(this);
3788
[email protected]9800de5e2011-03-11 18:19:493789 return BrowserWindow::CreateBrowserWindow(this);
3790}
3791
3792
3793///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573794// Browser, Command and state updating (private):
3795
3796void Browser::InitCommandState() {
3797 // All browser commands whose state isn't set automagically some other way
3798 // (like Back & Forward with initial page load) must have their state
3799 // initialized here, otherwise they will be forever disabled.
3800
[email protected]84214982008-12-10 18:49:103801 // Navigation commands
[email protected]1fc025202009-01-20 23:03:143802 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:163803 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:103804
3805 // Window management commands
[email protected]1fc025202009-01-20 23:03:143806 command_updater_.UpdateCommandEnabled(IDC_NEW_WINDOW, true);
[email protected]97b46382011-05-02 13:23:043807 command_updater_.UpdateCommandEnabled(
3808 IDC_NEW_INCOGNITO_WINDOW,
3809 profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled));
[email protected]1fc025202009-01-20 23:03:143810 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
3811 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
3812 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
3813 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:133814 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:143815 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]c8b59f92010-05-28 21:45:473816 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
[email protected]cdc05ec2011-05-18 15:15:593817 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:103818
3819 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:513820 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:143821 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
3822 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
3823 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
3824 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
3825 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
3826 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
3827 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
3828 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
3829 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
3830 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
3831 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
3832 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
3833 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
3834 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
3835 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
3836 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
3837 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
3838 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
3839 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
3840 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
3841 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
3842 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
3843 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
3844 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
3845 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
3846 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
3847 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
3848 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
3849 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
3850 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
3851 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
3852 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
3853 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
3854 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
3855 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:003856 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:143857 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
3858 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:103859
[email protected]63b02932009-06-05 09:40:513860 // Zoom
3861 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
3862 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
3863 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
3864 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
3865
[email protected]84214982008-12-10 18:49:103866 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:043867 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:143868 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:133869 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:143870 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:143871 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]4a4180a52010-08-23 06:39:483872 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER,
3873 browser_defaults::bookmarks_enabled);
[email protected]1fc025202009-01-20 23:03:143874 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
3875 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]4aee5652009-11-19 18:59:213876 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true);
[email protected]d6852fd2011-05-20 17:19:123877 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:293878
[email protected]96e34672010-02-09 21:40:293879#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:053880 command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
[email protected]f97d7f632010-06-01 21:08:333881 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:503882 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:473883 command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
3884 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:293885#endif
[email protected]c8b59f92010-05-28 21:45:473886
[email protected]14908b72011-04-20 06:54:363887 ExtensionService* extension_service = profile()->GetExtensionService();
[email protected]9cd51a02009-10-23 22:30:293888 bool enable_extensions =
[email protected]14908b72011-04-20 06:54:363889 extension_service && extension_service->extensions_enabled();
[email protected]9cd51a02009-10-23 22:30:293890 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
3891 enable_extensions);
3892
[email protected]64ff7942008-12-17 18:11:233893 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:143894 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:233895
[email protected]11f4857282009-11-13 19:56:173896 // Navigation commands
3897 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:233898
[email protected]11f4857282009-11-13 19:56:173899 // Window management commands
[email protected]cf299bc2010-08-12 20:27:093900 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:143901 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:173902 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
3903 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
3904 normal_window);
3905 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
3906 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
3907 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
3908 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
3909 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
3910 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
3911 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
3912 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
3913 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
3914 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
3915 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:553916#if defined(OS_MACOSX)
3917 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
3918#endif
[email protected]e662ade2009-06-08 18:20:143919
[email protected]fc33e9992010-04-08 19:40:133920 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:143921 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:133922
3923 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:143924 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
3925 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
3926 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:133927
[email protected]663bd9e2011-03-21 01:07:013928 // Autofill
[email protected]b35b26b32011-05-05 20:35:143929 command_updater_.UpdateCommandEnabled(IDC_AUTOFILL_DEFAULT, !is_devtools());
[email protected]cf28ec52010-04-09 22:56:343930
[email protected]11f4857282009-11-13 19:56:173931 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:133932 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:003933
[email protected]c1bbaa82010-11-08 11:17:053934 // The upgrade entry and the view incompatibility entry should always be
3935 // enabled. Whether they are visible is a separate matter determined on menu
3936 // show.
[email protected]b21d6912010-08-31 19:22:413937 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:053938 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:413939
[email protected]b569c112010-11-22 20:53:443940 // View Background Pages entry is always enabled, but is hidden if there are
3941 // no background pages.
3942 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
3943
[email protected]9282cea2009-02-18 18:49:003944 // Initialize other commands whose state changes based on fullscreen mode.
3945 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:003946
3947 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:583948
3949 UpdateCommandsForBookmarkEditing();
[email protected]36b6dcb2008-11-12 01:19:573950}
3951
[email protected]84214982008-12-10 18:49:103952void Browser::UpdateCommandsForTabState() {
[email protected]c7c42332008-11-15 01:10:543953 TabContents* current_tab = GetSelectedTabContents();
[email protected]a0366a52011-02-04 20:04:213954 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
3955 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:393956 return;
[email protected]d8375fd2008-11-25 22:45:393957
[email protected]84214982008-12-10 18:49:103958 // Navigation commands
[email protected]ce3fa3c2009-04-20 19:55:573959 NavigationController& nc = current_tab->controller();
3960 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
3961 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:133962 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
3963 CanReloadContents(current_tab));
3964 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
3965 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:293966
[email protected]84214982008-12-10 18:49:103967 // Window management commands
[email protected]1fc025202009-01-20 23:03:143968 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:143969 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:103970
[email protected]57c6a652009-05-04 07:58:343971 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:383972 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:143973 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:343974 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]31682282010-01-15 18:05:163975 current_tab->controller().CanViewSource());
[email protected]151666e2010-10-21 17:05:253976 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
3977 current_tab->ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:403978 if (is_devtools())
3979 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:253980
3981 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]4d07cdc2009-08-22 16:09:393982 // Instead of using GetURL here, we use url() (which is the "real" url of the
3983 // page) from the NavigationEntry because its reflects their origin rather
3984 // than the display one (returned by GetURL) which may be different (like
3985 // having "view-source:" on the front).
[email protected]fc33e9992010-04-08 19:40:133986 NavigationEntry* active_entry = nc.GetActiveEntry();
[email protected]c0f82ec52010-07-27 14:22:143987 bool is_chrome_internal = (active_entry ?
3988 active_entry->url().SchemeIs(chrome::kChromeUIScheme) : false);
3989 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
3990 !is_chrome_internal && SavePackage::IsSavableContents(
3991 current_tab->contents_mime_type()));
3992
[email protected]57c6a652009-05-04 07:58:343993 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:253994 // TODO(pinkerton): Disable app-mode in the model until we implement it
3995 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
3996#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:343997 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:233998 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:253999#endif
[email protected]9e823662010-10-13 23:36:004000
4001 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584002 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004003}
4004
4005void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374006 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004007
4008 command_updater_.UpdateCommandEnabled(
4009 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
4010 command_updater_.UpdateCommandEnabled(
4011 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
4012 command_updater_.UpdateCommandEnabled(
4013 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044014 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004015 UpdatePrintingState(restrictions);
4016}
4017
4018void Browser::UpdatePrintingState(int content_restrictions) {
4019 bool enabled = true;
4020 if (content_restrictions & CONTENT_RESTRICTION_PRINT) {
4021 enabled = false;
4022 } else if (g_browser_process->local_state()) {
[email protected]97b46382011-05-02 13:23:044023 enabled = g_browser_process->local_state()->
4024 GetBoolean(prefs::kPrintingEnabled);
[email protected]9e823662010-10-13 23:36:004025 }
4026 command_updater_.UpdateCommandEnabled(IDC_PRINT, enabled);
initial.commit09911bf2008-07-26 23:55:294027}
4028
[email protected]943d8122010-06-11 02:13:454029void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4030 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:144031 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:234032}
4033
[email protected]543432ee2010-10-22 16:32:134034void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044035 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424036 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134037 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4038 dev_tools_enabled);
4039 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4040 dev_tools_enabled);
4041 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4042 dev_tools_enabled);
4043}
4044
[email protected]a13f47d12011-04-14 11:41:584045void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044046 bool enabled =
4047 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4048 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584049
4050 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144051 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584052 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4053 enabled && CanBookmarkAllTabs());
4054}
4055
[email protected]97b46382011-05-02 13:23:044056void Browser::UpdateSaveAsState(int content_restrictions) {
4057 bool enabled = !(content_restrictions & CONTENT_RESTRICTION_SAVE);
4058 PrefService* state = g_browser_process->local_state();
4059 if (state)
4060 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4061
4062 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4063}
4064
4065void Browser::UpdateOpenFileState() {
4066 bool enabled = true;
4067 PrefService* local_state = g_browser_process->local_state();
4068 if (local_state)
4069 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4070
4071 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4072}
4073
[email protected]36b6dcb2008-11-12 01:19:574074///////////////////////////////////////////////////////////////////////////////
4075// Browser, UI update coalescing and handling (private):
4076
4077void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:494078 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294079}
4080
[email protected]36b6dcb2008-11-12 01:19:574081void Browser::ScheduleUIUpdate(const TabContents* source,
4082 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004083 if (!source)
4084 return;
4085
[email protected]2b4355c2009-04-04 17:55:464086 // Do some synchronous updates.
[email protected]36b6dcb2008-11-12 01:19:574087 if (changed_flags & TabContents::INVALIDATE_URL &&
4088 source == GetSelectedTabContents()) {
4089 // Only update the URL for the current tab. Note that we do not update
4090 // the navigation commands since those would have already been updated
4091 // synchronously by NavigationStateChanged.
4092 UpdateToolbar(false);
[email protected]8030f012009-09-25 18:09:374093 changed_flags &= ~TabContents::INVALIDATE_URL;
[email protected]36b6dcb2008-11-12 01:19:574094 }
[email protected]a5231662009-09-26 00:56:004095 if (changed_flags & TabContents::INVALIDATE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574096 // Update the loading state synchronously. This is so the throbber will
4097 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004098 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:404099 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4100 tab_handler_->GetTabStripModel()->GetIndexOfController(
4101 &source->controller()),
[email protected]6ebdc9b2010-09-27 16:55:574102 TabStripModelObserver::LOADING_ONLY);
4103 // The status bubble needs to be updated during INVALIDATE_LOAD too, but
4104 // we do that asynchronously by not stripping INVALIDATE_LOAD from
4105 // changed_flags.
[email protected]8030f012009-09-25 18:09:374106 }
4107
[email protected]f1cd5e82009-10-23 17:19:034108 if (changed_flags & TabContents::INVALIDATE_TITLE && !source->is_loading()) {
4109 // To correctly calculate whether the title changed while not loading
4110 // we need to process the update synchronously. This state only matters for
4111 // the TabStripModel, so we notify the TabStripModel now and notify others
4112 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:404113 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4114 tab_handler_->GetTabStripModel()->GetIndexOfController(
4115 &source->controller()),
[email protected]f1cd5e82009-10-23 17:19:034116 TabStripModelObserver::TITLE_NOT_LOADING);
4117 }
4118
[email protected]2b4355c2009-04-04 17:55:464119 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374120 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464121 return;
[email protected]36b6dcb2008-11-12 01:19:574122
4123 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404124 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574125
4126 if (chrome_updater_factory_.empty()) {
4127 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374128 MessageLoop::current()->PostDelayedTask(
4129 FROM_HERE,
[email protected]36b6dcb2008-11-12 01:19:574130 chrome_updater_factory_.NewRunnableMethod(
4131 &Browser::ProcessPendingUIUpdates),
[email protected]6ebdc9b2010-09-27 16:55:574132 kUIUpdateCoalescingTimeMS);
[email protected]36b6dcb2008-11-12 01:19:574133 }
4134}
4135
4136void Browser::ProcessPendingUIUpdates() {
4137#ifndef NDEBUG
4138 // Validate that all tabs we have pending updates for exist. This is scary
4139 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004140 // deleted tabs.
[email protected]85354982009-09-25 19:58:404141 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4142 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574143 bool found = false;
4144 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]a5231662009-09-26 00:56:004145 if (GetTabContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574146 found = true;
4147 break;
4148 }
4149 }
4150 DCHECK(found);
4151 }
4152#endif
4153
4154 chrome_updater_factory_.RevokeAll();
4155
[email protected]85354982009-09-25 19:58:404156 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4157 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574158 // Do not dereference |contents|, it may be out-of-date!
[email protected]85354982009-09-25 19:58:404159 const TabContents* contents = i->first;
4160 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574161
[email protected]a5231662009-09-26 00:56:004162 if (contents == GetSelectedTabContents()) {
4163 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344164
[email protected]9800de5e2011-03-11 18:19:494165 if (flags & TabContents::INVALIDATE_PAGE_ACTIONS) {
4166 LocationBar* location_bar = window()->GetLocationBar();
4167 if (location_bar)
4168 location_bar->UpdatePageActions();
4169 }
[email protected]6ebdc9b2010-09-27 16:55:574170 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]0dd3a0ab2011-02-18 08:17:444171 if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) {
4172 GetStatusBubble()->SetStatus(
4173 GetSelectedTabContentsWrapper()->GetStatusText());
4174 }
[email protected]a5231662009-09-26 00:56:004175
[email protected]f1cd5e82009-10-23 17:19:034176 if (flags & (TabContents::INVALIDATE_TAB |
4177 TabContents::INVALIDATE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254178// TODO(pinkerton): Disable app-mode in the model until we implement it
4179// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4180#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004181 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234182 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254183#endif
[email protected]a5231662009-09-26 00:56:004184 window_->UpdateTitleBar();
4185 }
[email protected]4d34e2e2009-05-26 22:55:284186 }
[email protected]36b6dcb2008-11-12 01:19:574187
[email protected]a5231662009-09-26 00:56:004188 // Updates that don't depend upon the selected state go here.
[email protected]f1cd5e82009-10-23 17:19:034189 if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:404190 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:494191 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034192 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574193 }
4194
4195 // We don't need to process INVALIDATE_STATE, since that's not visible.
4196 }
4197
4198 scheduled_updates_.clear();
4199}
4200
4201void Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
4202 if (!contents)
4203 return;
4204
[email protected]85354982009-09-25 19:58:404205 UpdateMap::iterator i = scheduled_updates_.find(contents);
4206 if (i != scheduled_updates_.end())
4207 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294208}
4209
[email protected]d938aed92009-01-22 19:49:334210
[email protected]36b6dcb2008-11-12 01:19:574211///////////////////////////////////////////////////////////////////////////////
4212// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294213
[email protected]36b6dcb2008-11-12 01:19:574214StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094215#if !defined(OS_MACOSX)
4216 // In kiosk mode, we want to always hide the status bubble.
4217 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4218 return NULL;
4219#endif
[email protected]9b032bf2009-07-21 17:34:234220 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294221}
4222
[email protected]36b6dcb2008-11-12 01:19:574223///////////////////////////////////////////////////////////////////////////////
4224// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294225
4226void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154227 SessionService* session_service =
4228 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294229 if (session_service) {
4230 for (int i = index; i < tab_count(); ++i) {
4231 TabContents* contents = GetTabContentsAt(i);
4232 if (contents) {
4233 session_service->SetTabIndexInWindow(
[email protected]ce3fa3c2009-04-20 19:55:574234 session_id(), contents->controller().session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404235 session_service->SetPinnedState(
4236 session_id(),
4237 contents->controller().session_id(),
4238 tab_handler_->GetTabStripModel()->IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294239 }
4240 }
4241 }
4242}
4243
[email protected]36b6dcb2008-11-12 01:19:574244///////////////////////////////////////////////////////////////////////////////
4245// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294246
[email protected]04b4a6c2008-08-02 00:44:474247void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214248 if (!is_attempting_to_close_browser_) {
4249 // Because we might invoke this after a delay it's possible for the value of
4250 // is_attempting_to_close_browser_ to have changed since we scheduled the
4251 // task.
4252 return;
4253 }
initial.commit09911bf2008-07-26 23:55:294254
[email protected]04b4a6c2008-08-02 00:44:474255 if (HasCompletedUnloadProcessing()) {
4256 // We've finished all the unload events and can proceed to close the
4257 // browser.
4258 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294259 return;
4260 }
4261
[email protected]04b4a6c2008-08-02 00:44:474262 // Process beforeunload tabs first. When that queue is empty, process
4263 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474264 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]06b42f032008-12-03 18:43:054265 TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244266 // Null check render_view_host here as this gets called on a PostTask and
4267 // the tab's render_view_host may have been nulled out.
4268 if (tab->render_view_host()) {
[email protected]ae23c272009-07-27 20:15:404269 tab->render_view_host()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244270 } else {
[email protected]08f0d612011-01-13 23:58:214271 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244272 }
[email protected]04b4a6c2008-08-02 00:44:474273 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294274 // We've finished firing all beforeunload events and can proceed with unload
4275 // events.
4276 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4277 // somewhere around here so that we have accurate measurements of shutdown
4278 // time.
[email protected]04b4a6c2008-08-02 00:44:474279 // TODO(ojan): We can probably fire all the unload events in parallel and
4280 // get a perf benefit from that in the cases where the tab hangs in it's
4281 // unload handler or takes a long time to page in.
[email protected]06b42f032008-12-03 18:43:054282 TabContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244283 // Null check render_view_host here as this gets called on a PostTask and
4284 // the tab's render_view_host may have been nulled out.
4285 if (tab->render_view_host()) {
[email protected]992db4c2011-05-12 15:37:154286 tab->render_view_host()->ClosePage();
[email protected]22484622009-06-10 21:17:244287 } else {
[email protected]08f0d612011-01-13 23:58:214288 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244289 }
initial.commit09911bf2008-07-26 23:55:294290 } else {
[email protected]04b4a6c2008-08-02 00:44:474291 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294292 }
4293}
4294
[email protected]d043c2cc2009-03-25 18:30:454295bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474296 return is_attempting_to_close_browser_ &&
4297 tabs_needing_before_unload_fired_.empty() &&
4298 tabs_needing_unload_fired_.empty();
4299}
4300
4301void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044302 // Closing of window can be canceled from:
4303 // - canceling beforeunload
4304 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474305 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284306 tabs_needing_before_unload_fired_.clear();
4307 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474308 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044309
4310 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4311 TabCloseableStateWatcher* watcher =
4312 g_browser_process->tab_closeable_state_watcher();
4313 if (watcher)
4314 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474315}
4316
[email protected]06b42f032008-12-03 18:43:054317bool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474318 DCHECK(is_attempting_to_close_browser_);
4319
[email protected]06b42f032008-12-03 18:43:054320 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4321 if (iter != set->end()) {
4322 set->erase(iter);
4323 return true;
[email protected]04b4a6c2008-08-02 00:44:474324 }
4325 return false;
4326}
initial.commit09911bf2008-07-26 23:55:294327
[email protected]08f0d612011-01-13 23:58:214328void Browser::ClearUnloadState(TabContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044329 // Closing of browser could be canceled (via IsClosingPermitted) between the
4330 // time when request was initiated and when this method is called, so check
4331 // for is_attempting_to_close_browser_ flag before proceeding.
4332 if (is_attempting_to_close_browser_) {
4333 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4334 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:214335 if (process_now) {
4336 ProcessPendingTabs();
4337 } else {
4338 MessageLoop::current()->PostTask(
4339 FROM_HERE,
4340 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
4341 }
[email protected]0b4d3382010-07-14 16:13:044342 }
initial.commit09911bf2008-07-26 23:55:294343}
4344
[email protected]36b6dcb2008-11-12 01:19:574345///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:064346// Browser, In-progress download termination handling (private):
4347
[email protected]460a2942010-12-15 19:43:154348void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present,
4349 bool* incognito_downloads_are_present) {
4350 *normal_downloads_are_present = false;
4351 *incognito_downloads_are_present = false;
4352
4353 // If there are no download in-progress, our job is done.
4354 DownloadManager* download_manager = NULL;
4355 // But first we need to check for the existance of the download manager, as
4356 // GetDownloadManager() will unnecessarily try to create one if it does not
4357 // exist.
4358 if (profile()->HasCreatedDownloadManager())
4359 download_manager = profile()->GetDownloadManager();
4360 if (profile()->IsOffTheRecord()) {
4361 // Browser is incognito and so download_manager if present is for incognito
4362 // downloads.
4363 *incognito_downloads_are_present =
4364 (download_manager && download_manager->in_progress_count() != 0);
4365 // Check original profile.
4366 if (profile()->GetOriginalProfile()->HasCreatedDownloadManager())
4367 download_manager = profile()->GetOriginalProfile()->GetDownloadManager();
4368 }
4369
4370 *normal_downloads_are_present =
4371 (download_manager && download_manager->in_progress_count() != 0);
4372}
4373
[email protected]69444cc2009-04-09 20:40:064374bool Browser::CanCloseWithInProgressDownloads() {
4375 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
[email protected]7a22201c2009-10-16 16:50:374376 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
4377 // We need to hear from the user before we can close.
4378 return false;
4379 }
4380 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
[email protected]69444cc2009-04-09 20:40:064381 return true;
4382 }
[email protected]446295a2010-04-19 23:43:004383 // Indicated that normal (non-incognito) downloads are pending.
4384 bool normal_downloads_are_present = false;
4385 bool incognito_downloads_are_present = false;
[email protected]460a2942010-12-15 19:43:154386 CheckDownloadsInProgress(&normal_downloads_are_present,
4387 &incognito_downloads_are_present);
[email protected]446295a2010-04-19 23:43:004388 if (!normal_downloads_are_present && !incognito_downloads_are_present)
4389 return true;
4390
4391 if (is_attempting_to_close_browser_)
4392 return true;
4393
4394 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
4395 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
[email protected]69444cc2009-04-09 20:40:064396 return true;
4397
4398 // Let's figure out if we are the last window for our profile.
4399 // Note that we cannot just use BrowserList::GetBrowserCount as browser
4400 // windows closing is delayed and the returned count might include windows
4401 // that are being closed.
[email protected]446295a2010-04-19 23:43:004402 // The browser allowed to be closed only if:
4403 // 1. It is a regular browser and there are no regular downloads present or
4404 // this is not the last regular browser window.
4405 // 2. It is an incognito browser and there are no incognito downloads present
4406 // or this is not the last incognito browser window.
[email protected]69444cc2009-04-09 20:40:064407 int count = 0;
4408 for (BrowserList::const_iterator iter = BrowserList::begin();
4409 iter != BrowserList::end(); ++iter) {
4410 // Don't count this browser window or any other in the process of closing.
[email protected]b35b26b32011-05-05 20:35:144411 // Only consider tabbed browser windows, not popups.
[email protected]460a2942010-12-15 19:43:154412 Browser* const browser = *iter;
4413 if (browser == this
4414 || browser->is_attempting_to_close_browser_
[email protected]b35b26b32011-05-05 20:35:144415 || !browser->is_type_tabbed())
[email protected]69444cc2009-04-09 20:40:064416 continue;
4417
[email protected]446295a2010-04-19 23:43:004418 // Verify that this is not the last non-incognito or incognito browser,
4419 // depending on the pending downloads.
4420 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154421 browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004422 continue;
4423 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154424 !browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004425 continue;
4426
[email protected]69444cc2009-04-09 20:40:064427 // We test the original profile, because an incognito browser window keeps
4428 // the original profile alive (and its DownloadManager).
4429 // We also need to test explicitly the profile directly so that 2 incognito
4430 // profiles count as a match.
4431 if ((*iter)->profile() == profile() ||
4432 (*iter)->profile()->GetOriginalProfile() == profile())
4433 count++;
4434 }
4435 if (count > 0)
4436 return true;
4437
4438 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4439 window_->ConfirmBrowserCloseWithPendingDownloads();
4440
4441 // Return false so the browser does not close. We'll close if the user
4442 // confirms in the dialog.
4443 return false;
4444}
4445
4446///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574447// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:294448
[email protected]1a6b30a2009-08-19 03:52:114449// static
[email protected]de4e7632010-09-01 06:24:044450Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
[email protected]b35b26b32011-05-05 20:35:144451 return BrowserList::FindTabbedBrowser(profile, match_incognito);
[email protected]de4e7632010-09-01 06:24:044452}
4453
4454// static
[email protected]1a6b30a2009-08-19 03:52:114455Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:044456 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:054457 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:114458 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:294459 return browser;
4460}
4461
[email protected]9219d262011-02-15 21:05:124462void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]e7cfdbd2011-04-22 14:41:374463 // TabContents...
[email protected]9219d262011-02-15 21:05:124464 tab->tab_contents()->set_delegate(delegate);
4465 tab->set_delegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:374466
4467 // ...and all the helpers.
4468 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:144469 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]ddb85052011-05-18 14:40:274470 tab->download_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:124471 tab->search_engine_tab_helper()->set_delegate(delegate);
4472}
4473
[email protected]4f3dc372009-02-24 00:10:294474void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:584475 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:294476 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:004477 string16 find_text;
4478#if defined(OS_MACOSX)
4479 // We always want to search for the contents of the find pasteboard on OS X.
4480 find_text = GetFindPboardText();
4481#endif
[email protected]9c318862011-02-01 22:27:244482 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:384483 find_tab_helper()->StartFinding(find_text,
4484 forward_direction,
4485 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:294486 }
[email protected]fbd77592008-11-12 20:50:274487}
[email protected]cb17f7f2009-02-06 18:14:484488
[email protected]36b6dcb2008-11-12 01:19:574489void Browser::CloseFrame() {
4490 window_->Close();
initial.commit09911bf2008-07-26 23:55:294491}
4492
[email protected]3c9e1872010-11-18 16:17:494493void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:174494 DetachType type) {
4495 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:154496 // Save the current location bar state, but only if the tab being detached
4497 // is the selected tab. Because saving state can conditionally revert the
4498 // location bar, saving the current tab's location bar state to a
4499 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:494500 if (contents == GetSelectedTabContentsWrapper()) {
4501 LocationBar* location_bar = window()->GetLocationBar();
4502 if (location_bar)
4503 location_bar->SaveStateToContents(contents->tab_contents());
4504 }
[email protected]c37e3b62010-01-22 00:15:174505
[email protected]ecc523f62010-09-28 22:45:404506 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:174507 SyncHistoryWithTabs(0);
4508 }
4509
[email protected]9219d262011-02-15 21:05:124510 SetAsDelegate(contents, NULL);
[email protected]3c9e1872010-11-18 16:17:494511 RemoveScheduledUpdatesFor(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:174512
[email protected]ecc523f62010-09-28 22:45:404513 if (find_bar_controller_.get() &&
[email protected]1ea49d52011-04-12 17:44:444514 index == tab_handler_->GetTabStripModel()->active_index()) {
[email protected]c37e3b62010-01-22 00:15:174515 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:404516 }
[email protected]c37e3b62010-01-22 00:15:174517
[email protected]08f0d612011-01-13 23:58:214518 if (is_attempting_to_close_browser_) {
4519 // If this is the last tab with unload handlers, then ProcessPendingTabs
4520 // would call back into the TabStripModel (which is invoking this method on
4521 // us). Avoid that by passing in false so that the call to
4522 // ProcessPendingTabs is delayed.
4523 ClearUnloadState(contents->tab_contents(), false);
4524 }
4525
[email protected]93f230e02011-06-01 14:40:004526 registrar_.Remove(this, NotificationType::INTERSTITIAL_ATTACHED,
4527 Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:174528 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:054529 Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:174530}
4531
initial.commit09911bf2008-07-26 23:55:294532// static
[email protected]f87919d72011-02-02 18:46:164533void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:294534 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:514535 std::string window_pref(prefs::kBrowserWindowPlacement);
4536 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:294537 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:144538 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:164539 if (!prefs->FindPreference(window_pref.c_str())) {
4540 prefs->RegisterDictionaryPref(window_pref.c_str(),
4541 PrefService::UNSYNCABLE_PREF);
4542 }
initial.commit09911bf2008-07-26 23:55:294543}
[email protected]5c238752009-06-13 10:29:074544
[email protected]281918912010-05-27 22:05:134545void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
4546 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
4547 !service->entries().empty());
4548}
4549
4550void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
4551 if (!tab_restore_service_)
4552 return;
4553
4554 DCHECK_EQ(tab_restore_service_, service);
4555 tab_restore_service_->RemoveObserver(this);
4556 tab_restore_service_ = NULL;
4557}
[email protected]97b6c4f2010-09-27 19:31:264558
[email protected]3c9e1872010-11-18 16:17:494559// Centralized method for creating a TabContents, configuring and installing
4560// all its supporting objects and observers.
4561TabContentsWrapper* Browser::TabContentsFactory(
4562 Profile* profile,
4563 SiteInstance* site_instance,
4564 int routing_id,
4565 const TabContents* base_tab_contents,
4566 SessionStorageNamespace* session_storage_namespace) {
4567 TabContents* new_contents = new TabContents(profile, site_instance,
4568 routing_id, base_tab_contents,
4569 session_storage_namespace);
4570 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
4571 return wrapper;
4572}
4573
[email protected]6b723f82010-10-05 20:14:274574bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]35242602011-01-06 16:38:534575 if (!instant() || !instant()->is_active() || !instant()->IsCurrent() ||
4576 disposition == NEW_BACKGROUND_TAB) {
4577 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
4578 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:264579 return false;
[email protected]35242602011-01-06 16:38:534580 }
[email protected]97b6c4f2010-09-27 19:31:264581
4582 if (disposition == CURRENT_TAB) {
[email protected]6b723f82010-10-05 20:14:274583 instant()->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER);
[email protected]97b6c4f2010-09-27 19:31:264584 return true;
4585 }
[email protected]35242602011-01-06 16:38:534586 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:494587 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]6b723f82010-10-05 20:14:274588 INSTANT_COMMIT_PRESSED_ENTER);
[email protected]a0df03c122011-01-05 00:22:554589 // HideInstant is invoked after release so that InstantController is not
4590 // active when HideInstant asks it for its state.
4591 HideInstant();
[email protected]97b6c4f2010-09-27 19:31:264592 preview_contents->controller().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:404593 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:264594 preview_contents,
4595 -1,
[email protected]6b723f82010-10-05 20:14:274596 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:414597 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:374598 instant()->CompleteRelease(preview_contents);
[email protected]97b6c4f2010-09-27 19:31:264599 return true;
4600 }
4601 // The omnibox currently doesn't use other dispositions, so we don't attempt
4602 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
4603 // support for the new disposition.
4604 NOTREACHED();
4605 return false;
4606}
[email protected]2031cf9d2010-10-12 05:05:374607
4608void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:144609 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:374610 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:194611 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:294612 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:374613 }
4614}
[email protected]77d8d622010-12-15 10:30:124615
4616void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:274617 DCHECK(contents);
4618
4619 NavigationEntry* active_entry = contents->controller().GetActiveEntry();
4620 if (!active_entry)
4621 return;
4622
4623 ViewSource(contents, active_entry->url(), active_entry->content_state());
4624}
4625
4626void Browser::ViewSource(TabContentsWrapper* contents,
4627 const GURL& url,
4628 const std::string& content_state) {
[email protected]afd1e522011-04-27 23:29:594629 UserMetrics::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:124630 DCHECK(contents);
4631
4632 TabContentsWrapper* view_source_contents = contents->Clone();
4633 view_source_contents->controller().PruneAllButActive();
4634 NavigationEntry* active_entry =
4635 view_source_contents->controller().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:504636 if (!active_entry)
4637 return;
4638
[email protected]932b7a12011-03-09 12:50:274639 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
4640 url.spec());
4641 active_entry->set_virtual_url(view_source_url);
[email protected]1436beff2010-12-16 19:47:044642
[email protected]932b7a12011-03-09 12:50:274643 // Do not restore scroller position.
4644 active_entry->set_content_state(
4645 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
4646
[email protected]cd3d50d2010-12-18 21:03:294647 // Do not restore title, derive it from the url.
[email protected]6b2f7a82011-04-25 19:30:514648 active_entry->set_title(string16());
[email protected]77d8d622010-12-15 10:30:124649
[email protected]47b309f2010-12-28 17:35:564650 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:124651 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
4652 // If this is a tabbed browser, just create a duplicate tab inside the same
4653 // window next to the tab being duplicated.
4654 int index = tab_handler_->GetTabStripModel()->
4655 GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:414656 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:564657 TabStripModel::ADD_INHERIT_GROUP;
[email protected]77d8d622010-12-15 10:30:124658 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]47b309f2010-12-28 17:35:564659 view_source_contents,
[email protected]77d8d622010-12-15 10:30:124660 add_types);
4661 } else {
[email protected]b35b26b32011-05-05 20:35:144662 Browser* browser = Browser::CreateForType(TYPE_TABBED, profile_);
[email protected]77d8d622010-12-15 10:30:124663
4664 // Preserve the size of the original window. The new window has already
4665 // been given an offset by the OS, so we shouldn't copy the old bounds.
4666 BrowserWindow* new_window = browser->window();
4667 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
4668 window()->GetRestoredBounds().size()));
4669
4670 // We need to show the browser now. Otherwise ContainerWin assumes the
4671 // TabContents is invisible and won't size it.
4672 browser->window()->Show();
4673
4674 // The page transition below is only for the purpose of inserting the tab.
[email protected]47b309f2010-12-28 17:35:564675 browser->AddTab(view_source_contents, PageTransition::LINK);
[email protected]77d8d622010-12-15 10:30:124676 }
4677
[email protected]92371eb2011-04-28 11:50:154678 SessionService* session_service =
4679 SessionServiceFactory::GetForProfileIfExisting(profile_);
4680 if (session_service)
4681 session_service->TabRestored(&view_source_contents->controller(), false);
[email protected]77d8d622010-12-15 10:30:124682}
[email protected]b9163e02011-04-20 16:03:374683
4684int Browser::GetContentRestrictionsForSelectedTab() {
4685 int content_restrictions = 0;
4686 TabContents* current_tab = GetSelectedTabContents();
4687 if (current_tab) {
4688 content_restrictions = current_tab->content_restrictions();
4689 NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
4690 // See comment in UpdateCommandsForTabState about why we call url().
4691 if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL()))
4692 content_restrictions |= CONTENT_RESTRICTION_SAVE;
4693 }
4694 return content_restrictions;
4695}