blob: a60947fc4f5068322788b1d4f879b17c026a06f3 [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]a07676b22011-06-17 16:36:5327#include "chrome/browser/background/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]81898992011-06-14 22:15:0064#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4465#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1566#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1867#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0668#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1569#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1370#include "chrome/browser/sync/profile_sync_service.h"
[email protected]40f047972009-11-25 03:54:4071#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0472#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2973#include "chrome/browser/tab_contents/background_contents.h"
[email protected]7cceebac2011-03-03 00:32:2174#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]07d490bc2011-03-07 17:05:2675#include "chrome/browser/tabs/tab_finder.h"
[email protected]c848d3d92010-09-16 21:57:4576#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]ffa6f592011-06-24 22:03:5777#include "chrome/browser/themes/theme_service.h"
78#include "chrome/browser/themes/theme_service_factory.h"
[email protected]3ab9cb82011-06-03 18:02:0779#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:3780#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:1481#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]55452902011-06-01 21:57:4782#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:0483#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:3784#include "chrome/browser/ui/browser_navigator.h"
[email protected]fb7da4132011-03-15 15:51:0085#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
[email protected]00070c732011-04-09 15:31:3386#include "chrome/browser/ui/browser_window.h"
[email protected]3ea60632011-04-08 18:25:4287#include "chrome/browser/ui/download/download_tab_helper.h"
[email protected]45300ad42010-12-02 15:51:1488#include "chrome/browser/ui/find_bar/find_bar.h"
89#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:3890#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1991#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:4392#include "chrome/browser/ui/panels/panel.h"
93#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:1294#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1995#include "chrome/browser/ui/status_bubble.h"
96#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:4497#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:1998#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]f847e6082011-03-24 00:08:2699#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]edc37b42011-04-18 20:43:39100#include "chrome/browser/ui/webui/active_downloads_ui.h"
[email protected]265a1492011-02-27 05:58:07101#include "chrome/browser/ui/webui/bug_report_ui.h"
[email protected]5c557f372011-02-26 15:09:20102#include "chrome/browser/ui/webui/options/content_settings_handler.h"
[email protected]9a800652010-12-02 17:08:44103#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54104#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50105#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33106#include "chrome/common/chrome_constants.h"
107#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:58108#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33109#include "chrome/common/extensions/extension_constants.h"
[email protected]8a53ee042009-01-21 16:41:33110#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25111#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34112#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23113#include "chrome/common/web_apps.h"
[email protected]b6021d32011-02-26 01:25:54114#include "content/browser/host_zoom_map.h"
[email protected]a01efd22011-03-01 00:38:32115#include "content/browser/renderer_host/render_view_host.h"
116#include "content/browser/site_instance.h"
[email protected]a01efd22011-03-01 00:38:32117#include "content/browser/tab_contents/interstitial_page.h"
118#include "content/browser/tab_contents/navigation_controller.h"
119#include "content/browser/tab_contents/navigation_entry.h"
[email protected]a01efd22011-03-01 00:38:32120#include "content/browser/tab_contents/tab_contents_view.h"
[email protected]afd1e522011-04-27 23:29:59121#include "content/browser/user_metrics.h"
[email protected]763ec4ca2011-04-29 15:48:12122#include "content/common/content_restriction.h"
[email protected]7f070d42011-03-09 20:25:32123#include "content/common/notification_service.h"
[email protected]4dd57932011-03-17 06:06:12124#include "content/common/page_transition_types.h"
[email protected]216813952011-05-19 22:21:26125#include "content/common/page_zoom.h"
126#include "content/common/view_messages.h"
[email protected]a3e18c42009-03-04 23:36:05127#include "grit/chromium_strings.h"
128#include "grit/generated_resources.h"
129#include "grit/locale_settings.h"
[email protected]8a53ee042009-01-21 16:41:33130#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33131#include "net/base/net_util.h"
132#include "net/base/registry_controlled_domain.h"
133#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39134#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17135#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38136#include "ui/gfx/point.h"
[email protected]1436beff2010-12-16 19:47:04137#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33138#include "webkit/glue/window_open_disposition.h"
[email protected]8a53ee042009-01-21 16:41:33139
140#if defined(OS_WIN)
[email protected]b99603c2010-12-30 22:13:32141#include "app/win/shell.h"
[email protected]36d5e5592010-11-15 20:45:59142#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15143#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59144#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12145#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19146#include "chrome/browser/ui/view_ids.h"
147#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]8a53ee042009-01-21 16:41:33148#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33149
[email protected]6a4f5af22009-09-23 22:43:00150#if defined(OS_MACOSX)
[email protected]8aee8ed32011-06-14 20:16:41151#include "content/browser/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00152#endif
153
[email protected]b7969202010-05-14 21:29:26154#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35155#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]ec2fd5a2011-04-30 06:16:05156#include "chrome/browser/extensions/file_manager_util.h"
[email protected]b7969202010-05-14 21:29:26157#endif
158
[email protected]8a53ee042009-01-21 16:41:33159using base::TimeDelta;
initial.commit09911bf2008-07-26 23:55:29160
[email protected]36b6dcb2008-11-12 01:19:57161///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29162
[email protected]505323e22009-01-24 02:47:58163namespace {
164
[email protected]91a79232010-11-10 18:15:08165// The URL to be loaded to display Help.
[email protected]8332c162011-01-26 12:01:54166const char kHelpContentUrl[] =
[email protected]91a79232010-11-10 18:15:08167#if defined(OS_CHROMEOS)
[email protected]8332c162011-01-26 12:01:54168 #if defined(OFFICIAL_BUILD)
169 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html";
170 #else
[email protected]95fc6f92011-04-13 00:37:20171 "https://www.google.com/support/chromeos/";
[email protected]8332c162011-01-26 12:01:54172 #endif
[email protected]91a79232010-11-10 18:15:08173#else
[email protected]95fc6f92011-04-13 00:37:20174 "https://www.google.com/support/chrome/";
[email protected]91a79232010-11-10 18:15:08175#endif
176
177// The URL to be opened when the Help link on the Autofill dialog is clicked.
178const char kAutofillHelpUrl[] =
179#if defined(OS_CHROMEOS)
[email protected]95fc6f92011-04-13 00:37:20180 "https://www.google.com/support/chromeos/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08181#else
[email protected]95fc6f92011-04-13 00:37:20182 "https://www.google.com/support/chrome/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08183#endif
184
185// The URL to be loaded to display the "Report a broken page" form.
186const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20187 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08188 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
189
190// The URL for the privacy dashboard.
191const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
192
193// How long we wait before updating the browser chrome while loading a page.
194const int kUIUpdateCoalescingTimeMS = 200;
195
196const char kHashMark[] = "#";
197
[email protected]505323e22009-01-24 02:47:58198} // namespace
199
[email protected]e838eaf2010-10-13 18:53:33200extern bool g_log_bug53991;
201
[email protected]b35b26b32011-05-05 20:35:14202////////////////////////////////////////////////////////////////////////////////
203// Browser, CreateParams:
204
205Browser::CreateParams::CreateParams(Type type, Profile* profile)
206 : type(type),
207 profile(profile) {
208}
209
[email protected]36b6dcb2008-11-12 01:19:57210///////////////////////////////////////////////////////////////////////////////
211// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29212
[email protected]299dabd2008-11-19 02:27:16213Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05214 : type_(type),
215 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39216 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40217 ALLOW_THIS_IN_INITIALIZER_LIST(
218 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14219 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29220 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05221 chrome_updater_factory_(this),
222 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06223 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]2e716622009-03-09 21:11:01224 maximized_state_(MAXIMIZED_STATE_DEFAULT),
[email protected]867125a02009-12-10 06:01:48225 method_factory_(this),
226 block_command_execution_(false),
227 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51228 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00229 pending_web_app_action_(NONE),
230 ALLOW_THIS_IN_INITIALIZER_LIST(
231 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48232 new BrowserTabRestoreServiceDelegate(this))),
233 bookmark_bar_state_(BookmarkBar::HIDDEN) {
[email protected]0cb94102009-05-22 19:51:21234 registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED,
235 NotificationService::AllSources());
[email protected]0c6da502009-08-14 22:32:39236 registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
237 NotificationService::AllSources());
[email protected]ad0c2e1b2010-01-30 00:00:10238 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
239 NotificationService::AllSources());
[email protected]0cb94102009-05-22 19:51:21240 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
241 NotificationService::AllSources());
[email protected]0dfe05c2011-02-23 23:03:36242 registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
243 NotificationService::AllSources());
[email protected]a4ed6282009-12-14 20:51:16244 registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED,
[email protected]371ed7a2009-08-25 15:22:46245 NotificationService::AllSources());
[email protected]ffa6f592011-06-24 22:03:57246 registrar_.Add(
247 this, NotificationType::BROWSER_THEME_CHANGED,
248 Source<ThemeService>(ThemeServiceFactory::GetForProfile(profile_)));
[email protected]9a9a9e22011-05-13 22:20:35249 registrar_.Add(this, NotificationType::TAB_CONTENT_SETTINGS_CHANGED,
250 NotificationService::AllSources());
[email protected]09b29342011-06-24 19:18:48251 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
252 NotificationService::AllSources());
initial.commit09911bf2008-07-26 23:55:29253
[email protected]91e1bd82009-09-03 22:04:40254 // Need to know when to alert the user of theme install delay.
255 registrar_.Add(this, NotificationType::EXTENSION_READY_FOR_INSTALL,
256 NotificationService::AllSources());
257
[email protected]9e823662010-10-13 23:36:00258 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04259 if (local_state) {
260 local_pref_registrar_.Init(local_state);
261 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
262 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
263 }
264
265 profile_pref_registrar_.Init(profile_->GetPrefs());
266 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
267 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
268 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]e1581e32011-06-09 15:18:02269 profile_pref_registrar_.Add(prefs::kIncognitoEnabled, this);
[email protected]9e823662010-10-13 23:36:00270
initial.commit09911bf2008-07-26 23:55:29271 InitCommandState();
272 BrowserList::AddBrowser(this);
273
[email protected]97b46382011-05-02 13:23:04274 // NOTE: These prefs all need to be explicitly destroyed in the destructor
275 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29276 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
277 profile_->GetPrefs(), NULL);
[email protected]b9c505b2010-04-30 15:05:10278 use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
[email protected]ac86c982011-05-11 13:26:05279 use_compact_navigation_bar_.Init(prefs::kUseCompactNavigationBar,
280 profile_->GetPrefs(),
281 this);
[email protected]97b46382011-05-02 13:23:04282
[email protected]b9c505b2010-04-30 15:05:10283 if (!TabMenuModel::AreVerticalTabsEnabled()) {
284 // If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
285 // might show vertical tabs but not show an option to turn them off.
286 use_vertical_tabs_.SetValue(false);
287 }
[email protected]ac86c982011-05-11 13:26:05288 if (!TabMenuModel::IsCompactNavigationModeEnabled()) {
289 // If the compact navigation bar isn't enabled, explicitly turn it off.
290 // Otherwise we might show the compact navigation bar but not show an option
291 // to turn it off.
292 use_compact_navigation_bar_.SetValue(false);
293 }
294
[email protected]b3344872010-05-03 15:52:29295 UpdateTabStripModelInsertionPolicy();
[email protected]281918912010-05-27 22:05:13296
[email protected]92371eb2011-04-28 11:50:15297 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13298 if (tab_restore_service_) {
299 tab_restore_service_->AddObserver(this);
300 TabRestoreServiceChanged(tab_restore_service_);
301 }
[email protected]d3b98c82010-07-14 07:45:59302
303 if (profile_->GetProfileSyncService())
304 profile_->GetProfileSyncService()->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30305
[email protected]2031cf9d2010-10-12 05:05:37306 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26307
308 // Make sure TabFinder has been created. This does nothing if TabFinder is
309 // not enabled.
310 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48311
312 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
initial.commit09911bf2008-07-26 23:55:29313}
314
315Browser::~Browser() {
[email protected]5044da82010-10-27 01:09:16316 VLOG_IF(1, g_log_bug53991) << "~Browser: " << profile_->IsOffTheRecord()
317 << "; stillActive="
318 << BrowserList::IsOffTheRecordSessionActive();
[email protected]e838eaf2010-10-13 18:53:33319
[email protected]d3b98c82010-07-14 07:45:59320 if (profile_->GetProfileSyncService())
321 profile_->GetProfileSyncService()->RemoveObserver(this);
322
initial.commit09911bf2008-07-26 23:55:29323 BrowserList::RemoveBrowser(this);
324
[email protected]7be64502011-05-03 17:51:47325#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29326 if (!BrowserList::HasBrowserWithProfile(profile_)) {
327 // We're the last browser window with this profile. We need to nuke the
328 // TabRestoreService, which will start the shutdown of the
329 // NavigationControllers and allow for proper shutdown. If we don't do this
330 // chrome won't shutdown cleanly, and may end up crashing when some
331 // thread tries to use the IO thread (or another thread) that is no longer
332 // valid.
[email protected]fbc947b2009-06-19 13:28:24333 // This isn't a valid assumption for Mac OS, as it stays running after
334 // the last browser has closed. The Mac equivalent is in its app
335 // controller.
[email protected]92371eb2011-04-28 11:50:15336 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29337 }
[email protected]fbc947b2009-06-19 13:28:24338#endif
initial.commit09911bf2008-07-26 23:55:29339
[email protected]92371eb2011-04-28 11:50:15340 SessionService* session_service =
341 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29342 if (session_service)
343 session_service->WindowClosed(session_id_);
344
[email protected]92371eb2011-04-28 11:50:15345 TabRestoreService* tab_restore_service =
346 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]d8375fd2008-11-25 22:45:39347 if (tab_restore_service)
[email protected]fb7da4132011-03-15 15:51:00348 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39349
[email protected]97b46382011-05-02 13:23:04350 profile_pref_registrar_.RemoveAll();
351 local_pref_registrar_.RemoveAll();
352
[email protected]9a8c4022011-01-25 14:25:33353 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33354 use_vertical_tabs_.Destroy();
[email protected]ac86c982011-05-11 13:26:05355 use_compact_navigation_bar_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33356
initial.commit09911bf2008-07-26 23:55:29357 if (profile_->IsOffTheRecord() &&
358 !BrowserList::IsOffTheRecordSessionActive()) {
[email protected]0d1add32011-04-07 00:06:50359 // An incognito profile is no longer needed, this indirectly
[email protected]860f55492009-03-27 19:50:59360 // frees its cache and cookies.
361 profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
initial.commit09911bf2008-07-26 23:55:29362 }
363
364 // There may be pending file dialogs, we need to tell them that we've gone
365 // away so they don't try and call back to us.
366 if (select_file_dialog_.get())
367 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13368
369 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29370}
371
[email protected]15952e462008-11-14 00:29:05372// static
373Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14374 Browser* browser = new Browser(TYPE_TABBED, profile);
375 browser->InitBrowserWindow();
376 return browser;
377}
378
379// static
380Browser* Browser::CreateWithParams(const CreateParams& params) {
381 Browser* browser = new Browser(params.type, params.profile);
382 browser->app_name_ = params.app_name;
383 if (!params.initial_bounds.IsEmpty())
384 browser->set_override_bounds(params.initial_bounds);
[email protected]9800de5e2011-03-11 18:19:49385 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05386 return browser;
387}
[email protected]6104acf2008-11-11 22:27:34388
[email protected]15952e462008-11-14 00:29:05389// static
[email protected]9ee17e8c2010-08-10 19:17:31390Browser* Browser::CreateForType(Type type, Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14391 CreateParams params(type, profile);
392 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05393}
394
395// static
[email protected]b35b26b32011-05-05 20:35:14396Browser* Browser::CreateForApp(Type type,
397 const std::string& app_name,
[email protected]5c209242011-06-06 20:36:17398 const gfx::Rect& window_bounds,
[email protected]b35b26b32011-05-05 20:35:14399 Profile* profile) {
400 DCHECK(type != TYPE_TABBED);
401 DCHECK(!app_name.empty());
[email protected]f075fe0a22010-04-26 04:06:43402
[email protected]b35b26b32011-05-05 20:35:14403 RegisterAppPrefs(app_name, profile);
404
405#if !defined(OS_CHROMEOS)
406 if (type == TYPE_PANEL &&
407 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
408 // The panel UI is not fully implemented, so we default to TYPE_POPUP when
409 // the panel switch is not enabled. See crbug/55943.
410 type = TYPE_POPUP;
[email protected]5530ac652010-09-25 05:35:49411 }
[email protected]b35b26b32011-05-05 20:35:14412#endif
[email protected]f075fe0a22010-04-26 04:06:43413
[email protected]b35b26b32011-05-05 20:35:14414 CreateParams params(type, profile);
415 params.app_name = app_name;
[email protected]5c209242011-06-06 20:36:17416 if (!window_bounds.IsEmpty())
417 params.initial_bounds = window_bounds;
[email protected]605cfad2010-06-22 20:49:35418
[email protected]b35b26b32011-05-05 20:35:14419 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05420}
421
[email protected]8e48e982009-12-25 11:22:46422// static
423Browser* Browser::CreateForDevTools(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14424 CreateParams params(TYPE_POPUP, profile);
425 params.app_name = DevToolsWindow::kDevToolsApp;
426 return CreateWithParams(params);
[email protected]8e48e982009-12-25 11:22:46427}
428
[email protected]9800de5e2011-03-11 18:19:49429void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05430 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43431
[email protected]9800de5e2011-03-11 18:19:49432 window_ = CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:05433
[email protected]80cf3562009-11-17 08:17:24434#if defined(OS_WIN)
[email protected]45446a52010-11-04 17:41:00435 {
436 // TODO: This might hit the disk
437 // http://code.google.com/p/chromium/issues/detail?id=61638
438 base::ThreadRestrictions::ScopedAllowIO allow_io;
439
440 // Set the app user model id for this application to that of the application
441 // name. See http://crbug.com/7028.
[email protected]b99603c2010-12-30 22:13:32442 app::win::SetAppIdForWindow(
[email protected]b35b26b32011-05-05 20:35:14443 is_app() ?
[email protected]45446a52010-11-04 17:41:00444 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
445 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
446 window()->GetNativeHandle());
447 }
[email protected]80cf3562009-11-17 08:17:24448#endif
449
[email protected]14d8c66e2009-09-22 00:32:52450 NotificationService::current()->Notify(
451 NotificationType::BROWSER_WINDOW_READY,
452 Source<Browser>(this),
453 NotificationService::NoDetails());
454
[email protected]ac86c982011-05-11 13:26:05455 if (use_compact_navigation_bar_.GetValue()) {
456 // This enables the compact navigation bar host.
457 UseCompactNavigationBarChanged();
458 }
459
[email protected]15952e462008-11-14 00:29:05460 // Show the First Run information bubble if we've been told to.
461 PrefService* local_state = g_browser_process->local_state();
[email protected]be3877f2009-01-14 15:51:10462 if (!local_state)
463 return;
[email protected]da6ce5602009-12-07 23:09:32464 if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
[email protected]15952e462008-11-14 00:29:05465 local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50466 FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07467 if (local_state->
[email protected]da6ce5602009-12-07 23:09:32468 FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
[email protected]adfe1882010-04-13 23:01:07469 local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50470 bubble_type = FirstRun::OEM_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07471 } else if (local_state->
472 FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
473 local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50474 bubble_type = FirstRun::MINIMAL_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07475 }
[email protected]15952e462008-11-14 00:29:05476 // Reset the preference so we don't show the bubble for subsequent windows.
477 local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
[email protected]adfe1882010-04-13 23:01:07478 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
initial.commit09911bf2008-07-26 23:55:29479 }
[email protected]f69c8852010-10-12 02:36:46480 if (local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01481 prefs::kAutofillPersonalDataManagerFirstRun) &&
482 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46483 // Notify PDM that this is a first run.
484#if defined(OS_WIN)
485 ImportAutofillDataWin(profile_->GetPersonalDataManager());
486#endif // defined(OS_WIN)
487 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01488 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46489 }
initial.commit09911bf2008-07-26 23:55:29490}
491
[email protected]36b6dcb2008-11-12 01:19:57492///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07493// Getters & Setters
494
495const std::vector<std::wstring>& Browser::user_data_dir_profiles() const {
496 return g_browser_process->user_data_dir_profiles();
497}
498
499void Browser::set_user_data_dir_profiles(
500 const std::vector<std::wstring>& profiles) {
501 g_browser_process->user_data_dir_profiles() = profiles;
502}
503
[email protected]b77cb302009-10-29 04:09:17504FindBarController* Browser::GetFindBarController() {
505 if (!find_bar_controller_.get()) {
506 FindBar* find_bar = BrowserWindow::CreateFindBar(this);
507 find_bar_controller_.reset(new FindBarController(find_bar));
508 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24509 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17510 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
511 }
512 return find_bar_controller_.get();
513}
514
[email protected]24db8a072009-10-29 20:35:37515bool Browser::HasFindBarController() const {
516 return find_bar_controller_.get() != NULL;
517}
518
[email protected]b35b26b32011-05-05 20:35:14519bool Browser::is_app() const {
520 return !app_name_.empty();
521}
522
523bool Browser::is_devtools() const {
524 return app_name_ == DevToolsWindow::kDevToolsApp;
525}
526
[email protected]5c238752009-06-13 10:29:07527///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57528// Browser, Creation Helpers:
529
530// static
[email protected]15952e462008-11-14 00:29:05531void Browser::OpenEmptyWindow(Profile* profile) {
532 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57533 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05534 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29535}
536
[email protected]36b6dcb2008-11-12 01:19:57537// static
[email protected]fbc947b2009-06-19 13:28:24538void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15539 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24540 if (service)
541 service->RestoreMostRecentEntry(NULL);
542}
543
544// static
[email protected]36b6dcb2008-11-12 01:19:57545void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55546 Browser* browser = GetOrCreateTabbedBrowser(
547 profile->GetOffTheRecordProfile());
548 browser->AddSelectedTabWithURL(url, PageTransition::LINK);
[email protected]15952e462008-11-14 00:29:05549 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17550}
551
[email protected]36b6dcb2008-11-12 01:19:57552// static
[email protected]d83a5602010-09-16 00:22:48553TabContents* Browser::OpenApplication(
554 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02555 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39556 extension_misc::LaunchContainer container,
[email protected]7e41c2b2011-05-06 10:31:16557 WindowOpenDisposition disposition) {
[email protected]56869382010-05-11 21:45:46558 TabContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04559 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
560 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37561
[email protected]9b217652010-10-08 22:04:23562 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
563
[email protected]bbadaa782010-04-28 21:21:53564 switch (container) {
[email protected]d83a5602010-09-16 00:22:48565 case extension_misc::LAUNCH_WINDOW:
566 case extension_misc::LAUNCH_PANEL:
[email protected]bbadaa782010-04-28 21:21:53567 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]0e71e4152010-12-07 04:16:26568 GURL(), NULL);
[email protected]c28071ad2010-03-12 17:28:56569 break;
[email protected]d83a5602010-09-16 00:22:48570 case extension_misc::LAUNCH_TAB: {
[email protected]7e41c2b2011-05-06 10:31:16571 tab = Browser::OpenApplicationTab(profile, extension, disposition);
[email protected]c28071ad2010-03-12 17:28:56572 break;
573 }
574 default:
575 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53576 break;
[email protected]c28071ad2010-03-12 17:28:56577 }
[email protected]bbadaa782010-04-28 21:21:53578 return tab;
[email protected]c28071ad2010-03-12 17:28:56579}
580
581// static
[email protected]bbadaa782010-04-28 21:21:53582TabContents* Browser::OpenApplicationWindow(
583 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02584 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48585 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26586 const GURL& url_input,
587 Browser** app_browser) {
[email protected]f381dfa2010-04-29 04:41:37588 GURL url;
589 if (!url_input.is_empty()) {
590 if (extension)
[email protected]cced75a2011-05-20 08:31:12591 DCHECK(extension->web_extent().MatchesURL(url_input));
[email protected]f381dfa2010-04-29 04:41:37592 url = url_input;
593 } else {
[email protected]ae5909e2011-02-23 14:34:18594 DCHECK(extension); // Empty url and no extension. Nothing to open.
[email protected]f381dfa2010-04-29 04:41:37595 url = extension->GetFullLaunchURL();
596 }
597
[email protected]2f1c09d2011-01-14 14:58:14598 std::string app_name;
599 if (extension)
600 app_name =
601 web_app::GenerateApplicationNameFromExtensionId(extension->id());
602 else
603 app_name = web_app::GenerateApplicationNameFromURL(url);
604
[email protected]b35b26b32011-05-05 20:35:14605 Type type = extension && (container == extension_misc::LAUNCH_PANEL) ?
606 TYPE_PANEL : TYPE_POPUP;
[email protected]94ce7252010-12-20 21:46:33607
[email protected]5c209242011-06-06 20:36:17608 gfx::Rect window_bounds;
609 if (extension) {
610 window_bounds.set_width(extension->launch_width());
611 window_bounds.set_height(extension->launch_height());
612 }
[email protected]94ce7252010-12-20 21:46:33613
[email protected]5c209242011-06-06 20:36:17614 Browser* browser = Browser::CreateForApp(type, app_name, window_bounds,
[email protected]b35b26b32011-05-05 20:35:14615 profile);
[email protected]011396a2011-04-13 23:35:28616
[email protected]0e71e4152010-12-07 04:16:26617 if (app_browser)
618 *app_browser = browser;
619
[email protected]3c9e1872010-11-18 16:17:49620 TabContentsWrapper* wrapper =
[email protected]cecc93a2010-10-05 15:58:55621 browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
[email protected]3c9e1872010-11-18 16:17:49622 TabContents* contents = wrapper->tab_contents();
[email protected]cecc93a2010-10-05 15:58:55623 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
624 contents->render_view_host()->SyncRendererPrefs();
625 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53626
[email protected]68f009f2009-02-26 19:43:35627 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
628 // focus explicitly.
[email protected]cecc93a2010-10-05 15:58:55629 contents->view()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26630 return contents;
631}
[email protected]eabfdae92009-12-11 06:13:51632
[email protected]0e71e4152010-12-07 04:16:26633TabContents* Browser::OpenAppShortcutWindow(Profile* profile,
634 const GURL& url,
635 bool update_shortcut) {
636 Browser* app_browser;
637 TabContents* tab = OpenApplicationWindow(
638 profile,
639 NULL, // this is a URL app. No extension.
640 extension_misc::LAUNCH_WINDOW,
641 url,
642 &app_browser);
643
644 if (!tab)
645 return NULL;
646
647 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35648 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
649 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
650 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46651 // OnDidGetApplicationInfo, which calls
652 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
653 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26654 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35655 }
[email protected]0e71e4152010-12-07 04:16:26656 return tab;
[email protected]c28071ad2010-03-12 17:28:56657}
658
659// static
[email protected]bbadaa782010-04-28 21:21:53660TabContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02661 const Extension* extension,
[email protected]7e41c2b2011-05-06 10:31:16662 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14663 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]cecc93a2010-10-05 15:58:55664 TabContents* contents = NULL;
[email protected]ea86bfb2011-02-08 18:15:44665 if (!browser)
[email protected]cecc93a2010-10-05 15:58:55666 return contents;
[email protected]c28071ad2010-03-12 17:28:56667
[email protected]10abd192010-09-30 02:03:49668 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36669 ExtensionService* extension_service = profile->GetExtensionService();
670 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59671
[email protected]10abd192010-09-30 02:03:49672 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36673 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02674 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23675 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]eaca0ad12011-04-18 15:53:41676 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49677 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
678 add_type |= TabStripModel::ADD_PINNED;
679
[email protected]37fcf262011-01-26 19:39:15680 // For extensions lacking launch urls, determine a reasonable fallback.
681 GURL extension_url = extension->GetFullLaunchURL();
682 if (!extension_url.is_valid()) {
683 extension_url = extension->options_url();
684 if (!extension_url.is_valid())
685 extension_url = GURL(chrome::kChromeUIExtensionsURL);
686 }
687
[email protected]10abd192010-09-30 02:03:49688 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
689 // cases.
[email protected]37fcf262011-01-26 19:39:15690 browser::NavigateParams params(browser, extension_url,
[email protected]616381f02010-11-02 15:15:33691 PageTransition::START_PAGE);
692 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16693 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39694
[email protected]7e41c2b2011-05-06 10:31:16695 if (disposition == CURRENT_TAB) {
696 TabContents* existing_tab = browser->GetSelectedTabContents();
[email protected]24bf2022010-10-14 16:34:39697 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49698 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39699
700 existing_tab->OpenURL(extension->GetFullLaunchURL(), existing_tab->GetURL(),
[email protected]7e41c2b2011-05-06 10:31:16701 disposition, PageTransition::LINK);
[email protected]616381f02010-11-02 15:15:33702 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39703 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49704 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26705 }
[email protected]eaca0ad12011-04-18 15:53:41706 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
707 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39708
709 contents = existing_tab;
710 } else {
[email protected]616381f02010-11-02 15:15:33711 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:49712 contents = params.target_contents->tab_contents();
[email protected]24bf2022010-10-14 16:34:39713 }
714
[email protected]7bd42fc2011-02-09 17:32:42715 // TODO(skerner): If we are already in full screen mode, and the user
716 // set the app to open as a regular or pinned tab, what should happen?
717 // Today we open the tab, but stay in full screen mode. Should we leave
718 // full screen mode in this case?
719 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
720 !browser->window()->IsFullscreen())
721 browser->ToggleFullscreenMode();
[email protected]10abd192010-09-30 02:03:49722
[email protected]cecc93a2010-10-05 15:58:55723 return contents;
[email protected]c28071ad2010-03-12 17:28:56724}
725
726// static
[email protected]90a8bf252010-03-12 00:09:47727void Browser::OpenBookmarkManagerWindow(Profile* profile) {
728 Browser* browser = Browser::Create(profile);
729 browser->ShowBookmarkManagerTab();
730 browser->window()->Show();
731}
732
[email protected]057d959a2010-03-12 02:56:20733#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47734// static
[email protected]91a5b3e2009-10-30 19:32:22735void Browser::OpenHistoryWindow(Profile* profile) {
736 Browser* browser = Browser::Create(profile);
737 browser->ShowHistoryTab();
738 browser->window()->Show();
739}
740
741// static
742void Browser::OpenDownloadsWindow(Profile* profile) {
743 Browser* browser = Browser::Create(profile);
744 browser->ShowDownloadsTab();
745 browser->window()->Show();
746}
747
748// static
[email protected]1fdff702009-10-22 00:36:18749void Browser::OpenHelpWindow(Profile* profile) {
750 Browser* browser = Browser::Create(profile);
751 browser->OpenHelpTab();
752 browser->window()->Show();
753}
[email protected]4a42d272010-06-18 01:29:42754
[email protected]eca258132010-11-15 23:33:08755// static
[email protected]4a42d272010-06-18 01:29:42756void Browser::OpenOptionsWindow(Profile* profile) {
757 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49758 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42759 browser->window()->Show();
760}
[email protected]c8de64a2011-01-25 17:10:23761
762// static
763void Browser::OpenClearBrowingDataDialogWindow(Profile* profile) {
764 Browser* browser = Browser::Create(profile);
765 browser->OpenClearBrowsingDataDialog();
766 browser->window()->Show();
767}
768
769// static
770void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
771 Browser* browser = Browser::Create(profile);
772 browser->OpenImportSettingsDialog();
773 browser->window()->Show();
774}
[email protected]b99081b2011-03-10 17:43:47775
776// static
777void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
778 Browser* browser = Browser::Create(profile);
779 browser->OpenInstantConfirmDialog();
780 browser->window()->Show();
781}
[email protected]1fdff702009-10-22 00:36:18782#endif
783
[email protected]ccb55cf52010-03-06 22:02:04784// static
785void Browser::OpenExtensionsWindow(Profile* profile) {
786 Browser* browser = Browser::Create(profile);
787 browser->ShowExtensionsTab();
788 browser->window()->Show();
789}
790
[email protected]29d70252011-04-28 02:16:58791// static
792void Browser::NewWindowWithProfile(Profile* profile) {
793 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
794 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:15795 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
[email protected]29d70252011-04-28 02:16:58796 if (!session_service ||
797 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
798 Browser::OpenEmptyWindow(profile->GetOriginalProfile());
799 }
800}
[email protected]ccb55cf52010-03-06 22:02:04801
[email protected]36b6dcb2008-11-12 01:19:57802///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57803// Browser, State Storage and Retrieval for UI:
804
[email protected]57ecc4b2010-08-11 03:02:51805std::string Browser::GetWindowPlacementKey() const {
806 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57807 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51808 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57809 name.append(app_name_);
810 }
[email protected]bc9a5152008-11-15 00:32:04811 return name;
812}
[email protected]36b6dcb2008-11-12 01:19:57813
[email protected]bc9a5152008-11-15 00:32:04814bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14815 switch (type_) {
816 case TYPE_TABBED:
817 return true;
818 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:51819 // Only save the window placement of popups if they are restored,
820 // or the window belongs to DevTools.
821 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:14822 case TYPE_PANEL:
823 // Do not save the window placement of panels.
824 return false;
825 default:
826 return false;
827 }
[email protected]bc9a5152008-11-15 00:32:04828}
[email protected]36b6dcb2008-11-12 01:19:57829
[email protected]bc9a5152008-11-15 00:32:04830void Browser::SaveWindowPlacement(const gfx::Rect& bounds, bool maximized) {
831 // Save to the session storage service, used when reloading a past session.
832 // Note that we don't want to be the ones who cause lazy initialization of
833 // the session service. This function gets called during initial window
834 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:15835 SessionService* session_service =
836 SessionServiceFactory::GetForProfileIfExisting(profile());
837 if (session_service)
838 session_service->SetWindowBounds(session_id_, bounds, maximized);
[email protected]36b6dcb2008-11-12 01:19:57839}
840
[email protected]15952e462008-11-14 00:29:05841gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]bb975362009-01-21 01:00:22842 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05843 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
844 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
845 if (record_mode || playback_mode) {
846 // In playback/record mode we always fix the size of the browser and
847 // move it to (0,0). The reason for this is two reasons: First we want
848 // resize/moves in the playback to still work, and Second we want
849 // playbacks to work (as much as possible) on machines w/ different
850 // screen sizes.
851 return gfx::Rect(0, 0, 800, 600);
852 }
853
854 gfx::Rect restored_bounds = override_bounds_;
855 bool maximized;
[email protected]f87919d72011-02-02 18:46:16856 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05857 &restored_bounds, &maximized);
858 return restored_bounds;
859}
860
861// TODO(beng): obtain maximized state some other way so we don't need to go
862// through all this hassle.
863bool Browser::GetSavedMaximizedState() const {
[email protected]bb975362009-01-21 01:00:22864 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]15952e462008-11-14 00:29:05865 return true;
866
[email protected]2e716622009-03-09 21:11:01867 if (maximized_state_ == MAXIMIZED_STATE_MAXIMIZED)
868 return true;
869 if (maximized_state_ == MAXIMIZED_STATE_UNMAXIMIZED)
870 return false;
871
872 // An explicit maximized state was not set. Query the window sizer.
[email protected]15952e462008-11-14 00:29:05873 gfx::Rect restored_bounds;
[email protected]2e716622009-03-09 21:11:01874 bool maximized = false;
[email protected]f87919d72011-02-02 18:46:16875 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05876 &restored_bounds, &maximized);
877 return maximized;
[email protected]36b6dcb2008-11-12 01:19:57878}
879
880SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:04881 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:23882 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
883 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:04884 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57885}
886
[email protected]731f8a42009-07-20 22:07:32887string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3c9e1872010-11-18 16:17:49888 TabContents* contents = GetSelectedTabContents();
[email protected]dda5dfa32009-07-10 00:33:29889 string16 title;
[email protected]c7c42332008-11-15 01:10:54890
[email protected]731f8a42009-07-20 22:07:32891 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
892 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57893 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29894 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57895 FormatTitleForDisplay(&title);
896 }
897 if (title.empty())
[email protected]0dd3a0ab2011-02-18 08:17:44898 title = TabContentsWrapper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57899
[email protected]16779842009-07-08 23:45:29900#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:33901 // On Mac or ChromeOS, we don't want to suffix the page title with
902 // the application name.
[email protected]d904bc82009-07-07 00:41:04903 return title;
[email protected]7be64502011-05-03 17:51:47904#else
[email protected]edb5e6a2009-04-08 23:46:17905 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55906 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:14907 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:17908 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29909 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50910#endif
[email protected]36b6dcb2008-11-12 01:19:57911}
912
913// static
[email protected]dda5dfa32009-07-10 00:33:29914void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57915 size_t current_index = 0;
916 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:51917 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:15918 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:57919 current_index = match_index;
920 }
921}
922
923///////////////////////////////////////////////////////////////////////////////
924// Browser, OnBeforeUnload handling:
925
[email protected]460a2942010-12-15 19:43:15926bool Browser::TabsNeedBeforeUnloadFired() {
927 if (tabs_needing_before_unload_fired_.empty()) {
928 for (int i = 0; i < tab_count(); ++i) {
929 TabContents* contents = GetTabContentsAt(i);
930 if (contents->NeedToFireBeforeUnload())
931 tabs_needing_before_unload_fired_.insert(contents);
932 }
933 }
934 return !tabs_needing_before_unload_fired_.empty();
935}
936
[email protected]36b6dcb2008-11-12 01:19:57937bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:06938 if (!CanCloseWithInProgressDownloads())
939 return false;
940
941 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:04942 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:06943
[email protected]36b6dcb2008-11-12 01:19:57944 is_attempting_to_close_browser_ = true;
945
[email protected]460a2942010-12-15 19:43:15946 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:04947 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:57948
949 ProcessPendingTabs();
950 return false;
951}
952
953void Browser::OnWindowClosing() {
954 if (!ShouldCloseWindow())
955 return;
956
[email protected]911f8152010-03-18 16:46:40957 bool exiting = false;
958
[email protected]c984d9f2010-07-20 20:52:20959 // Application should shutdown on last window close if the user is explicitly
960 // trying to quit, or if there is nothing keeping the browser alive (such as
961 // AppController on the Mac, or BackgroundContentsService for background
962 // pages).
963 bool should_quit_if_last_browser =
964 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:50965
966 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:57967 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:40968 exiting = true;
969 }
[email protected]36b6dcb2008-11-12 01:19:57970
[email protected]92371eb2011-04-28 11:50:15971 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:57972 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:15973 SessionService* session_service =
974 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:57975 if (session_service)
976 session_service->WindowClosing(session_id());
977
[email protected]92371eb2011-04-28 11:50:15978 TabRestoreService* tab_restore_service =
979 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]b35b26b32011-05-05 20:35:14980 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:00981 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39982
[email protected]911f8152010-03-18 16:46:40983 // TODO(sky): convert session/tab restore to use notification.
984 NotificationService::current()->Notify(
985 NotificationType::BROWSER_CLOSING,
986 Source<Browser>(this),
987 Details<bool>(&exiting));
988
[email protected]36b6dcb2008-11-12 01:19:57989 CloseAllTabs();
990}
991
[email protected]28788c7d2011-05-20 23:03:45992void Browser::OnWindowActivated() {
993 // On some platforms we want to automatically reload tabs that are
994 // killed when the user selects them.
995 TabContents* contents = GetSelectedTabContents();
996 if (contents && contents->crashed_status() ==
997 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
998 if (CommandLine::ForCurrentProcess()->HasSwitch(
999 switches::kReloadKilledTabs)) {
1000 Reload(CURRENT_TAB);
1001 }
1002 }
1003}
1004
[email protected]69444cc2009-04-09 20:40:061005////////////////////////////////////////////////////////////////////////////////
1006// In-progress download termination handling:
1007
1008void Browser::InProgressDownloadResponse(bool cancel_downloads) {
1009 if (cancel_downloads) {
1010 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1011 CloseWindow();
1012 return;
1013 }
1014
1015 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1016 // close again we'll show the warning again.
1017 cancel_download_confirmation_state_ = NOT_PROMPTED;
1018
1019 // Show the download page so the user can figure-out what downloads are still
1020 // in-progress.
1021 ShowDownloadsTab();
1022}
1023
[email protected]69444cc2009-04-09 20:40:061024////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451025// Browser, TabStripModel pass-thrus:
1026
1027int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:401028 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:451029}
1030
[email protected]1ea49d52011-04-12 17:44:441031int Browser::active_index() const {
1032 return tab_handler_->GetTabStripModel()->active_index();
[email protected]c848d3d92010-09-16 21:57:451033}
1034
1035int Browser::GetIndexOfController(
1036 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:401037 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451038}
1039
[email protected]3c9e1872010-11-18 16:17:491040TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
[email protected]fb7e74922011-06-09 01:39:421041 return tabstrip_model()->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491042}
[email protected]b375c5d2011-05-03 21:15:041043
[email protected]3c9e1872010-11-18 16:17:491044TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
1045 return tabstrip_model()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451046}
1047
1048TabContents* Browser::GetSelectedTabContents() const {
[email protected]3c9e1872010-11-18 16:17:491049 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1050 if (wrapper)
1051 return wrapper->tab_contents();
1052 return NULL;
1053}
1054
1055TabContents* Browser::GetTabContentsAt(int index) const {
1056 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
1057 if (wrapper)
1058 return wrapper->tab_contents();
1059 return NULL;
[email protected]c848d3d92010-09-16 21:57:451060}
1061
[email protected]eaca0ad12011-04-18 15:53:411062void Browser::ActivateTabAt(int index, bool user_gesture) {
1063 tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451064}
1065
[email protected]fb7da4132011-03-15 15:51:001066bool Browser::IsTabPinned(int index) const {
1067 return tabstrip_model()->IsTabPinned(index);
1068}
1069
[email protected]c848d3d92010-09-16 21:57:451070void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:401071 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451072}
1073
1074////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571075// Browser, Tab adding/showing functions:
1076
[email protected]95bf8a5b2010-12-22 16:04:071077bool Browser::IsTabStripEditable() const {
1078 return window()->IsTabStripEditable();
1079}
1080
[email protected]b3344872010-05-03 15:52:291081int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:401082 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
1083 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291084}
1085
[email protected]3c9e1872010-11-18 16:17:491086TabContentsWrapper* Browser::AddSelectedTabWithURL(const GURL& url,
[email protected]cecc93a2010-10-05 15:58:551087 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:331088 browser::NavigateParams params(this, url, transition);
1089 params.disposition = NEW_FOREGROUND_TAB;
1090 browser::Navigate(&params);
1091 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571092}
1093
[email protected]3c9e1872010-11-18 16:17:491094TabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]d99cdfd2009-10-08 18:58:111095 PageTransition::Type type) {
[email protected]ecc523f62010-09-28 22:45:401096 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]eaca0ad12011-04-18 15:53:411097 tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
[email protected]3c9e1872010-11-18 16:17:491098 return tab_contents->tab_contents();
[email protected]36b6dcb2008-11-12 01:19:571099}
1100
[email protected]e0c7c262009-04-23 23:09:431101void Browser::AddTabContents(TabContents* new_contents,
1102 WindowOpenDisposition disposition,
1103 const gfx::Rect& initial_pos,
1104 bool user_gesture) {
1105 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1106}
1107
1108void Browser::CloseTabContents(TabContents* contents) {
1109 CloseContents(contents);
1110}
1111
1112void Browser::BrowserShowHtmlDialog(HtmlDialogUIDelegate* delegate,
[email protected]322f3ff2009-05-22 16:19:541113 gfx::NativeWindow parent_window) {
[email protected]66b0967e2011-05-10 17:55:561114 window_->ShowHTMLDialog(delegate, parent_window);
[email protected]e0c7c262009-04-23 23:09:431115}
1116
1117void Browser::BrowserRenderWidgetShowing() {
1118 RenderWidgetShowing();
1119}
1120
[email protected]c9bd2e82011-04-15 23:28:191121void Browser::BookmarkBarSizeChanged(bool is_animating) {
1122 window_->ToolbarSizeChanged(is_animating);
[email protected]e0c7c262009-04-23 23:09:431123}
1124
[email protected]ce3fa3c2009-04-20 19:55:571125TabContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571126 const std::vector<TabNavigation>& navigations,
1127 int tab_index,
1128 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081129 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091130 bool select,
[email protected]5e369672009-11-03 23:48:301131 bool pin,
[email protected]6ee12c42010-09-14 09:36:071132 bool from_last_session,
1133 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:491134 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
1135 MSG_ROUTING_NONE,
1136 GetSelectedTabContents(),
[email protected]ecc523f62010-09-28 22:45:401137 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:491138 TabContents* new_tab = wrapper->tab_contents();
[email protected]36fb2c7c2011-04-04 15:49:081139 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]03838e22011-06-06 15:27:141140 std::vector<NavigationEntry*> entries;
1141 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1142 profile_, navigations, &entries);
1143 new_tab->controller().Restore(
1144 selected_navigation, from_last_session, &entries);
1145 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571146
[email protected]eaca0ad12011-04-18 15:53:411147 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211148 TabStripModel::ADD_NONE;
1149 if (pin) {
1150 tab_index = std::min(tab_index, tabstrip_model()->IndexOfFirstNonMiniTab());
1151 add_types |= TabStripModel::ADD_PINNED;
1152 }
1153 tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1154 add_types);
[email protected]c93a9dd2010-04-22 20:25:181155 if (select) {
[email protected]77bc6732009-04-20 22:01:031156 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181157 } else {
1158 // We set the size of the view here, before WebKit does its initial
1159 // layout. If we don't, the initial layout of background tabs will be
1160 // performed with a view width of 0, which may cause script outputs and
1161 // anchor link location calculations to be incorrect even after a new
1162 // layout with proper view dimensions. TabStripModel::AddTabContents()
1163 // contains similar logic.
1164 new_tab->view()->SizeContents(window_->GetRestoredBounds().size());
1165 new_tab->HideContents();
1166 }
[email protected]92371eb2011-04-28 11:50:151167 SessionService* session_service =
1168 SessionServiceFactory::GetForProfileIfExisting(profile_);
1169 if (session_service)
[email protected]81898992011-06-14 22:15:001170 session_service->TabRestored(wrapper, pin);
[email protected]ce3fa3c2009-04-20 19:55:571171 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571172}
1173
1174void Browser::ReplaceRestoredTab(
1175 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301176 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101177 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071178 const std::string& extension_app_id,
1179 SessionStorageNamespace* session_storage_namespace) {
[email protected]3c9e1872010-11-18 16:17:491180 TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
[email protected]ecc523f62010-09-28 22:45:401181 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:491182 GetSelectedTabContents(),
[email protected]6ee12c42010-09-14 09:36:071183 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081184 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]3c9e1872010-11-18 16:17:491185 TabContents* replacement = wrapper->tab_contents();
[email protected]03838e22011-06-06 15:27:141186 std::vector<NavigationEntry*> entries;
1187 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1188 profile_, navigations, &entries);
1189 replacement->controller().Restore(
1190 selected_navigation, from_last_session, &entries);
1191 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571192
[email protected]ecc523f62010-09-28 22:45:401193 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
[email protected]1ea49d52011-04-12 17:44:441194 tab_handler_->GetTabStripModel()->active_index(),
[email protected]3c9e1872010-11-18 16:17:491195 wrapper);
[email protected]36b6dcb2008-11-12 01:19:571196}
1197
[email protected]a8eff102009-04-14 15:23:431198bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131199 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431200}
1201
[email protected]3698f172010-03-17 20:50:291202bool Browser::NavigateToIndexWithDisposition(int index,
1203 WindowOpenDisposition disp) {
1204 NavigationController& controller =
[email protected]cb84d642010-06-10 00:56:281205 GetOrCloneTabForDisposition(disp)->controller();
1206 if (index < 0 || index >= controller.entry_count())
[email protected]3698f172010-03-17 20:50:291207 return false;
[email protected]cb84d642010-06-10 00:56:281208 controller.GoToIndex(index);
1209 return true;
[email protected]3698f172010-03-17 20:50:291210}
1211
[email protected]fee320542011-03-02 01:30:491212browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1213 const GURL& url) {
[email protected]616381f02010-11-02 15:15:331214 browser::NavigateParams params(this, url, PageTransition::AUTO_BOOKMARK);
1215 params.disposition = SINGLETON_TAB;
[email protected]7d329992011-04-15 18:20:021216 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:351217 params.user_gesture = true;
[email protected]fee320542011-03-02 01:30:491218 return params;
1219}
1220
1221void Browser::ShowSingletonTab(const GURL& url) {
1222 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331223 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571224}
[email protected]d938aed92009-01-22 19:49:331225
[email protected]ae2622c2009-07-30 23:47:581226void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
[email protected]326464d2010-02-16 22:21:101227#if !defined(OS_MACOSX)
[email protected]b35b26b32011-05-05 20:35:141228 const bool show_main_ui = is_type_tabbed() && !is_fullscreen;
[email protected]326464d2010-02-16 22:21:101229#else
[email protected]b35b26b32011-05-05 20:35:141230 const bool show_main_ui = is_type_tabbed();
[email protected]326464d2010-02-16 22:21:101231#endif
[email protected]ae2622c2009-07-30 23:47:581232
[email protected]b35b26b32011-05-05 20:35:141233 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
[email protected]83548a42010-06-18 13:53:371234
[email protected]ae2622c2009-07-30 23:47:581235 // Navigation commands
1236 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
1237
1238 // Window management commands
[email protected]ae2622c2009-07-30 23:47:581239 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
[email protected]b35b26b32011-05-05 20:35:141240 type_ != TYPE_TABBED && !is_fullscreen);
[email protected]ae2622c2009-07-30 23:47:581241
1242 // Focus various bits of UI
1243 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
1244 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
1245 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
[email protected]cc824372010-03-31 15:33:011246 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141247 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371248 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141249 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371250 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141251 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371252 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141253 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
[email protected]83548a42010-06-18 13:53:371254 command_updater_.UpdateCommandEnabled(
[email protected]b35b26b32011-05-05 20:35:141255 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
[email protected]ae2622c2009-07-30 23:47:581256
1257 // Show various bits of UI
1258 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
[email protected]1c41a932010-11-22 23:41:231259 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]4a4180a52010-08-23 06:39:481260 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
1261 browser_defaults::bookmarks_enabled && show_main_ui);
[email protected]ae2622c2009-07-30 23:47:581262 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
[email protected]d3b98c82010-07-14 07:45:591263 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
1264 show_main_ui && profile_->IsSyncAccessible());
[email protected]da96e54c2010-08-12 00:18:321265
[email protected]ae2622c2009-07-30 23:47:581266 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
1267 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
1268 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
1269 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
[email protected]fdb98512009-08-26 01:37:101270 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
[email protected]c8b59f92010-05-28 21:45:471271 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
[email protected]ac86c982011-05-11 13:26:051272 command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
[email protected]7664ab32011-02-01 23:35:251273#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
1274 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
1275#endif
[email protected]ae2622c2009-07-30 23:47:581276}
1277
[email protected]36b6dcb2008-11-12 01:19:571278///////////////////////////////////////////////////////////////////////////////
1279// Browser, Assorted browser commands:
1280
[email protected]d497b0782010-03-29 19:19:061281bool Browser::ShouldOpenNewTabForWindowDisposition(
1282 WindowOpenDisposition disposition) {
1283 return (disposition == NEW_FOREGROUND_TAB ||
1284 disposition == NEW_BACKGROUND_TAB);
1285}
1286
[email protected]cb84d642010-06-10 00:56:281287TabContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291288 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491289 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]d497b0782010-03-29 19:19:061290 if (ShouldOpenNewTabForWindowDisposition(disposition)) {
[email protected]cb84d642010-06-10 00:56:281291 current_tab = current_tab->Clone();
[email protected]ecc523f62010-09-28 22:45:401292 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]4a1665442010-06-28 16:09:391293 current_tab, -1, PageTransition::LINK,
[email protected]eaca0ad12011-04-18 15:53:411294 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
[email protected]4a1665442010-06-28 16:09:391295 TabStripModel::ADD_NONE);
[email protected]3698f172010-03-17 20:50:291296 }
[email protected]3c9e1872010-11-18 16:17:491297 return current_tab->tab_contents();
[email protected]3698f172010-03-17 20:50:291298}
1299
[email protected]b3344872010-05-03 15:52:291300void Browser::UpdateTabStripModelInsertionPolicy() {
[email protected]ecc523f62010-09-28 22:45:401301 tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
[email protected]b3344872010-05-03 15:52:291302 TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
1303}
1304
1305void Browser::UseVerticalTabsChanged() {
1306 UpdateTabStripModelInsertionPolicy();
1307 window()->ToggleTabStripMode();
1308}
1309
[email protected]ac86c982011-05-11 13:26:051310void Browser::UseCompactNavigationBarChanged() {
1311 window_->ToggleUseCompactNavigationBar();
1312}
1313
[email protected]018cf362010-05-05 22:43:221314bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1315 bool check_fullscreen) const {
1316 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1317 // other platforms, we hide some controls when in fullscreen mode.
1318 bool hide_ui_for_fullscreen = false;
1319#if !defined(OS_MACOSX)
1320 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1321 window_->IsFullscreen();
1322#endif
1323
[email protected]8b8e7c92010-08-19 18:05:561324 unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
[email protected]018cf362010-05-05 22:43:221325
1326#if !defined(OS_CHROMEOS)
1327 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1328 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1329 features |= FEATURE_DOWNLOADSHELF;
1330#endif // !defined(OS_CHROMEOS)
1331
[email protected]b35b26b32011-05-05 20:35:141332 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221333 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221334
1335 if (!hide_ui_for_fullscreen) {
[email protected]b35b26b32011-05-05 20:35:141336 if (!is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221337 features |= FEATURE_TITLEBAR;
1338
[email protected]b35b26b32011-05-05 20:35:141339 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221340 features |= FEATURE_TABSTRIP;
1341
[email protected]b35b26b32011-05-05 20:35:141342 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221343 features |= FEATURE_TOOLBAR;
1344
[email protected]b35b26b32011-05-05 20:35:141345 if (!is_app())
[email protected]018cf362010-05-05 22:43:221346 features |= FEATURE_LOCATIONBAR;
1347 }
1348 return !!(features & feature);
1349}
1350
[email protected]0b4d3382010-07-14 16:13:041351bool Browser::IsClosingPermitted() {
1352 TabCloseableStateWatcher* watcher =
1353 g_browser_process->tab_closeable_state_watcher();
1354 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1355 if (!can_close && is_attempting_to_close_browser_)
1356 CancelWindowClose();
1357 return can_close;
1358}
1359
[email protected]485fba42009-03-24 23:27:291360void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591361 UserMetrics::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271362
[email protected]3c9e1872010-11-18 16:17:491363 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]ce3fa3c2009-04-20 19:55:571364 if (current_tab->controller().CanGoBack()) {
[email protected]cb84d642010-06-10 00:56:281365 TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061366 // If we are on an interstitial page and clone the tab, it won't be copied
1367 // to the new tab, so we don't need to go back.
[email protected]3c9e1872010-11-18 16:17:491368 if (current_tab->tab_contents()->showing_interstitial_page() &&
1369 (new_tab != current_tab->tab_contents()))
[email protected]d497b0782010-03-29 19:19:061370 return;
[email protected]cb84d642010-06-10 00:56:281371 new_tab->controller().GoBack();
[email protected]485fba42009-03-24 23:27:291372 }
[email protected]36b6dcb2008-11-12 01:19:571373}
1374
[email protected]3698f172010-03-17 20:50:291375void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591376 UserMetrics::RecordAction(UserMetricsAction("Forward"));
[email protected]3c9e1872010-11-18 16:17:491377 if (GetSelectedTabContentsWrapper()->controller().CanGoForward())
[email protected]cb84d642010-06-10 00:56:281378 GetOrCloneTabForDisposition(disposition)->controller().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571379}
1380
[email protected]cb84d642010-06-10 00:56:281381void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591382 UserMetrics::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281383 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161384}
[email protected]fbd77592008-11-12 20:50:271385
[email protected]cb84d642010-06-10 00:56:281386void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591387 UserMetrics::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281388 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161389}
1390
[email protected]cb84d642010-06-10 00:56:281391void Browser::ReloadInternal(WindowOpenDisposition disposition,
1392 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571393 // If we are showing an interstitial, treat this as an OpenURL.
1394 TabContents* current_tab = GetSelectedTabContents();
[email protected]cb84d642010-06-10 00:56:281395 if (current_tab && current_tab->showing_interstitial_page()) {
1396 NavigationEntry* entry = current_tab->controller().GetActiveEntry();
1397 DCHECK(entry); // Should exist if interstitial is showing.
1398 OpenURL(entry->url(), GURL(), disposition, PageTransition::RELOAD);
1399 return;
[email protected]36b6dcb2008-11-12 01:19:571400 }
[email protected]cb84d642010-06-10 00:56:281401
1402 // As this is caused by a user action, give the focus to the page.
[email protected]3c9e1872010-11-18 16:17:491403 TabContents* tab = GetOrCloneTabForDisposition(disposition);
1404 if (!tab->FocusLocationBarByDefault())
1405 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281406 if (ignore_cache)
[email protected]3c9e1872010-11-18 16:17:491407 tab->controller().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281408 else
[email protected]3c9e1872010-11-18 16:17:491409 tab->controller().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571410}
1411
[email protected]485fba42009-03-24 23:27:291412void Browser::Home(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591413 UserMetrics::RecordAction(UserMetricsAction("Home"));
[email protected]485fba42009-03-24 23:27:291414 OpenURL(GetHomePage(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
[email protected]36b6dcb2008-11-12 01:19:571415}
1416
[email protected]fbd77592008-11-12 20:50:271417void Browser::OpenCurrentURL() {
[email protected]afd1e522011-04-27 23:29:591418 UserMetrics::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351419 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491420 if (!location_bar)
1421 return;
1422
[email protected]9d0306ea2009-09-02 19:38:391423 WindowOpenDisposition open_disposition =
1424 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271425 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301426 return;
[email protected]03bb953d2010-09-14 21:38:301427
[email protected]83bf2d142009-11-06 18:19:301428 GURL url(WideToUTF8(location_bar->GetInputString()));
[email protected]07d490bc2011-03-07 17:05:261429
1430 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1431 Browser* existing_browser = NULL;
1432 TabContents* existing_tab = TabFinder::GetInstance()->FindTab(
1433 this, url, &existing_browser);
1434 if (existing_tab) {
1435 existing_browser->ActivateContents(existing_tab);
1436 return;
1437 }
1438 }
1439
[email protected]616381f02010-11-02 15:15:331440 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1441 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251442 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1443 // inherit the opener. In some cases the tabstrip will determine the group
1444 // should be inherited, in which case the group is inherited instead of the
1445 // opener.
[email protected]616381f02010-11-02 15:15:331446 params.tabstrip_add_types =
1447 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1448 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331449
[email protected]6e37fe32011-03-02 09:06:521450 DCHECK(profile_->GetExtensionService());
1451 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:331452 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1453 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1454 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1455 }
[email protected]fbd77592008-11-12 20:50:271456}
1457
[email protected]84214982008-12-10 18:49:101458void Browser::Stop() {
[email protected]afd1e522011-04-27 23:29:591459 UserMetrics::RecordAction(UserMetricsAction("Stop"));
[email protected]3c9e1872010-11-18 16:17:491460 GetSelectedTabContentsWrapper()->tab_contents()->Stop();
[email protected]84214982008-12-10 18:49:101461}
1462
1463void Browser::NewWindow() {
[email protected]047e7272010-06-03 19:53:351464 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
[email protected]6e6f6cb2011-01-27 13:26:551465 CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito) &&
[email protected]97b46382011-05-02 13:23:041466 profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled)) {
[email protected]047e7272010-06-03 19:53:351467 NewIncognitoWindow();
1468 return;
1469 }
[email protected]afd1e522011-04-27 23:29:591470 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
[email protected]c9b19942010-03-26 15:58:081471 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:151472 SessionServiceFactory::GetForProfile(profile_->GetOriginalProfile());
[email protected]c9b19942010-03-26 15:58:081473 if (!session_service ||
1474 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1475 Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1476 }
[email protected]84214982008-12-10 18:49:101477}
1478
1479void Browser::NewIncognitoWindow() {
[email protected]97b46382011-05-02 13:23:041480 if (!profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled)) {
[email protected]6e6f6cb2011-01-27 13:26:551481 NewWindow();
1482 return;
1483 }
1484
[email protected]afd1e522011-04-27 23:29:591485 UserMetrics::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]84214982008-12-10 18:49:101486 Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1487}
1488
[email protected]84214982008-12-10 18:49:101489void Browser::CloseWindow() {
[email protected]afd1e522011-04-27 23:29:591490 UserMetrics::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101491 window_->Close();
1492}
1493
[email protected]fbd77592008-11-12 20:50:271494void Browser::NewTab() {
[email protected]afd1e522011-04-27 23:29:591495 UserMetrics::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261496
[email protected]b35b26b32011-05-05 20:35:141497 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271498 AddBlankTab(true);
[email protected]49bb7ea32011-02-02 17:58:061499 GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271500 } else {
[email protected]1a6b30a2009-08-19 03:52:111501 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271502 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051503 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111504 // The call to AddBlankTab above did not set the focus to the tab as its
1505 // window was not active, so we have to do it explicitly.
1506 // See http://crbug.com/6380.
[email protected]3c9e1872010-11-18 16:17:491507 b->GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271508 }
1509}
1510
1511void Browser::CloseTab() {
[email protected]afd1e522011-04-27 23:29:591512 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211513 if (CanCloseTab())
1514 tab_handler_->GetTabStripModel()->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271515}
1516
[email protected]fbd77592008-11-12 20:50:271517void Browser::SelectNextTab() {
[email protected]afd1e522011-04-27 23:29:591518 UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]ecc523f62010-09-28 22:45:401519 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271520}
1521
1522void Browser::SelectPreviousTab() {
[email protected]afd1e522011-04-27 23:29:591523 UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]ecc523f62010-09-28 22:45:401524 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271525}
1526
[email protected]91ac9202010-07-30 18:32:351527void Browser::OpenTabpose() {
1528#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031529 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1530 switches::kEnableExposeForTabs)) {
1531 return;
1532 }
1533
[email protected]afd1e522011-04-27 23:29:591534 UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351535 window()->OpenTabpose();
1536#else
1537 NOTREACHED();
1538#endif
1539}
1540
[email protected]9ac7fcb2009-09-14 18:22:521541void Browser::MoveTabNext() {
[email protected]afd1e522011-04-27 23:29:591542 UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]ecc523f62010-09-28 22:45:401543 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521544}
1545
1546void Browser::MoveTabPrevious() {
[email protected]afd1e522011-04-27 23:29:591547 UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]ecc523f62010-09-28 22:45:401548 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521549}
1550
[email protected]fbd77592008-11-12 20:50:271551void Browser::SelectNumberedTab(int index) {
1552 if (index < tab_count()) {
[email protected]afd1e522011-04-27 23:29:591553 UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]eaca0ad12011-04-18 15:53:411554 tab_handler_->GetTabStripModel()->ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271555 }
1556}
1557
1558void Browser::SelectLastTab() {
[email protected]afd1e522011-04-27 23:29:591559 UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]ecc523f62010-09-28 22:45:401560 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271561}
1562
1563void Browser::DuplicateTab() {
[email protected]afd1e522011-04-27 23:29:591564 UserMetrics::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441565 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271566}
1567
1568void Browser::RestoreTab() {
[email protected]afd1e522011-04-27 23:29:591569 UserMetrics::RecordAction(UserMetricsAction("RestoreTab"));
[email protected]92371eb2011-04-28 11:50:151570 TabRestoreService* service =
1571 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]fbd77592008-11-12 20:50:271572 if (!service)
1573 return;
1574
[email protected]fb7da4132011-03-15 15:51:001575 service->RestoreMostRecentEntry(tab_restore_service_delegate());
[email protected]fbd77592008-11-12 20:50:271576}
1577
[email protected]0c4c3882009-10-01 21:42:141578void Browser::WriteCurrentURLToClipboard() {
1579 // TODO(ericu): There isn't currently a metric for this. Should there be?
1580 // We don't appear to track the action when it comes from the
1581 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141582
1583 TabContents* contents = GetSelectedTabContents();
1584 if (!contents->ShouldDisplayURL())
1585 return;
1586
[email protected]90f39902009-10-03 04:25:371587 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141588 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171589 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141590 g_browser_process->clipboard());
1591}
1592
[email protected]fbd77592008-11-12 20:50:271593void Browser::ConvertPopupToTabbedBrowser() {
[email protected]afd1e522011-04-27 23:29:591594 UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]1ea49d52011-04-12 17:44:441595 int tab_strip_index = tab_handler_->GetTabStripModel()->active_index();
[email protected]3c9e1872010-11-18 16:17:491596 TabContentsWrapper* contents =
[email protected]ecc523f62010-09-28 22:45:401597 tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
[email protected]15952e462008-11-14 00:29:051598 Browser* browser = Browser::Create(profile_);
1599 browser->tabstrip_model()->AppendTabContents(contents, true);
1600 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271601}
1602
[email protected]9282cea2009-02-18 18:49:001603void Browser::ToggleFullscreenMode() {
[email protected]34930432009-11-09 00:12:091604#if !defined(OS_MACOSX)
1605 // In kiosk mode, we always want to be fullscreen. When the browser first
1606 // starts we're not yet fullscreen, so let the initial toggle go through.
1607 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
1608 window_->IsFullscreen())
1609 return;
1610#endif
1611
[email protected]afd1e522011-04-27 23:29:591612 UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
[email protected]9282cea2009-02-18 18:49:001613 window_->SetFullscreen(!window_->IsFullscreen());
[email protected]7be64502011-05-03 17:51:471614 // On X11, setting fullscreen mode is an async call to the X server, which
[email protected]ae2622c2009-07-30 23:47:581615 // may or may not support fullscreen mode.
[email protected]7be64502011-05-03 17:51:471616#if !defined(USE_X11)
[email protected]9282cea2009-02-18 18:49:001617 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
[email protected]ae2622c2009-07-30 23:47:581618#endif
[email protected]9282cea2009-02-18 18:49:001619}
1620
[email protected]da17b372010-01-22 23:37:221621#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331622void Browser::Search() {
1623 // If the NTP is showing, close it.
[email protected]692c5342011-05-25 19:16:211624 const GURL& url = GetSelectedTabContents()->GetURL();
[email protected]89f550b2011-06-08 18:34:031625 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1626 url.host() == chrome::kChromeUINewTabHost) {
[email protected]f97d7f632010-06-01 21:08:331627 CloseTab();
1628 return;
1629 }
[email protected]64559862010-09-23 19:00:161630
1631 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101632 if (window_->IsFullscreen()) {
[email protected]64559862010-09-23 19:00:161633 ToggleFullscreenMode();
[email protected]ebdda9092010-10-22 17:59:101634 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1635 // visible at this point. Wait for next event cycle which toggles
1636 // the visibility of omnibox before creating new tab.
1637 MessageLoop::current()->PostTask(
1638 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search));
1639 return;
1640 }
[email protected]64559862010-09-23 19:00:161641
[email protected]f97d7f632010-06-01 21:08:331642 // Otherwise just open it.
1643 NewTab();
1644}
[email protected]d14af522010-12-02 03:54:501645
1646void Browser::ShowKeyboardOverlay() {
1647 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1648}
[email protected]20d17242009-10-26 20:21:051649#endif
1650
[email protected]fbd77592008-11-12 20:50:271651void Browser::Exit() {
[email protected]afd1e522011-04-27 23:29:591652 UserMetrics::RecordAction(UserMetricsAction("Exit"));
[email protected]965e4c42010-09-07 21:23:351653#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:351654 chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
1655 // Write /tmp/uptime-logout-started as well.
1656 const char kLogoutStarted[] = "logout-started";
1657 chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted);
[email protected]db3abe62011-02-09 15:13:251658
1659 // Login screen should show up in owner's locale.
1660 PrefService* state = g_browser_process->local_state();
1661 if (state) {
1662 std::string owner_locale = state->GetString(prefs::kOwnerLocale);
1663 if (!owner_locale.empty() &&
1664 state->GetString(prefs::kApplicationLocale) != owner_locale &&
1665 !state->IsManagedPreference(prefs::kApplicationLocale)) {
1666 state->SetString(prefs::kApplicationLocale, owner_locale);
1667 state->ScheduleSavePersistentPrefs();
1668 }
1669 }
[email protected]965e4c42010-09-07 21:23:351670#endif
[email protected]460a2942010-12-15 19:43:151671 BrowserList::Exit();
[email protected]fbd77592008-11-12 20:50:271672}
1673
[email protected]36b6dcb2008-11-12 01:19:571674void Browser::BookmarkCurrentPage() {
[email protected]afd1e522011-04-27 23:29:591675 UserMetrics::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271676
[email protected]76624fde2009-10-09 18:13:231677 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571678 if (!model || !model->IsLoaded())
1679 return; // Ignore requests until bookmarks are loaded.
1680
[email protected]76624fde2009-10-09 18:13:231681 GURL url;
[email protected]261cd762010-08-20 05:45:371682 string16 title;
[email protected]b375c5d2011-05-03 21:15:041683 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
1684 bookmark_utils::GetURLAndTitleToBookmark(tab->tab_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441685 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211686 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321687 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211688 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041689 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211690 }
[email protected]261cd762010-08-20 05:45:371691 model->SetURLStarred(url, title, true);
[email protected]11dbbd22009-11-06 18:55:041692 // Make sure the model actually added a bookmark before showing the star. A
1693 // bookmark isn't created if the url is invalid.
1694 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271695 // Only show the bubble if the window is active, otherwise we may get into
1696 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441697 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271698 }
[email protected]36b6dcb2008-11-12 01:19:571699}
1700
[email protected]40bdb6d92009-02-25 00:22:271701void Browser::SavePage() {
[email protected]afd1e522011-04-27 23:29:591702 UserMetrics::RecordAction(UserMetricsAction("SavePage"));
[email protected]15d04ae2010-10-30 01:04:501703 TabContents* current_tab = GetSelectedTabContents();
1704 if (current_tab && current_tab->contents_mime_type() == "application/pdf")
[email protected]afd1e522011-04-27 23:29:591705 UserMetrics::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]3ea60632011-04-08 18:25:421706 GetSelectedTabContentsWrapper()->download_tab_helper()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271707}
1708
[email protected]77d8d622010-12-15 10:30:121709void Browser::ViewSelectedSource() {
1710 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571711}
initial.commit09911bf2008-07-26 23:55:291712
[email protected]4801ecc2009-04-05 04:52:581713void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171714 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581715}
1716
[email protected]a3e18c42009-03-04 23:36:051717bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221718 return SupportsWindowFeatureImpl(feature, true);
1719}
[email protected]f5bf8ccf2010-02-05 18:19:251720
[email protected]018cf362010-05-05 22:43:221721bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1722 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051723}
1724
[email protected]89d6e6e2009-12-03 23:06:511725void Browser::EmailPageLocation() {
[email protected]afd1e522011-04-27 23:29:591726 UserMetrics::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]d221a392011-05-24 14:34:241727 TabContents* tc = GetSelectedTabContents();
1728 DCHECK(tc);
1729
1730 std::string title = EscapeQueryParamValue(UTF16ToUTF8(tc->GetTitle()), false);
1731 std::string page_url = EscapeQueryParamValue(tc->GetURL().spec(), false);
1732 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1733 title + "&body=%0A%0A" + page_url;
1734 platform_util::OpenExternal(GURL(mailto));
[email protected]89d6e6e2009-12-03 23:06:511735}
1736
[email protected]fbd77592008-11-12 20:50:271737void Browser::Print() {
[email protected]8980e0d2011-05-27 19:16:231738 if (switches::IsPrintPreviewEnabled())
1739 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1740 else
[email protected]49fe2262011-04-15 20:56:151741 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]fbd77592008-11-12 20:50:271742}
1743
[email protected]fbd77592008-11-12 20:50:271744void Browser::ToggleEncodingAutoDetect() {
[email protected]afd1e522011-04-27 23:29:591745 UserMetrics::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271746 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181747 // If "auto detect" is turned on, then any current override encoding
1748 // is cleared. This also implicitly performs a reload.
1749 // OTOH, if "auto detect" is turned off, we don't change the currently
1750 // active encoding.
1751 if (encoding_auto_detect_.GetValue()) {
1752 TabContents* contents = GetSelectedTabContents();
1753 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081754 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181755 }
[email protected]fbd77592008-11-12 20:50:271756}
1757
1758void Browser::OverrideEncoding(int encoding_id) {
[email protected]afd1e522011-04-27 23:29:591759 UserMetrics::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401760 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271761 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]57c6a652009-05-04 07:58:341762 TabContents* contents = GetSelectedTabContents();
1763 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081764 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271765 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401766 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191767 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1768 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401769 encoding_id,
1770 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271771 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191772 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271773 }
[email protected]36b6dcb2008-11-12 01:19:571774}
1775
[email protected]84214982008-12-10 18:49:101776void Browser::Cut() {
[email protected]afd1e522011-04-27 23:29:591777 UserMetrics::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231778 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571779}
1780
[email protected]84214982008-12-10 18:49:101781void Browser::Copy() {
[email protected]afd1e522011-04-27 23:29:591782 UserMetrics::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231783 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571784}
1785
[email protected]84214982008-12-10 18:49:101786void Browser::Paste() {
[email protected]afd1e522011-04-27 23:29:591787 UserMetrics::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231788 window()->Paste();
[email protected]84214982008-12-10 18:49:101789}
1790
1791void Browser::Find() {
[email protected]afd1e522011-04-27 23:29:591792 UserMetrics::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291793 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101794}
1795
1796void Browser::FindNext() {
[email protected]afd1e522011-04-27 23:29:591797 UserMetrics::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291798 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101799}
1800
1801void Browser::FindPrevious() {
[email protected]afd1e522011-04-27 23:29:591802 UserMetrics::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291803 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101804}
1805
[email protected]40bd6582009-12-04 23:49:511806void Browser::Zoom(PageZoom::Function zoom_function) {
[email protected]896220042010-03-23 18:14:281807 static const UserMetricsAction kActions[] = {
[email protected]216813952011-05-19 22:21:261808 UserMetricsAction("ZoomMinus"),
1809 UserMetricsAction("ZoomNormal"),
1810 UserMetricsAction("ZoomPlus")
1811 };
[email protected]896220042010-03-23 18:14:281812
[email protected]afd1e522011-04-27 23:29:591813 UserMetrics::RecordAction(kActions[zoom_function - PageZoom::ZOOM_OUT]);
[email protected]3c9e1872010-11-18 16:17:491814 TabContentsWrapper* tab_contents = GetSelectedTabContentsWrapper();
[email protected]216813952011-05-19 22:21:261815 RenderViewHost* host = tab_contents->render_view_host();
1816 host->Send(new ViewMsg_Zoom(host->routing_id(), zoom_function));
[email protected]84214982008-12-10 18:49:101817}
1818
1819void Browser::FocusToolbar() {
[email protected]afd1e522011-04-27 23:29:591820 UserMetrics::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:101821 window_->FocusToolbar();
1822}
1823
[email protected]bdb7ff62010-07-20 01:56:521824void Browser::FocusAppMenu() {
[email protected]afd1e522011-04-27 23:29:591825 UserMetrics::RecordAction(UserMetricsAction("FocusAppMenu"));
[email protected]bdb7ff62010-07-20 01:56:521826 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:011827}
1828
[email protected]84214982008-12-10 18:49:101829void Browser::FocusLocationBar() {
[email protected]afd1e522011-04-27 23:29:591830 UserMetrics::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:581831 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:101832}
1833
[email protected]83548a42010-06-18 13:53:371834void Browser::FocusBookmarksToolbar() {
[email protected]afd1e522011-04-27 23:29:591835 UserMetrics::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:371836 window_->FocusBookmarksToolbar();
1837}
1838
1839void Browser::FocusChromeOSStatus() {
[email protected]afd1e522011-04-27 23:29:591840 UserMetrics::RecordAction(UserMetricsAction("FocusChromeOSStatus"));
[email protected]83548a42010-06-18 13:53:371841 window_->FocusChromeOSStatus();
1842}
1843
1844void Browser::FocusNextPane() {
[email protected]afd1e522011-04-27 23:29:591845 UserMetrics::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:371846 window_->RotatePaneFocus(true);
1847}
1848
1849void Browser::FocusPreviousPane() {
[email protected]afd1e522011-04-27 23:29:591850 UserMetrics::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:371851 window_->RotatePaneFocus(false);
1852}
1853
[email protected]84214982008-12-10 18:49:101854void Browser::FocusSearch() {
1855 // TODO(beng): replace this with FocusLocationBar
[email protected]afd1e522011-04-27 23:29:591856 UserMetrics::RecordAction(UserMetricsAction("FocusSearch"));
[email protected]7745b822009-01-27 20:15:351857 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:101858}
1859
1860void Browser::OpenFile() {
[email protected]afd1e522011-04-27 23:29:591861 UserMetrics::RecordAction(UserMetricsAction("OpenFile"));
[email protected]9d1d8ad52011-03-11 22:58:171862#if defined(OS_CHROMEOS) && !defined(FILE_MANAGER_EXTENSION)
[email protected]f59f1162010-04-23 21:19:291863 FileBrowseUI::OpenPopup(profile_,
1864 "",
1865 FileBrowseUI::kPopupWidth,
1866 FileBrowseUI::kPopupHeight);
1867#else
[email protected]84214982008-12-10 18:49:101868 if (!select_file_dialog_.get())
1869 select_file_dialog_ = SelectFileDialog::Create(this);
1870
[email protected]35896a32010-06-09 08:42:511871 const FilePath directory = profile_->last_selected_directory();
1872
[email protected]84214982008-12-10 18:49:101873 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:561874 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:101875 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:511876 string16(), directory,
[email protected]b949f1112009-04-12 20:03:081877 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]d9898912011-04-15 21:10:001878 GetSelectedTabContents(),
[email protected]d56bcd22009-03-16 19:51:561879 parent_window, NULL);
[email protected]f59f1162010-04-23 21:19:291880#endif
[email protected]84214982008-12-10 18:49:101881}
1882
1883void Browser::OpenCreateShortcutsDialog() {
[email protected]afd1e522011-04-27 23:29:591884 UserMetrics::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:471885#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:491886 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1887 DCHECK(current_tab &&
1888 web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
1889 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:511890
1891 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
1892 if (!entry)
1893 return;
1894
[email protected]eabfdae92009-12-11 06:13:511895 // RVH's GetApplicationInfo should not be called before it returns.
1896 DCHECK(pending_web_app_action_ == NONE);
1897 pending_web_app_action_ = CREATE_SHORTCUT;
1898
[email protected]a2cf65eb2010-01-18 08:20:381899 // Start fetching web app info for CreateApplicationShortcut dialog and show
1900 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]553602e12011-04-05 17:01:181901 current_tab->extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]98f6e022009-06-05 22:49:531902#else
1903 NOTIMPLEMENTED();
1904#endif
[email protected]36b6dcb2008-11-12 01:19:571905}
1906
[email protected]2a8a98122010-07-16 11:58:481907void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
1908 std::string uma_string;
1909 switch (action) {
1910 case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
1911 uma_string = "DevTools_ToggleConsole";
1912 break;
1913 case DEVTOOLS_TOGGLE_ACTION_NONE:
1914 case DEVTOOLS_TOGGLE_ACTION_INSPECT:
1915 default:
1916 uma_string = "DevTools_ToggleWindow";
1917 break;
1918 }
[email protected]afd1e522011-04-27 23:29:591919 UserMetrics::RecordAction(UserMetricsAction(uma_string.c_str()));
[email protected]3061ccf32009-07-13 14:17:491920 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
[email protected]3c9e1872010-11-18 16:17:491921 GetSelectedTabContentsWrapper()->render_view_host(), action);
[email protected]fbd77592008-11-12 20:50:271922}
1923
[email protected]adb6a84d2011-02-07 16:58:401924void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]afd1e522011-04-27 23:29:591925 UserMetrics::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:401926 if (highlight_background_resources)
1927 window_->ShowBackgroundPages();
1928 else
1929 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:101930}
1931
[email protected]84214982008-12-10 18:49:101932void Browser::OpenBugReportDialog() {
[email protected]afd1e522011-04-27 23:29:591933 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]35d06152011-01-10 22:19:421934 browser::ShowHtmlBugReportView(this);
[email protected]84214982008-12-10 18:49:101935}
[email protected]44b2c8852009-03-18 00:57:491936
[email protected]84214982008-12-10 18:49:101937void Browser::ToggleBookmarkBar() {
[email protected]afd1e522011-04-27 23:29:591938 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:101939 window_->ToggleBookmarkBar();
1940}
1941
[email protected]84214982008-12-10 18:49:101942void Browser::OpenBookmarkManager() {
[email protected]afd1e522011-04-27 23:29:591943 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"));
[email protected]47e532b2010-04-23 17:46:401944 ShowBookmarkManagerTab();
[email protected]84214982008-12-10 18:49:101945}
[email protected]8bf80e922009-03-09 20:56:361946
[email protected]fdb98512009-08-26 01:37:101947void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:121948 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:101949 window_->ShowAppMenu();
1950}
1951
[email protected]6404197b2010-03-03 00:40:401952void Browser::ShowBookmarkManagerTab() {
[email protected]afd1e522011-04-27 23:29:591953 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]fee320542011-03-02 01:30:491954 ShowSingletonTab(GURL(chrome::kChromeUIBookmarksURL));
[email protected]6404197b2010-03-03 00:40:401955}
1956
[email protected]8bf80e922009-03-09 20:56:361957void Browser::ShowHistoryTab() {
[email protected]afd1e522011-04-27 23:29:591958 UserMetrics::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]fee320542011-03-02 01:30:491959 ShowSingletonTab(GURL(chrome::kChromeUIHistoryURL));
[email protected]8bf80e922009-03-09 20:56:361960}
[email protected]84214982008-12-10 18:49:101961
1962void Browser::ShowDownloadsTab() {
[email protected]afd1e522011-04-27 23:29:591963 UserMetrics::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]3d037ce72011-04-04 17:43:451964 if (window()) {
1965 DownloadShelf* shelf = window()->GetDownloadShelf();
1966 if (shelf->IsShowing())
1967 shelf->Close();
1968 }
[email protected]fee320542011-03-02 01:30:491969 ShowSingletonTab(GURL(chrome::kChromeUIDownloadsURL));
[email protected]84214982008-12-10 18:49:101970}
1971
[email protected]34085a32009-11-06 22:49:481972void Browser::ShowExtensionsTab() {
[email protected]afd1e522011-04-27 23:29:591973 UserMetrics::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]fee320542011-03-02 01:30:491974 ShowSingletonTab(GURL(chrome::kChromeUIExtensionsURL));
[email protected]34085a32009-11-06 22:49:481975}
1976
[email protected]c1bbaa82010-11-08 11:17:051977void Browser::ShowAboutConflictsTab() {
[email protected]afd1e522011-04-27 23:29:591978 UserMetrics::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:491979 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:051980}
1981
[email protected]10e457c2010-04-29 03:35:231982void Browser::ShowBrokenPageTab(TabContents* contents) {
[email protected]afd1e522011-04-27 23:29:591983 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]10e457c2010-04-29 03:35:231984 string16 page_title = contents->GetTitle();
1985 NavigationEntry* entry = contents->controller().GetActiveEntry();
1986 if (!entry)
1987 return;
1988 std::string page_url = entry->url().spec();
1989 std::vector<std::string> subst;
1990 subst.push_back(UTF16ToASCII(page_title));
1991 subst.push_back(page_url);
1992 std::string report_page_url =
1993 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:491994 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:231995}
1996
[email protected]12e816bde2010-09-14 19:59:291997void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]fcca741b2011-06-17 22:46:371998 browser::NavigateParams params(GetSingletonTabNavigateParams(
1999 GURL(chrome::kChromeUISettingsURL + sub_page)));
[email protected]fee320542011-03-02 01:30:492000 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
[email protected]fcca741b2011-06-17 22:46:372001
[email protected]4d920ea2011-06-22 22:29:062002 if (GetSelectedTabContents() != NULL &&
2003 (GetSelectedTabContents()->GetURL() == GURL(chrome::kChromeUINewTabURL) ||
[email protected]fcca741b2011-06-17 22:46:372004 GetSelectedTabContents()->GetURL() == GURL(chrome::kAboutBlankURL)) &&
2005 browser::GetIndexOfSingletonTab(&params) < 0) {
2006 params.disposition = CURRENT_TAB;
2007 }
2008
[email protected]fee320542011-03-02 01:30:492009 browser::Navigate(&params);
[email protected]4a42d272010-06-18 01:29:422010}
2011
[email protected]84214982008-12-10 18:49:102012void Browser::OpenClearBrowsingDataDialog() {
[email protected]afd1e522011-04-27 23:29:592013 UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:052014 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:102015}
2016
[email protected]84214982008-12-10 18:49:102017void Browser::OpenOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592018 UserMetrics::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]fcca741b2011-06-17 22:46:372019 ShowOptionsTab("");
[email protected]fbd77592008-11-12 20:50:272020}
2021
2022void Browser::OpenPasswordManager() {
[email protected]afd1e522011-04-27 23:29:592023 UserMetrics::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:042024 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272025}
2026
[email protected]1bdf29e2009-05-11 23:45:252027void Browser::OpenImportSettingsDialog() {
[email protected]afd1e522011-04-27 23:29:592028 UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052029 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252030}
[email protected]1bdf29e2009-05-11 23:45:252031
[email protected]b99081b2011-03-10 17:43:472032void Browser::OpenInstantConfirmDialog() {
2033 ShowOptionsTab(chrome::kInstantConfirmPage);
2034}
2035
[email protected]ca38d8e2009-08-20 18:08:162036void Browser::OpenSyncMyBookmarksDialog() {
[email protected]40f047972009-11-25 03:54:402037 sync_ui_util::OpenSyncMyBookmarksDialog(
[email protected]c8de64a2011-01-25 17:10:232038 profile_, this, ProfileSyncService::START_FROM_WRENCH);
[email protected]ca38d8e2009-08-20 18:08:162039}
[email protected]ca38d8e2009-08-20 18:08:162040
[email protected]fbd77592008-11-12 20:50:272041void Browser::OpenAboutChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592042 UserMetrics::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]976e69f2010-08-13 18:28:172043#if defined(OS_CHROMEOS)
[email protected]01c3857e2011-06-09 04:35:482044 std::string chrome_settings(chrome::kChromeUISettingsURL);
2045 ShowSingletonTab(GURL(chrome_settings.append(chrome::kAboutOptionsSubPage)));
[email protected]976e69f2010-08-13 18:28:172046#else
[email protected]2d46c842008-11-14 19:24:312047 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:172048#endif
[email protected]fbd77592008-11-12 20:50:272049}
2050
[email protected]b1b73942010-05-26 20:11:542051void Browser::OpenUpdateChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592052 UserMetrics::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542053 window_->ShowUpdateChromeDialog();
2054}
2055
[email protected]fbd77592008-11-12 20:50:272056void Browser::OpenHelpTab() {
[email protected]0a4a0be2010-11-09 10:42:472057 GURL help_url(kHelpContentUrl);
[email protected]0a4a0be2010-11-09 10:42:472058 GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
2059 AddSelectedTabWithURL(localized_help_url, PageTransition::AUTO_BOOKMARK);
[email protected]fbd77592008-11-12 20:50:272060}
2061
[email protected]403c14862009-10-28 00:00:492062void Browser::OpenThemeGalleryTabAndActivate() {
[email protected]616381f02010-11-02 15:15:332063 AddSelectedTabWithURL(GURL(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)),
2064 PageTransition::LINK);
[email protected]403c14862009-10-28 00:00:492065}
2066
[email protected]31cc1c022010-10-15 20:03:472067void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]3e0505452010-11-02 21:45:242068 OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
2069 NEW_FOREGROUND_TAB, PageTransition::LINK);
[email protected]31cc1c022010-10-15 20:03:472070 window_->Activate();
2071}
2072
[email protected]663bd9e2011-03-21 01:07:012073void Browser::OpenAutofillHelpTabAndActivate() {
[email protected]91a79232010-11-10 18:15:082074 GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
2075 AddSelectedTabWithURL(help_url, PageTransition::LINK);
[email protected]bb8fe2d2010-06-28 20:04:222076}
2077
[email protected]024617a2010-08-20 05:08:052078void Browser::OpenSearchEngineOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592079 UserMetrics::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052080 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052081}
2082
[email protected]16779842009-07-08 23:45:292083#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:052084void Browser::OpenFileManager() {
2085 UserMetrics::RecordAction(UserMetricsAction("OpenFileManager"));
2086 ShowSingletonTab(FileManagerUtil::GetFileBrowserUrl());
2087}
2088
[email protected]5dcbc02f2010-01-26 22:32:062089void Browser::OpenSystemOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592090 UserMetrics::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"));
[email protected]445177652011-03-09 02:04:052091 ShowOptionsTab(chrome::kSystemOptionsSubPage);
[email protected]5dcbc02f2010-01-26 22:32:062092}
2093
2094void Browser::OpenInternetOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592095 UserMetrics::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"));
[email protected]445177652011-03-09 02:04:052096 ShowOptionsTab(chrome::kInternetOptionsSubPage);
[email protected]024617a2010-08-20 05:08:052097}
2098
2099void Browser::OpenLanguageOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592100 UserMetrics::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"));
[email protected]445177652011-03-09 02:04:052101 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
[email protected]be715072009-07-07 15:43:202102}
[email protected]46b92f852010-10-06 13:12:052103
2104void Browser::OpenSystemTabAndActivate() {
2105 OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
2106 NEW_FOREGROUND_TAB, PageTransition::LINK);
2107 window_->Activate();
2108}
2109
[email protected]38017612010-10-13 18:46:002110void Browser::OpenMobilePlanTabAndActivate() {
2111 OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
2112 NEW_FOREGROUND_TAB, PageTransition::LINK);
2113 window_->Activate();
2114}
[email protected]be715072009-07-07 15:43:202115#endif
2116
[email protected]a003d8e2010-10-02 21:03:352117void Browser::OpenPluginsTabAndActivate() {
2118 OpenURL(GURL(chrome::kAboutPluginsURL), GURL(),
2119 NEW_FOREGROUND_TAB, PageTransition::LINK);
2120 window_->Activate();
2121}
2122
[email protected]36b6dcb2008-11-12 01:19:572123///////////////////////////////////////////////////////////////////////////////
2124
2125// static
[email protected]79117172009-08-28 16:11:442126void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542127 const PrefService::Preference* home_page_pref =
2128 prefs->FindPreference(prefs::kHomePage);
2129 if (home_page_pref &&
2130 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192131 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:332132 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:192133 GoogleURLTracker::kDefaultGoogleHomepage);
2134 }
[email protected]8fe6e1c2010-05-27 08:21:542135 const PrefService::Preference* home_page_is_new_tab_page_pref =
2136 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2137 if (home_page_is_new_tab_page_pref &&
2138 !home_page_is_new_tab_page_pref->IsManaged() &&
2139 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332140 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442141}
2142
2143// static
[email protected]36b6dcb2008-11-12 01:19:572144void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572145 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]8b8e7c92010-08-19 18:05:562146 prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
[email protected]f87919d72011-02-02 18:46:162147 prefs->RegisterIntegerPref(prefs::kMultipleProfilePrefMigration, 0);
[email protected]d9898912011-04-15 21:10:002148 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]09d81f82010-12-15 16:46:422149 // Educated guess: Chrome has a bundled Flash version supporting
2150 // clearing LSO data, Chromium hasn't.
2151#if defined(GOOGLE_CHROME_BUILD)
2152 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, true);
2153#else
2154 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, false);
2155#endif
[email protected]36b6dcb2008-11-12 01:19:572156}
2157
2158// static
2159void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182160 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]d36f941b2011-05-09 06:19:162161 chrome::kChromeUINewTabURL,
2162 PrefService::SYNCABLE_PREF);
2163 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2164 true,
2165 PrefService::SYNCABLE_PREF);
2166 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2167 false,
2168 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092169#if defined(OS_MACOSX)
2170 // This really belongs in platform code, but there's no good place to
2171 // initialize it between the time when the AppController is created
2172 // (where there's no profile) and the time the controller gets another
2173 // crack at the start of the main event loop. By that time, BrowserInit
2174 // has already created the browser window, and it's too late: we need the
2175 // pref to be already initialized. Doing it here also saves us from having
2176 // to hard-code pref registration in the several unit tests that use
2177 // this preference.
[email protected]d36f941b2011-05-09 06:19:162178 prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
2179 false,
2180 PrefService::SYNCABLE_PREF);
2181 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2182 true,
2183 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092184#endif
[email protected]d36f941b2011-05-09 06:19:162185 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2186 true,
2187 PrefService::SYNCABLE_PREF);
2188 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2189 true,
2190 PrefService::SYNCABLE_PREF);
2191 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2192 true,
2193 PrefService::SYNCABLE_PREF);
2194 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2195 true,
2196 PrefService::SYNCABLE_PREF);
2197 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2198 false,
2199 PrefService::SYNCABLE_PREF);
2200 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2201 false,
2202 PrefService::SYNCABLE_PREF);
2203 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2204 0,
2205 PrefService::SYNCABLE_PREF);
2206 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2207 true,
2208 PrefService::UNSYNCABLE_PREF);
2209 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2210 true,
2211 PrefService::UNSYNCABLE_PREF);
2212 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2213 true,
2214 PrefService::UNSYNCABLE_PREF);
2215 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2216 true,
2217 PrefService::UNSYNCABLE_PREF);
2218 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2219 true,
2220 PrefService::UNSYNCABLE_PREF);
2221 prefs->RegisterBooleanPref(prefs::kUseVerticalTabs,
2222 false,
2223 PrefService::UNSYNCABLE_PREF);
[email protected]ac86c982011-05-11 13:26:052224 prefs->RegisterBooleanPref(prefs::kUseCompactNavigationBar,
2225 false,
2226 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162227 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2228 true,
2229 PrefService::SYNCABLE_PREF);
2230 prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar,
2231 true,
2232 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162233 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2234 std::string(),
2235 PrefService::UNSYNCABLE_PREF);
2236 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2237 true,
2238 PrefService::UNSYNCABLE_PREF);
2239 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2240 false,
2241 PrefService::UNSYNCABLE_PREF);
2242 prefs->RegisterBooleanPref(prefs::kIncognitoEnabled,
2243 true,
2244 PrefService::UNSYNCABLE_PREF);
2245 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
2246 -1,
2247 PrefService::UNSYNCABLE_PREF);
2248 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2249 PrefService::UNSYNCABLE_PREF);
2250 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2251 PrefService::UNSYNCABLE_PREF);
[email protected]2bf2bd92011-03-31 07:12:442252 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162253 // them even though they're only typically controlled via policy.
2254 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2255 false,
2256 PrefService::UNSYNCABLE_PREF);
2257 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2258 false,
2259 PrefService::UNSYNCABLE_PREF);
2260 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2261 false,
2262 PrefService::UNSYNCABLE_PREF);
2263 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2264 true,
2265 PrefService::UNSYNCABLE_PREF);
2266 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2267 true,
2268 PrefService::UNSYNCABLE_PREF);
2269 prefs->RegisterBooleanPref(prefs::kWebKitAllowRunningInsecureContent,
[email protected]f43fd974d2011-06-01 18:53:192270 false,
[email protected]d36f941b2011-05-09 06:19:162271 PrefService::UNSYNCABLE_PREF);
[email protected]839fee772011-05-05 03:21:372272 prefs->RegisterBooleanPref(prefs::kWebKitAllowDisplayingInsecureContent,
[email protected]d36f941b2011-05-09 06:19:162273 true,
2274 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572275}
2276
2277// static
[email protected]ecc523f62010-09-28 22:45:402278bool Browser::RunUnloadEventsHelper(TabContents* contents) {
2279 // If the TabContents is not connected yet, then there's no unload
2280 // handler we can fire even if the TabContents has an unload listener.
2281 // One case where we hit this is in a tab that has an infinite loop
2282 // before load.
[email protected]5aab5e22010-12-08 22:13:292283 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402284 // If the page has unload listeners, then we tell the renderer to fire
2285 // them. Once they have fired, we'll get a message back saying whether
2286 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292287 // with the NeedToFireBeforeUnload bit cleared.
[email protected]ecc523f62010-09-28 22:45:402288 contents->render_view_host()->FirePageBeforeUnload(false);
2289 return true;
2290 }
2291 return false;
2292}
2293
2294// static
[email protected]36b6dcb2008-11-12 01:19:572295Browser* Browser::GetBrowserForController(
2296 const NavigationController* controller, int* index_result) {
2297 BrowserList::const_iterator it;
2298 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]ecc523f62010-09-28 22:45:402299 int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
2300 controller);
[email protected]36b6dcb2008-11-12 01:19:572301 if (index != TabStripModel::kNoTab) {
2302 if (index_result)
2303 *index_result = index;
2304 return *it;
2305 }
2306 }
2307
2308 return NULL;
2309}
2310
[email protected]485fba42009-03-24 23:27:292311void Browser::ExecuteCommandWithDisposition(
2312 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142313 // No commands are enabled if there is not yet any selected tab.
2314 // TODO(pkasting): It seems like we should not need this, because either
2315 // most/all commands should not have been enabled yet anyway or the ones that
2316 // are enabled should be global, or safe themselves against having no selected
2317 // tab. However, Ben says he tried removing this before and got lots of
2318 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2319 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492320 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142321 return;
2322
[email protected]59c9f002010-11-19 00:38:052323 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2324 << id;
[email protected]36b6dcb2008-11-12 01:19:572325
[email protected]867125a02009-12-10 06:01:482326 // If command execution is blocked then just record the command and return.
2327 if (block_command_execution_) {
2328 // We actually only allow no more than one blocked command, otherwise some
2329 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062330 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482331 last_blocked_command_id_ = id;
2332 last_blocked_command_disposition_ = disposition;
2333 return;
2334 }
2335
[email protected]fbd77592008-11-12 20:50:272336 // The order of commands in this switch statement must match the function
2337 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572338 switch (id) {
[email protected]84214982008-12-10 18:49:102339 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282340 case IDC_BACK: GoBack(disposition); break;
2341 case IDC_FORWARD: GoForward(disposition); break;
2342 case IDC_RELOAD: Reload(disposition); break;
2343 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2344 case IDC_HOME: Home(disposition); break;
2345 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282346 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572347
[email protected]84214982008-12-10 18:49:102348 // Window management commands
[email protected]cb84d642010-06-10 00:56:282349 case IDC_NEW_WINDOW: NewWindow(); break;
2350 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282351 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2352 case IDC_NEW_TAB: NewTab(); break;
2353 case IDC_CLOSE_TAB: CloseTab(); break;
2354 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2355 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352356 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282357 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2358 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572359 case IDC_SELECT_TAB_0:
2360 case IDC_SELECT_TAB_1:
2361 case IDC_SELECT_TAB_2:
2362 case IDC_SELECT_TAB_3:
2363 case IDC_SELECT_TAB_4:
2364 case IDC_SELECT_TAB_5:
2365 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542366 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282367 break;
2368 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2369 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2370 case IDC_RESTORE_TAB: RestoreTab(); break;
2371 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2372 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
2373 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
2374 case IDC_EXIT: Exit(); break;
2375 case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break;
[email protected]ac86c982011-05-11 13:26:052376 case IDC_COMPACT_NAVBAR: ToggleUseCompactNavigationBar(); break;
[email protected]da17b372010-01-22 23:37:222377#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282378 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:502379 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052380#endif
[email protected]36b6dcb2008-11-12 01:19:572381
[email protected]84214982008-12-10 18:49:102382 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282383 case IDC_SAVE_PAGE: SavePage(); break;
2384 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2385 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122386 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282387 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2388 case IDC_PRINT: Print(); break;
2389 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572390 case IDC_ENCODING_UTF8:
2391 case IDC_ENCODING_UTF16LE:
2392 case IDC_ENCODING_ISO88591:
2393 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492394 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572395 case IDC_ENCODING_GB18030:
2396 case IDC_ENCODING_BIG5HKSCS:
2397 case IDC_ENCODING_BIG5:
2398 case IDC_ENCODING_KOREAN:
2399 case IDC_ENCODING_SHIFTJIS:
2400 case IDC_ENCODING_ISO2022JP:
2401 case IDC_ENCODING_EUCJP:
2402 case IDC_ENCODING_THAI:
2403 case IDC_ENCODING_ISO885915:
2404 case IDC_ENCODING_MACINTOSH:
2405 case IDC_ENCODING_ISO88592:
2406 case IDC_ENCODING_WINDOWS1250:
2407 case IDC_ENCODING_ISO88595:
2408 case IDC_ENCODING_WINDOWS1251:
2409 case IDC_ENCODING_KOI8R:
2410 case IDC_ENCODING_KOI8U:
2411 case IDC_ENCODING_ISO88597:
2412 case IDC_ENCODING_WINDOWS1253:
2413 case IDC_ENCODING_ISO88594:
2414 case IDC_ENCODING_ISO885913:
2415 case IDC_ENCODING_WINDOWS1257:
2416 case IDC_ENCODING_ISO88593:
2417 case IDC_ENCODING_ISO885910:
2418 case IDC_ENCODING_ISO885914:
2419 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572420 case IDC_ENCODING_WINDOWS1254:
2421 case IDC_ENCODING_ISO88596:
2422 case IDC_ENCODING_WINDOWS1256:
2423 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002424 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572425 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282426 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572427
[email protected]84214982008-12-10 18:49:102428 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282429 case IDC_CUT: Cut(); break;
2430 case IDC_COPY: Copy(); break;
2431 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102432
2433 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282434 case IDC_FIND: Find(); break;
2435 case IDC_FIND_NEXT: FindNext(); break;
2436 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102437
2438 // Zoom
[email protected]cb84d642010-06-10 00:56:282439 case IDC_ZOOM_PLUS: Zoom(PageZoom::ZOOM_IN); break;
2440 case IDC_ZOOM_NORMAL: Zoom(PageZoom::RESET); break;
2441 case IDC_ZOOM_MINUS: Zoom(PageZoom::ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102442
2443 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282444 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2445 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2446 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522447 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372448 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
2449 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
2450 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2451 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102452
2453 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282454 case IDC_OPEN_FILE: OpenFile(); break;
2455 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482456 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2457 DEVTOOLS_TOGGLE_ACTION_NONE);
2458 break;
2459 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2460 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2461 break;
2462 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2463 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2464 break;
[email protected]adb6a84d2011-02-07 16:58:402465 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2466 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]1c41a932010-11-22 23:41:232467 case IDC_FEEDBACK: OpenBugReportDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492468
[email protected]cb84d642010-06-10 00:56:282469 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252470 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492471
[email protected]cb84d642010-06-10 00:56:282472 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2473 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]cb84d642010-06-10 00:56:282474 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2475 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2476 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
2477 case IDC_SYNC_BOOKMARKS: OpenSyncMyBookmarksDialog(); break;
2478 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052479 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282480 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2481 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2482 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412483 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2484 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052485 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]cb84d642010-06-10 00:56:282486 case IDC_HELP_PAGE: OpenHelpTab(); break;
[email protected]16779842009-07-08 23:45:292487#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:052488 case IDC_FILE_MANAGER: OpenFileManager(); break;
[email protected]cb84d642010-06-10 00:56:282489 case IDC_SYSTEM_OPTIONS: OpenSystemOptionsDialog(); break;
2490 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:052491 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:202492#endif
[email protected]d938aed92009-01-22 19:49:332493
[email protected]36b6dcb2008-11-12 01:19:572494 default:
[email protected]84214982008-12-10 18:49:102495 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272496 break;
[email protected]36b6dcb2008-11-12 01:19:572497 }
2498}
2499
[email protected]3ab6796d32010-12-21 23:56:072500bool Browser::ExecuteCommandIfEnabled(int id) {
2501 if (command_updater_.SupportsCommand(id) &&
2502 command_updater_.IsCommandEnabled(id)) {
2503 ExecuteCommand(id);
2504 return true;
2505 }
2506 return false;
2507}
2508
[email protected]06181422011-02-09 17:44:212509bool Browser::IsReservedCommandOrKey(int command_id,
2510 const NativeWebKeyboardEvent& event) {
[email protected]06181422011-02-09 17:44:212511#if defined(OS_CHROMEOS)
2512 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
2513 // aren't able to block Chrome from performing the standard actions for F1-F4
2514 // (F5-7 are grabbed by other X clients and hence don't need this protection,
2515 // and F8-10 are handled separately in Chrome via a GDK event filter, but
2516 // let's future-proof this).
2517 ui::KeyboardCode key_code =
[email protected]6a1ae6cd2011-02-11 20:06:092518 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]06181422011-02-09 17:44:212519 if (key_code == ui::VKEY_F1 ||
2520 key_code == ui::VKEY_F2 ||
2521 key_code == ui::VKEY_F3 ||
2522 key_code == ui::VKEY_F4 ||
2523 key_code == ui::VKEY_F5 ||
2524 key_code == ui::VKEY_F6 ||
2525 key_code == ui::VKEY_F7 ||
2526 key_code == ui::VKEY_F8 ||
2527 key_code == ui::VKEY_F9 ||
2528 key_code == ui::VKEY_F10) {
[email protected]6a1ae6cd2011-02-11 20:06:092529 return true;
[email protected]06181422011-02-09 17:44:212530 }
2531#endif
2532
[email protected]6a1ae6cd2011-02-11 20:06:092533 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:482534 command_id == IDC_CLOSE_WINDOW ||
2535 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2536 command_id == IDC_NEW_TAB ||
2537 command_id == IDC_NEW_WINDOW ||
2538 command_id == IDC_RESTORE_TAB ||
2539 command_id == IDC_SELECT_NEXT_TAB ||
2540 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:552541 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:332542 command_id == IDC_EXIT ||
2543 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:482544}
2545
2546void Browser::SetBlockCommandExecution(bool block) {
2547 block_command_execution_ = block;
2548 if (block) {
2549 last_blocked_command_id_ = -1;
2550 last_blocked_command_disposition_ = CURRENT_TAB;
2551 }
2552}
2553
2554int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2555 if (disposition)
2556 *disposition = last_blocked_command_disposition_;
2557 return last_blocked_command_id_;
2558}
2559
[email protected]3c9e1872010-11-18 16:17:492560void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]19d9f3a2010-10-14 21:49:362561 PageTransition::Type transition,
2562 bool user_initiated) {
2563 tabstrip_model()->TabNavigating(contents, transition);
2564
[email protected]3c9e1872010-11-18 16:17:492565 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:362566 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2567 // Forcibly reset the location bar if the url is going to change in the
2568 // current tab, since otherwise it won't discard any ongoing user edits,
2569 // since it doesn't realize this is a user-initiated action.
2570 window()->GetLocationBar()->Revert();
2571 }
2572
2573 if (GetStatusBubble())
2574 GetStatusBubble()->Hide();
2575
2576 // Update the location bar. This is synchronous. We specifically don't
2577 // update the load state since the load hasn't started yet and updating it
2578 // will put it out of sync with the actual state like whether we're
2579 // displaying a favicon, which controls the throbber. If we updated it here,
2580 // the throbber will show the default favicon for a split second when
2581 // navigating away from the new tab page.
[email protected]3c9e1872010-11-18 16:17:492582 ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
[email protected]19d9f3a2010-10-14 21:49:362583
2584 if (contents_is_selected)
[email protected]3c9e1872010-11-18 16:17:492585 contents->tab_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:362586}
2587
2588GURL Browser::GetHomePage() const {
2589 // --homepage overrides any preferences.
2590 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2591 if (command_line.HasSwitch(switches::kHomePage)) {
[email protected]a8e4b5a82010-10-27 00:05:472592 // TODO(evanm): clean up usage of DIR_CURRENT.
2593 // http://code.google.com/p/chromium/issues/detail?id=60630
2594 // For now, allow this code to call getcwd().
2595 base::ThreadRestrictions::ScopedAllowIO allow_io;
2596
[email protected]19d9f3a2010-10-14 21:49:362597 FilePath browser_directory;
2598 PathService::Get(base::DIR_CURRENT, &browser_directory);
2599 GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory,
2600 command_line.GetSwitchValuePath(switches::kHomePage)));
2601 if (home_page.is_valid())
2602 return home_page;
2603 }
2604
2605 if (profile_->GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
2606 return GURL(chrome::kChromeUINewTabURL);
2607 GURL home_page(URLFixerUpper::FixupURL(
2608 profile_->GetPrefs()->GetString(prefs::kHomePage),
2609 std::string()));
2610 if (!home_page.is_valid())
2611 return GURL(chrome::kChromeUINewTabURL);
2612 return home_page;
2613}
2614
[email protected]36b6dcb2008-11-12 01:19:572615///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402616// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:362617
[email protected]ecc523f62010-09-28 22:45:402618void Browser::OpenURL(const GURL& url, const GURL& referrer,
2619 WindowOpenDisposition disposition,
2620 PageTransition::Type transition) {
2621 OpenURLFromTab(NULL, url, referrer, disposition, transition);
2622}
2623
2624///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:292625// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2626
2627void Browser::ExecuteCommand(int id) {
2628 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2629}
2630
2631///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402632// Browser, TabHandlerDelegate implementation:
2633
2634Profile* Browser::GetProfile() const {
2635 return profile();
2636}
2637
2638Browser* Browser::AsBrowser() {
2639 return this;
2640}
2641
2642///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572643// Browser, TabStripModelDelegate implementation:
2644
[email protected]3c9e1872010-11-18 16:17:492645TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582646 return AddBlankTabAt(-1, foreground);
2647}
2648
[email protected]3c9e1872010-11-18 16:17:492649TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052650 // Time new tab page creation time. We keep track of the timing data in
2651 // TabContents, but we want to include the time it takes to create the
2652 // TabContents object too.
2653 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332654 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
2655 PageTransition::TYPED);
[email protected]616381f02010-11-02 15:15:332656 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2657 params.tabstrip_index = index;
2658 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:492659 params.target_contents->tab_contents()->set_new_tab_start_time(
2660 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332661 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052662}
2663
[email protected]3c9e1872010-11-18 16:17:492664Browser* Browser::CreateNewStripWithContents(
2665 TabContentsWrapper* detached_contents,
2666 const gfx::Rect& window_bounds,
2667 const DockInfo& dock_info,
2668 bool maximize) {
[email protected]018cf362010-05-05 22:43:222669 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:062670
[email protected]5e495462008-11-20 23:07:412671 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:412672 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2673 dock_info.AdjustOtherWindowBounds();
2674
[email protected]36b6dcb2008-11-12 01:19:572675 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:142676 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:412677 browser->set_override_bounds(new_window_bounds);
[email protected]2e716622009-03-09 21:11:012678 browser->set_maximized_state(
2679 maximize ? MAXIMIZED_STATE_MAXIMIZED : MAXIMIZED_STATE_UNMAXIMIZED);
[email protected]9800de5e2011-03-11 18:19:492680 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:052681 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:272682 // Make sure the loading state is updated correctly, otherwise the throbber
2683 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492684 browser->LoadingStateChanged(detached_contents->tab_contents());
[email protected]3d1104f2009-03-26 15:30:282685 return browser;
[email protected]36b6dcb2008-11-12 01:19:572686}
2687
2688int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:402689 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
2690 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:572691}
2692
[email protected]3c9e1872010-11-18 16:17:492693TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]36b6dcb2008-11-12 01:19:572694 const GURL& url, const GURL& referrer, Profile* profile,
2695 PageTransition::Type transition, bool defer_load,
2696 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:492697 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:402698 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:492699 GetSelectedTabContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:572700 if (!defer_load) {
2701 // Load the initial URL before adding the new tab contents to the tab strip
2702 // so that the tab contents has navigation state.
[email protected]ce3fa3c2009-04-20 19:55:572703 contents->controller().LoadURL(url, referrer, transition);
[email protected]36b6dcb2008-11-12 01:19:572704 }
2705
2706 return contents;
2707}
2708
2709bool Browser::CanDuplicateContentsAt(int index) {
[email protected]ce3fa3c2009-04-20 19:55:572710 NavigationController& nc = GetTabContentsAt(index)->controller();
2711 return nc.tab_contents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:572712}
2713
2714void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:492715 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:332716 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:122717 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:562718
2719 bool pinned = false;
2720 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2721 // If this is a tabbed browser, just create a duplicate tab inside the same
2722 // window next to the tab being duplicated.
2723 int index = tab_handler_->GetTabStripModel()->
2724 GetIndexOfTabContents(contents);
2725 pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:412726 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:562727 TabStripModel::ADD_INHERIT_GROUP |
2728 (pinned ? TabStripModel::ADD_PINNED : 0);
2729 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
2730 contents_dupe,
2731 add_types);
2732 } else {
2733 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:142734 if (is_app()) {
2735 CHECK(!is_type_popup());
2736 CHECK(!is_type_panel());
[email protected]5c209242011-06-06 20:36:172737 browser = Browser::CreateForApp(TYPE_POPUP, app_name_, gfx::Rect(),
[email protected]b35b26b32011-05-05 20:35:142738 profile_);
2739 } else if (is_type_popup()) {
[email protected]47b309f2010-12-28 17:35:562740 browser = Browser::CreateForType(TYPE_POPUP, profile_);
2741 }
2742
2743 // Preserve the size of the original window. The new window has already
2744 // been given an offset by the OS, so we shouldn't copy the old bounds.
2745 BrowserWindow* new_window = browser->window();
2746 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
2747 window()->GetRestoredBounds().size()));
2748
[email protected]4e595682011-02-09 17:07:022749 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]47b309f2010-12-28 17:35:562750 // TabContents is invisible and won't size it.
2751 browser->window()->Show();
2752
2753 // The page transition below is only for the purpose of inserting the tab.
2754 browser->AddTab(contents_dupe, PageTransition::LINK);
2755 }
2756
[email protected]92371eb2011-04-28 11:50:152757 SessionService* session_service =
2758 SessionServiceFactory::GetForProfileIfExisting(profile_);
2759 if (session_service)
[email protected]81898992011-06-14 22:15:002760 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:572761}
2762
[email protected]36b6dcb2008-11-12 01:19:572763void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:472764#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:572765 // This is scheduled to run after we return to the message loop because
2766 // otherwise the frame will think the drag session is still active and ignore
2767 // the request.
[email protected]d6a3c772009-01-27 19:41:202768 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:372769 MessageLoop::current()->PostTask(
2770 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]d6a3c772009-01-27 19:41:202771#endif
initial.commit09911bf2008-07-26 23:55:292772}
2773
[email protected]3c9e1872010-11-18 16:17:492774void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:582775 // We don't create historical tabs for incognito windows or windows without
2776 // profiles.
[email protected]92371eb2011-04-28 11:50:152777 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:582778 return;
[email protected]92371eb2011-04-28 11:50:152779
[email protected]0d4ef7f2011-05-12 22:38:572780 // We don't create historical tabs for print preview tabs.
2781 if (contents->tab_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
2782 return;
2783
[email protected]92371eb2011-04-28 11:50:152784 TabRestoreService* service =
2785 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:582786
[email protected]fb5ff422010-05-03 20:46:102787 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:152788 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2789 service->CreateHistoricalTab(&contents->controller(),
[email protected]fb7da4132011-03-15 15:51:002790 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:582791 }
2792}
2793
[email protected]3c9e1872010-11-18 16:17:492794bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
2795 return Browser::RunUnloadEventsHelper(contents->tab_contents());
[email protected]505323e22009-01-24 02:47:582796}
2797
[email protected]8e48e982009-12-25 11:22:462798bool Browser::CanReloadContents(TabContents* source) const {
[email protected]b35b26b32011-05-05 20:35:142799 return !is_devtools();
[email protected]8e48e982009-12-25 11:22:462800}
2801
[email protected]2db5a2042011-04-26 17:13:472802bool Browser::CanCloseContents(std::vector<int>* indices) {
2803 DCHECK(!indices->empty());
2804 TabCloseableStateWatcher* watcher =
2805 g_browser_process->tab_closeable_state_watcher();
2806 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
2807 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:042808 return false;
[email protected]2db5a2042011-04-26 17:13:472809 // Now, handle cases where at least one tab can be closed.
2810 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:102811 // in-progress downloads.
2812 // Note that the next call when it returns false will ask the user for
2813 // confirmation before closing the browser if the user decides so.
[email protected]2db5a2042011-04-26 17:13:472814 if (tab_handler_->GetTabStripModel()->count() ==
2815 static_cast<int>(indices->size()) &&
2816 !CanCloseWithInProgressDownloads()) {
2817 indices->clear();
2818 can_close_all = false;
2819 }
2820 return can_close_all;
[email protected]940ccb22009-04-30 17:11:102821}
[email protected]d6a3c772009-01-27 19:41:202822
[email protected]a206b442009-10-08 23:20:202823bool Browser::CanBookmarkAllTabs() const {
2824 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:582825 return (model && model->IsLoaded()) &&
2826 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:042827 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:202828}
2829
[email protected]b3ac5c82009-10-08 20:56:542830void Browser::BookmarkAllTabs() {
[email protected]ec12ffe2009-10-16 22:28:442831 BookmarkModel* model = profile()->GetBookmarkModel();
2832 DCHECK(model && model->IsLoaded());
2833
2834 BookmarkEditor::EditDetails details;
2835 details.type = BookmarkEditor::EditDetails::NEW_FOLDER;
2836 bookmark_utils::GetURLsForOpenTabs(this, &(details.urls));
2837 DCHECK(!details.urls.empty());
[email protected]b3ac5c82009-10-08 20:56:542838
[email protected]b3ac5c82009-10-08 20:56:542839 BookmarkEditor::Show(window()->GetNativeHandle(), profile_,
[email protected]ec12ffe2009-10-16 22:28:442840 model->GetParentForNewNodes(), details,
[email protected]97a056462010-04-28 16:46:352841 BookmarkEditor::SHOW_TREE);
[email protected]b3ac5c82009-10-08 20:56:542842}
2843
[email protected]0b4d3382010-07-14 16:13:042844bool Browser::CanCloseTab() const {
2845 TabCloseableStateWatcher* watcher =
2846 g_browser_process->tab_closeable_state_watcher();
2847 return !watcher || watcher->CanCloseTab(this);
2848}
2849
[email protected]b9c505b2010-04-30 15:05:102850void Browser::ToggleUseVerticalTabs() {
2851 use_vertical_tabs_.SetValue(!UseVerticalTabs());
[email protected]b3344872010-05-03 15:52:292852 UseVerticalTabsChanged();
[email protected]b9c505b2010-04-30 15:05:102853}
2854
[email protected]ac86c982011-05-11 13:26:052855void Browser::ToggleUseCompactNavigationBar() {
2856 use_compact_navigation_bar_.SetValue(!UseCompactNavigationBar());
2857 UseCompactNavigationBarChanged();
2858}
2859
[email protected]b283a7532010-08-12 21:24:592860bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:442861 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
2862 // for those windows, we already have a big icon in the top-left outside any
2863 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:332864 return true;
[email protected]b283a7532010-08-12 21:24:592865}
2866
[email protected]2d46c842008-11-14 19:24:312867///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572868// Browser, TabStripModelObserver implementation:
2869
[email protected]3c9e1872010-11-18 16:17:492870void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572871 int index,
2872 bool foreground) {
[email protected]9219d262011-02-15 21:05:122873 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:002874 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:582875
[email protected]c37e3b62010-01-22 00:15:172876 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:572877
[email protected]159f7762008-12-19 14:58:272878 // Make sure the loading state is updated correctly, otherwise the throbber
2879 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492880 LoadingStateChanged(contents->tab_contents());
[email protected]159f7762008-12-19 14:58:272881
[email protected]36b6dcb2008-11-12 01:19:572882 // If the tab crashes in the beforeunload or unload handler, it won't be
2883 // able to ack. But we know we can close it.
[email protected]0cb94102009-05-22 19:51:212884 registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:052885 Source<TabContents>(contents->tab_contents()));
[email protected]93f230e02011-06-01 14:40:002886
2887 registrar_.Add(this, NotificationType::INTERSTITIAL_ATTACHED,
2888 Source<TabContents>(contents->tab_contents()));
[email protected]36b6dcb2008-11-12 01:19:572889}
2890
[email protected]f2cc7382010-10-15 18:03:052891void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:492892 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:052893 int index) {
[email protected]bfd04a62009-02-01 18:16:562894 NotificationService::current()->Notify(
2895 NotificationType::TAB_CLOSING,
[email protected]ce3fa3c2009-04-20 19:55:572896 Source<NavigationController>(&contents->controller()),
[email protected]bfd04a62009-02-01 18:16:562897 NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:572898
2899 // Sever the TabContents' connection back to us.
[email protected]9219d262011-02-15 21:05:122900 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:572901}
2902
[email protected]3c9e1872010-11-18 16:17:492903void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:172904 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:572905}
2906
[email protected]9ac8a242011-06-07 19:42:522907void Browser::TabDeactivated(TabContentsWrapper* contents) {
[email protected]6b723f82010-10-05 20:14:272908 if (instant())
2909 instant()->DestroyPreviewContents();
[email protected]03bb953d2010-09-14 21:38:302910
[email protected]85ff2c42009-05-29 21:22:032911 // Save what the user's currently typing, so it can be restored when we
2912 // switch back to this tab.
[email protected]3c9e1872010-11-18 16:17:492913 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]85ff2c42009-05-29 21:22:032914}
2915
[email protected]3aca95d42011-05-24 22:06:542916void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
2917 TabContentsWrapper* new_contents,
2918 int index,
2919 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:162920 // On some platforms we want to automatically reload tabs that are
2921 // killed when the user selects them.
2922 if (user_gesture && new_contents->tab_contents()->crashed_status() ==
2923 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
2924 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:562925 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]a8f024392011-01-13 21:50:162926 Reload(CURRENT_TAB);
[email protected]f8a35772011-02-02 23:17:562927 return;
2928 }
[email protected]a8f024392011-01-13 21:50:162929 }
2930
[email protected]36b6dcb2008-11-12 01:19:572931 // If we have any update pending, do it now.
2932 if (!chrome_updater_factory_.empty() && old_contents)
2933 ProcessPendingUIUpdates();
2934
[email protected]36b6dcb2008-11-12 01:19:572935 // Propagate the profile to the location bar.
2936 UpdateToolbar(true);
2937
[email protected]943d8122010-06-11 02:13:452938 // Update reload/stop state.
[email protected]3c9e1872010-11-18 16:17:492939 UpdateReloadStopState(new_contents->tab_contents()->is_loading(), true);
[email protected]36b6dcb2008-11-12 01:19:572940
[email protected]84214982008-12-10 18:49:102941 // Update commands to reflect current state.
2942 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:572943
2944 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:102945 StatusBubble* status_bubble = GetStatusBubble();
2946 if (status_bubble) {
2947 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:572948
[email protected]be3877f2009-01-14 15:51:102949 // Show the loading state (if any).
[email protected]0dd3a0ab2011-02-18 08:17:442950 status_bubble->SetStatus(GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:102951 }
[email protected]36b6dcb2008-11-12 01:19:572952
[email protected]24db8a072009-10-29 20:35:372953 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:242954 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:172955 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:582956 }
2957
[email protected]36b6dcb2008-11-12 01:19:572958 // Update sessions. Don't force creation of sessions. If sessions doesn't
2959 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:152960 SessionService* session_service =
2961 SessionServiceFactory::GetForProfileIfExisting(profile_);
2962 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
2963 session_service->SetSelectedTabInWindow(
2964 session_id(), tab_handler_->GetTabStripModel()->active_index());
[email protected]36b6dcb2008-11-12 01:19:572965 }
[email protected]09b29342011-06-24 19:18:482966
2967 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:572968}
2969
[email protected]3c9e1872010-11-18 16:17:492970void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572971 int from_index,
[email protected]1a242c32010-02-02 21:20:542972 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:572973 DCHECK(from_index >= 0 && to_index >= 0);
2974 // Notify the history service.
2975 SyncHistoryWithTabs(std::min(from_index, to_index));
2976}
2977
[email protected]da25dd52011-01-11 19:06:302978void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
2979 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:492980 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:432981 int index) {
[email protected]c37e3b62010-01-22 00:15:172982 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
2983 TabInsertedAt(new_contents, index,
[email protected]1ea49d52011-04-12 17:44:442984 (index == tab_handler_->GetTabStripModel()->active_index()));
[email protected]c37e3b62010-01-22 00:15:172985
2986 int entry_count = new_contents->controller().entry_count();
2987 if (entry_count > 0) {
2988 // Send out notification so that observers are updated appropriately.
2989 new_contents->controller().NotifyEntryChanged(
2990 new_contents->controller().GetEntryAtIndex(entry_count - 1),
2991 entry_count - 1);
2992 }
[email protected]47e020a2010-10-15 14:43:372993
[email protected]92371eb2011-04-28 11:50:152994 SessionService* session_service =
2995 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:372996 if (session_service) {
2997 // The new_contents may end up with a different navigation stack. Force
2998 // the session service to update itself.
2999 session_service->TabRestored(
[email protected]81898992011-06-14 22:15:003000 new_contents, tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373001 }
[email protected]2914600d2011-01-31 23:25:143002
3003 DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
3004 if (devtools_manager) // NULL in unit tests.
3005 devtools_manager->TabReplaced(old_contents, new_contents);
[email protected]c37e3b62010-01-22 00:15:173006}
3007
[email protected]3c9e1872010-11-18 16:17:493008void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153009 SessionService* session_service =
3010 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093011 if (session_service) {
3012 session_service->SetPinnedState(
3013 session_id(),
[email protected]81898992011-06-14 22:15:003014 GetTabContentsWrapperAt(index)->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:403015 tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093016 }
3017}
3018
[email protected]36b6dcb2008-11-12 01:19:573019void Browser::TabStripEmpty() {
3020 // Close the frame after we return to the message loop (not immediately,
3021 // otherwise it will destroy this object before the stack has a chance to
3022 // cleanly unwind.)
3023 // Note: This will be called several times if TabStripEmpty is called several
3024 // times. This is because it does not close the window if tabs are
3025 // still present.
3026 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3027 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373028 MessageLoop::current()->PostTask(
3029 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]36b6dcb2008-11-12 01:19:573030}
3031
3032///////////////////////////////////////////////////////////////////////////////
3033// Browser, TabContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293034
3035void Browser::OpenURLFromTab(TabContents* source,
[email protected]1f7d7e92009-06-02 20:55:043036 const GURL& url,
3037 const GURL& referrer,
initial.commit09911bf2008-07-26 23:55:293038 WindowOpenDisposition disposition,
[email protected]e38f40152008-09-12 23:08:303039 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:333040 browser::NavigateParams params(this, url, transition);
[email protected]3c9e1872010-11-18 16:17:493041 params.source_contents =
3042 tabstrip_model()->GetTabContentsAt(
3043 tabstrip_model()->GetWrapperIndex(source));
[email protected]616381f02010-11-02 15:15:333044 params.referrer = referrer;
3045 params.disposition = disposition;
3046 params.tabstrip_add_types = TabStripModel::ADD_NONE;
[email protected]7d329992011-04-15 18:20:023047 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:353048 params.user_gesture = true;
[email protected]616381f02010-11-02 15:15:333049 browser::Navigate(&params);
initial.commit09911bf2008-07-26 23:55:293050}
3051
3052void Browser::NavigationStateChanged(const TabContents* source,
3053 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293054 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403055 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293056 ScheduleUIUpdate(source, changed_flags);
3057
[email protected]84214982008-12-10 18:49:103058 // We don't schedule updates to commands since they will only change once per
3059 // navigation, so we don't have to worry about flickering.
[email protected]e83f1682008-09-07 23:57:403060 if (changed_flags & TabContents::INVALIDATE_URL)
[email protected]84214982008-12-10 18:49:103061 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293062}
3063
initial.commit09911bf2008-07-26 23:55:293064void Browser::AddNewContents(TabContents* source,
3065 TabContents* new_contents,
3066 WindowOpenDisposition disposition,
3067 const gfx::Rect& initial_pos,
3068 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373069 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333070 DCHECK(disposition != SAVE_TO_DISK);
3071 // Can't create a new contents for the current tab - invalid case.
3072 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293073
[email protected]e7cfdbd2011-04-22 14:41:373074 TabContentsWrapper* source_wrapper = NULL;
3075 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453076 TabContentsWrapper* new_wrapper =
3077 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
3078 if (!new_wrapper)
3079 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]e7cfdbd2011-04-22 14:41:373080 if (source) {
3081 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3082 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3083 }
3084
3085 if (source_wrapper) {
3086 // Handle blocking of all contents.
3087 if (source_blocked_content->all_contents_blocked()) {
3088 source_blocked_content->AddTabContents(new_wrapper,
3089 disposition,
3090 initial_pos,
3091 user_gesture);
3092 return;
3093 }
3094
3095 // Handle blocking of popups.
3096 if ((disposition == NEW_POPUP) && !user_gesture &&
3097 !CommandLine::ForCurrentProcess()->HasSwitch(
3098 switches::kDisablePopupBlocking)) {
3099 // Unrequested popups from normal pages are constrained unless they're in
3100 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363101 GetConstrainingContentsWrapper(source_wrapper)->
3102 blocked_content_tab_helper()->
3103 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373104 return;
3105 }
3106
[email protected]216813952011-05-19 22:21:263107 RenderViewHost* view = new_contents->render_view_host();
3108 view->Send(new ViewMsg_DisassociateFromPopupCount(view->routing_id()));
[email protected]e7cfdbd2011-04-22 14:41:373109 }
3110
[email protected]e7cfdbd2011-04-22 14:41:373111 browser::NavigateParams params(this, new_wrapper);
[email protected]3c9e1872010-11-18 16:17:493112 params.source_contents =
[email protected]e7cfdbd2011-04-22 14:41:373113 source ? tabstrip_model()->GetTabContentsAt(
3114 tabstrip_model()->GetWrapperIndex(source))
3115 : NULL;
[email protected]3c9e1872010-11-18 16:17:493116 params.disposition = disposition;
3117 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353118 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3119 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493120 browser::Navigate(&params);
[email protected]e7cfdbd2011-04-22 14:41:373121
3122 if (source) {
3123 NotificationService::current()->Notify(
3124 NotificationType::TAB_ADDED,
3125 Source<TabContentsDelegate>(source->delegate()),
3126 Details<TabContents>(source));
3127 }
initial.commit09911bf2008-07-26 23:55:293128}
3129
initial.commit09911bf2008-07-26 23:55:293130void Browser::ActivateContents(TabContents* contents) {
[email protected]eaca0ad12011-04-18 15:53:413131 tab_handler_->GetTabStripModel()->ActivateTabAt(
[email protected]3c9e1872010-11-18 16:17:493132 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393133 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293134}
3135
[email protected]ea42e7782010-08-23 23:58:123136void Browser::DeactivateContents(TabContents* contents) {
3137 window_->Deactivate();
3138}
3139
initial.commit09911bf2008-07-26 23:55:293140void Browser::LoadingStateChanged(TabContents* source) {
[email protected]ecc523f62010-09-28 22:45:403141 window_->UpdateLoadingAnimations(
3142 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393143 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293144
[email protected]3c9e1872010-11-18 16:17:493145 TabContents* selected_contents = GetSelectedTabContents();
3146 if (source == selected_contents) {
[email protected]943d8122010-06-11 02:13:453147 UpdateReloadStopState(source->is_loading(), false);
[email protected]43d259d2010-09-03 21:37:463148 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443149 GetStatusBubble()->SetStatus(
3150 GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463151 }
[email protected]eabfdae92009-12-11 06:13:513152
3153 if (!source->is_loading() &&
3154 pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333155 // Schedule a shortcut update when web application info is available if
3156 // last committed entry is not NULL. Last committed entry could be NULL
3157 // when an interstitial page is injected (e.g. bad https certificate,
3158 // malware site etc). When this happens, we abort the shortcut update.
[email protected]eabfdae92009-12-11 06:13:513159 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3160 if (entry) {
[email protected]553602e12011-04-05 17:01:183161 TabContentsWrapper::GetCurrentWrapperForContents(source)->
3162 extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]eabfdae92009-12-11 06:13:513163 } else {
3164 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513165 }
3166 }
initial.commit09911bf2008-07-26 23:55:293167 }
3168}
3169
3170void Browser::CloseContents(TabContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473171 if (is_attempting_to_close_browser_) {
3172 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063173 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473174 // will go down the slow shutdown path instead of the fast path of killing
3175 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213176 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473177 return;
3178 }
3179
[email protected]3c9e1872010-11-18 16:17:493180 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293181 if (index == TabStripModel::kNoTab) {
3182 NOTREACHED() << "CloseContents called for tab not in our strip";
3183 return;
3184 }
[email protected]ecc523f62010-09-28 22:45:403185 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:393186 index,
3187 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293188}
3189
[email protected]15e8abe2008-08-20 22:40:403190void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143191 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293192 NOTREACHED() << "moving invalid browser type";
3193 return;
3194 }
[email protected]e561e202010-03-24 17:57:123195 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293196}
3197
[email protected]b6c874582009-05-08 19:38:313198void Browser::DetachContents(TabContents* source) {
[email protected]3c9e1872010-11-18 16:17:493199 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313200 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:403201 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313202}
3203
[email protected]b35b26b32011-05-05 20:35:143204bool Browser::IsPopupOrPanel(const TabContents* source) const {
initial.commit09911bf2008-07-26 23:55:293205 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143206 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293207}
3208
[email protected]b8595e92009-11-14 01:18:003209void Browser::ContentsMouseEvent(
3210 TabContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:103211 if (!GetStatusBubble())
3212 return;
3213
[email protected]36b6dcb2008-11-12 01:19:573214 if (source == GetSelectedTabContents()) {
[email protected]b8595e92009-11-14 01:18:003215 GetStatusBubble()->MouseMoved(location, !motion);
3216 if (!motion)
[email protected]43d259d2010-09-03 21:37:463217 GetStatusBubble()->SetURL(GURL(), string16());
[email protected]36b6dcb2008-11-12 01:19:573218 }
3219}
3220
3221void Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
[email protected]be3877f2009-01-14 15:51:103222 if (!GetStatusBubble())
3223 return;
3224
[email protected]36b6dcb2008-11-12 01:19:573225 if (source == GetSelectedTabContents()) {
3226 PrefService* prefs = profile_->GetPrefs();
[email protected]ddd231e2010-06-29 20:35:193227 GetStatusBubble()->SetURL(
[email protected]43d259d2010-09-03 21:37:463228 url, UTF8ToUTF16(prefs->GetString(prefs::kAcceptLanguages)));
[email protected]36b6dcb2008-11-12 01:19:573229 }
3230}
3231
[email protected]3a6a3b62009-05-27 21:36:203232void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:233233 if (GetStatusBubble())
3234 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:203235}
3236
[email protected]aa02fff12010-07-21 19:55:253237bool Browser::UseVerticalTabs() const {
3238 return use_vertical_tabs_.GetValue();
3239}
3240
[email protected]ac86c982011-05-11 13:26:053241bool Browser::UseCompactNavigationBar() const {
3242 return use_compact_navigation_bar_.GetValue();
3243}
3244
[email protected]36b6dcb2008-11-12 01:19:573245void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253246 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573247}
3248
[email protected]fa1cf0b82010-01-15 21:49:443249void Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
[email protected]3c9e1872010-11-18 16:17:493250 int index = tabstrip_model()->GetWrapperIndex(contents);
[email protected]fa1cf0b82010-01-15 21:49:443251 if (index == TabStripModel::kNoTab) {
3252 NOTREACHED();
3253 return;
3254 }
3255 tabstrip_model()->SetTabBlocked(index, blocked);
3256}
3257
[email protected]7e383692009-06-12 19:14:543258void Browser::TabContentsFocused(TabContents* tab_content) {
3259 window_->TabContentsFocused(tab_content);
3260}
3261
[email protected]130efb02009-09-18 18:54:353262bool Browser::TakeFocus(bool reverse) {
3263 NotificationService::current()->Notify(
3264 NotificationType::FOCUS_RETURNED_TO_BROWSER,
3265 Source<Browser>(this),
3266 NotificationService::NoDetails());
3267 return false;
3268}
3269
[email protected]36b6dcb2008-11-12 01:19:573270bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143271 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573272}
3273
3274void Browser::ConvertContentsToApplication(TabContents* contents) {
[email protected]ce3fa3c2009-04-20 19:55:573275 const GURL& url = contents->controller().GetActiveEntry()->url();
[email protected]57ecc4b2010-08-11 03:02:513276 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573277
[email protected]b6c874582009-05-08 19:38:313278 DetachContents(contents);
[email protected]94ce7252010-12-20 21:46:333279 Browser* app_browser = Browser::CreateForApp(
[email protected]5c209242011-06-06 20:36:173280 TYPE_POPUP, app_name, gfx::Rect(), profile_);
[email protected]ae2f2a772011-05-04 16:30:273281 TabContentsWrapper* wrapper =
3282 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3283 if (!wrapper)
3284 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323285 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3286
3287 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
3288 contents->render_view_host()->SyncRendererPrefs();
3289 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573290}
3291
[email protected]36b6dcb2008-11-12 01:19:573292void Browser::BeforeUnloadFired(TabContents* tab,
3293 bool proceed,
3294 bool* proceed_to_fire_unload) {
3295 if (!is_attempting_to_close_browser_) {
3296 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393297 if (!proceed)
3298 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573299 return;
3300 }
3301
3302 if (!proceed) {
3303 CancelWindowClose();
3304 *proceed_to_fire_unload = false;
[email protected]0cce15f2010-05-21 16:58:393305 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573306 return;
3307 }
3308
[email protected]06b42f032008-12-03 18:43:053309 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313310 // Now that beforeunload has fired, put the tab on the queue to fire
3311 // unload.
[email protected]06b42f032008-12-03 18:43:053312 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573313 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063314 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573315 // fire all the beforeunload events before attempting to fire the unload
3316 // events should the user cancel closing the browser.
3317 *proceed_to_fire_unload = false;
3318 return;
3319 }
3320
3321 *proceed_to_fire_unload = true;
3322}
3323
[email protected]a26dc362010-04-23 01:48:583324void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133325 // Two differences between this and FocusLocationBar():
3326 // (1) This doesn't get recorded in user metrics, since it's called
3327 // internally.
3328 // (2) This checks whether the location bar can be focused, and if not, clears
3329 // the focus. FocusLocationBar() is only reached when the location bar is
3330 // focusable, but this may be reached at other times, e.g. while in
3331 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583332 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573333}
3334
[email protected]7d5925a2009-03-03 02:59:123335void Browser::RenderWidgetShowing() {
3336 window_->DisableInactiveFrame();
3337}
[email protected]a239c3f2009-02-17 22:13:193338
[email protected]0a2aeb82009-05-15 21:52:483339int Browser::GetExtraRenderViewHeight() const {
3340 return window_->GetExtraRenderViewHeight();
3341}
3342
[email protected]bb678332009-07-21 00:15:503343void Browser::ShowPageInfo(Profile* profile,
[email protected]4d677202009-07-19 07:37:123344 const GURL& url,
3345 const NavigationEntry::SSLStatus& ssl,
3346 bool show_history) {
[email protected]bb678332009-07-21 00:15:503347 window()->ShowPageInfo(profile, url, ssl, show_history);
[email protected]4d677202009-07-19 07:37:123348}
3349
[email protected]1788e772010-12-15 16:40:503350void Browser::ViewSourceForTab(TabContents* source, const GURL& page_url) {
3351 DCHECK(source);
3352 int index = tabstrip_model()->GetWrapperIndex(source);
[email protected]77d8d622010-12-15 10:30:123353 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3354 ViewSource(wrapper);
3355}
3356
[email protected]932b7a12011-03-09 12:50:273357void Browser::ViewSourceForFrame(TabContents* source,
3358 const GURL& frame_url,
3359 const std::string& frame_content_state) {
3360 DCHECK(source);
3361 int index = tabstrip_model()->GetWrapperIndex(source);
3362 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3363 ViewSource(wrapper, frame_url, frame_content_state);
3364}
3365
[email protected]867125a02009-12-10 06:01:483366bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3367 bool* is_keyboard_shortcut) {
3368 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3369}
[email protected]97df4b332009-10-02 01:25:413370
[email protected]867125a02009-12-10 06:01:483371void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3372 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413373}
3374
[email protected]14f3408a2009-08-31 20:53:533375void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
3376 window()->ShowRepostFormWarningDialog(tab_contents);
3377}
3378
[email protected]579e3192011-03-11 22:37:453379void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
[email protected]445177652011-03-09 02:04:053380 ShowOptionsTab(
3381 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
3382 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
[email protected]63543142010-02-09 23:22:203383}
3384
[email protected]a503c97c2010-07-16 13:05:483385void Browser::ShowCollectedCookiesDialog(TabContents *tab_contents) {
3386 window()->ShowCollectedCookiesDialog(tab_contents);
3387}
3388
[email protected]ec0b6c42010-08-26 03:16:583389bool Browser::ShouldAddNavigationToHistory(
3390 const history::HistoryAddPageArgs& add_page_args,
3391 NavigationType::Type navigation_type) {
[email protected]2e29d922009-10-22 22:13:353392 // Don't update history if running as app.
3393 return !IsApplication();
3394}
3395
[email protected]9e823662010-10-13 23:36:003396void Browser::ContentRestrictionsChanged(TabContents* source) {
3397 UpdateCommandsForContentRestrictionState();
3398}
3399
[email protected]55452902011-06-01 21:57:473400void Browser::RendererUnresponsive(TabContents* source) {
3401 browser::ShowHungRendererDialog(source);
3402}
3403
3404void Browser::RendererResponsive(TabContents* source) {
3405 browser::HideHungRendererDialog(source);
3406}
3407
3408void Browser::WorkerCrashed(TabContents* source) {
3409 TabContentsWrapper* wrapper =
3410 TabContentsWrapper::GetCurrentWrapperForContents(source);
3411 wrapper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3412 source, NULL, l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
3413 true));
[email protected]0dd3a0ab2011-02-18 08:17:443414}
3415
[email protected]09b29342011-06-24 19:18:483416void Browser::DidNavigateMainFramePostCommit(TabContents* tab) {
3417 if (tab == GetSelectedTabContents())
3418 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003419}
3420
[email protected]09b29342011-06-24 19:18:483421void Browser::DidNavigateToPendingEntry(TabContents* tab) {
3422 if (tab == GetSelectedTabContents())
3423 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003424}
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,
[email protected]8e5c89a2011-06-07 18:13:333477 TemplateURLService* template_url_service) {
[email protected]9219d262011-02-15 21:05:123478 window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
[email protected]8e5c89a2011-06-07 18:13:333479 template_url_service);
[email protected]9219d262011-02-15 21:05:123480}
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]e1581e32011-06-09 15:18:023674 } else if (pref_name == prefs::kIncognitoEnabled) {
3675 command_updater_.UpdateCommandEnabled(
3676 IDC_NEW_INCOGNITO_WINDOW,
3677 profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled));
[email protected]543432ee2010-10-22 16:32:133678 } else if (pref_name == prefs::kDevToolsDisabled) {
3679 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:043680 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]543432ee2010-10-22 16:32:133681 g_browser_process->devtools_manager()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:583682 } else if (pref_name == prefs::kEditBookmarksEnabled) {
3683 UpdateCommandsForBookmarkEditing();
[email protected]97b46382011-05-02 13:23:043684 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
3685 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
3686 UpdateOpenFileState();
[email protected]2a7e7c152010-10-01 20:12:093687 } else {
[email protected]b9c505b2010-04-30 15:05:103688 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:093689 }
[email protected]b9c505b2010-04-30 15:05:103690 break;
3691 }
3692
[email protected]9a9a9e22011-05-13 22:20:353693 case NotificationType::TAB_CONTENT_SETTINGS_CHANGED: {
3694 TabContents* tab_contents = Source<TabContents>(source).ptr();
3695 if (tab_contents == GetSelectedTabContents()) {
3696 LocationBar* location_bar = window()->GetLocationBar();
3697 if (location_bar)
3698 location_bar->UpdateContentSettingsIcons();
3699 }
3700 break;
3701 }
3702
[email protected]93f230e02011-06-01 14:40:003703 case NotificationType::INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:483704 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
3705 break;
3706
3707 case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED:
3708 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]93f230e02011-06-01 14:40:003709 break;
3710
[email protected]e83f1682008-09-07 23:57:403711 default:
3712 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:293713 }
3714}
3715
[email protected]d3b98c82010-07-14 07:45:593716///////////////////////////////////////////////////////////////////////////////
3717// Browser, ProfileSyncServiceObserver implementation:
3718
3719void Browser::OnStateChanged() {
3720 DCHECK(profile_->GetProfileSyncService());
3721
3722#if !defined(OS_MACOSX)
[email protected]b35b26b32011-05-05 20:35:143723 const bool show_main_ui = is_type_tabbed() && !window_->IsFullscreen();
[email protected]d3b98c82010-07-14 07:45:593724#else
[email protected]b35b26b32011-05-05 20:35:143725 const bool show_main_ui = is_type_tabbed();
[email protected]d3b98c82010-07-14 07:45:593726#endif
3727
3728 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
3729 show_main_ui && profile_->IsSyncAccessible());
3730}
[email protected]88d74942009-01-21 22:04:443731
[email protected]36b6dcb2008-11-12 01:19:573732///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:273733// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:303734
[email protected]36d5e5592010-11-15 20:45:593735void Browser::PrepareForInstant() {
3736 window_->PrepareForInstant();
3737}
3738
[email protected]3c9e1872010-11-18 16:17:493739void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
3740 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:143741 window_->ShowInstant(preview_contents);
[email protected]03bb953d2010-09-14 21:38:303742}
3743
[email protected]6b723f82010-10-05 20:14:273744void Browser::HideInstant() {
[email protected]1946c932010-12-15 00:07:383745 window_->HideInstant(instant_->is_active());
[email protected]03bb953d2010-09-14 21:38:303746}
3747
[email protected]3c9e1872010-11-18 16:17:493748void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
3749 TabContentsWrapper* tab_contents = instant_->tab_contents();
3750 int index =
3751 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
3752 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:303753 // TabStripModel takes ownership of preview_contents.
[email protected]43032342011-03-21 14:10:313754 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
3755 index, preview_contents);
3756 // InstantUnloadHandler takes ownership of tab_contents.
3757 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:333758
3759 GURL url = preview_contents->tab_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:523760 DCHECK(profile_->GetExtensionService());
3761 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:333762 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
3763 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
3764 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
3765 }
[email protected]03bb953d2010-09-14 21:38:303766}
3767
[email protected]c98fd5d82011-05-04 15:20:093768void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
3769 TabContentsWrapper* new_tab_contents) {
3770 int index =
3771 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(old_tab_contents);
[email protected]71b5d242011-04-30 02:27:203772 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]c98fd5d82011-05-04 15:20:093773 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(index,
3774 new_tab_contents);
[email protected]71b5d242011-04-30 02:27:203775}
3776
[email protected]33b8b8e2011-03-15 14:51:553777void Browser::SetSuggestedText(const string16& text,
3778 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:363779 if (window()->GetLocationBar())
3780 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:303781}
3782
[email protected]6b723f82010-10-05 20:14:273783gfx::Rect Browser::GetInstantBounds() {
3784 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:473785}
3786
[email protected]03bb953d2010-09-14 21:38:303787///////////////////////////////////////////////////////////////////////////////
[email protected]9800de5e2011-03-11 18:19:493788// Browser, protected:
3789
3790BrowserWindow* Browser::CreateBrowserWindow() {
[email protected]b35b26b32011-05-05 20:35:143791 if (type_ == TYPE_PANEL &&
[email protected]011396a2011-04-13 23:35:283792 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels))
3793 return PanelManager::GetInstance()->CreatePanel(this);
3794
[email protected]9800de5e2011-03-11 18:19:493795 return BrowserWindow::CreateBrowserWindow(this);
3796}
3797
3798
3799///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573800// Browser, Command and state updating (private):
3801
3802void Browser::InitCommandState() {
3803 // All browser commands whose state isn't set automagically some other way
3804 // (like Back & Forward with initial page load) must have their state
3805 // initialized here, otherwise they will be forever disabled.
3806
[email protected]84214982008-12-10 18:49:103807 // Navigation commands
[email protected]1fc025202009-01-20 23:03:143808 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:163809 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:103810
3811 // Window management commands
[email protected]1fc025202009-01-20 23:03:143812 command_updater_.UpdateCommandEnabled(IDC_NEW_WINDOW, true);
[email protected]97b46382011-05-02 13:23:043813 command_updater_.UpdateCommandEnabled(
3814 IDC_NEW_INCOGNITO_WINDOW,
3815 profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled));
[email protected]1fc025202009-01-20 23:03:143816 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
3817 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
3818 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
3819 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:133820 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:143821 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]c8b59f92010-05-28 21:45:473822 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
[email protected]cdc05ec2011-05-18 15:15:593823 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:103824
3825 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:513826 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:143827 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
3828 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
3829 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
3830 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
3831 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
3832 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
3833 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
3834 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
3835 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
3836 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
3837 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
3838 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
3839 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
3840 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
3841 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
3842 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
3843 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
3844 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
3845 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
3846 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
3847 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
3848 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
3849 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
3850 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
3851 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
3852 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
3853 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
3854 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
3855 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
3856 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
3857 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
3858 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
3859 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
3860 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
3861 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:003862 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:143863 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
3864 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:103865
[email protected]63b02932009-06-05 09:40:513866 // Zoom
3867 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
3868 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
3869 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
3870 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
3871
[email protected]84214982008-12-10 18:49:103872 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:043873 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:143874 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:133875 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:143876 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:143877 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]4a4180a52010-08-23 06:39:483878 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER,
3879 browser_defaults::bookmarks_enabled);
[email protected]1fc025202009-01-20 23:03:143880 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
3881 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]4aee5652009-11-19 18:59:213882 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true);
[email protected]d6852fd2011-05-20 17:19:123883 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:293884
[email protected]96e34672010-02-09 21:40:293885#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:053886 command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
[email protected]f97d7f632010-06-01 21:08:333887 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:503888 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:473889 command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
3890 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:293891#endif
[email protected]c8b59f92010-05-28 21:45:473892
[email protected]14908b72011-04-20 06:54:363893 ExtensionService* extension_service = profile()->GetExtensionService();
[email protected]9cd51a02009-10-23 22:30:293894 bool enable_extensions =
[email protected]14908b72011-04-20 06:54:363895 extension_service && extension_service->extensions_enabled();
[email protected]9cd51a02009-10-23 22:30:293896 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
3897 enable_extensions);
3898
[email protected]64ff7942008-12-17 18:11:233899 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:143900 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:233901
[email protected]11f4857282009-11-13 19:56:173902 // Navigation commands
3903 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:233904
[email protected]11f4857282009-11-13 19:56:173905 // Window management commands
[email protected]cf299bc2010-08-12 20:27:093906 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:143907 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:173908 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
3909 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
3910 normal_window);
3911 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
3912 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
3913 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
3914 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
3915 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
3916 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
3917 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
3918 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
3919 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
3920 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
3921 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:553922#if defined(OS_MACOSX)
3923 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
3924#endif
[email protected]e662ade2009-06-08 18:20:143925
[email protected]fc33e9992010-04-08 19:40:133926 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:143927 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:133928
3929 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:143930 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
3931 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
3932 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:133933
[email protected]663bd9e2011-03-21 01:07:013934 // Autofill
[email protected]b35b26b32011-05-05 20:35:143935 command_updater_.UpdateCommandEnabled(IDC_AUTOFILL_DEFAULT, !is_devtools());
[email protected]cf28ec52010-04-09 22:56:343936
[email protected]11f4857282009-11-13 19:56:173937 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:133938 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:003939
[email protected]c1bbaa82010-11-08 11:17:053940 // The upgrade entry and the view incompatibility entry should always be
3941 // enabled. Whether they are visible is a separate matter determined on menu
3942 // show.
[email protected]b21d6912010-08-31 19:22:413943 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:053944 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:413945
[email protected]b569c112010-11-22 20:53:443946 // View Background Pages entry is always enabled, but is hidden if there are
3947 // no background pages.
3948 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
3949
[email protected]9282cea2009-02-18 18:49:003950 // Initialize other commands whose state changes based on fullscreen mode.
3951 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:003952
3953 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:583954
3955 UpdateCommandsForBookmarkEditing();
[email protected]36b6dcb2008-11-12 01:19:573956}
3957
[email protected]84214982008-12-10 18:49:103958void Browser::UpdateCommandsForTabState() {
[email protected]c7c42332008-11-15 01:10:543959 TabContents* current_tab = GetSelectedTabContents();
[email protected]a0366a52011-02-04 20:04:213960 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
3961 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:393962 return;
[email protected]d8375fd2008-11-25 22:45:393963
[email protected]84214982008-12-10 18:49:103964 // Navigation commands
[email protected]ce3fa3c2009-04-20 19:55:573965 NavigationController& nc = current_tab->controller();
3966 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
3967 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:133968 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
3969 CanReloadContents(current_tab));
3970 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
3971 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:293972
[email protected]84214982008-12-10 18:49:103973 // Window management commands
[email protected]1fc025202009-01-20 23:03:143974 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:143975 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:103976
[email protected]57c6a652009-05-04 07:58:343977 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:383978 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:143979 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:343980 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]31682282010-01-15 18:05:163981 current_tab->controller().CanViewSource());
[email protected]151666e2010-10-21 17:05:253982 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
3983 current_tab->ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:403984 if (is_devtools())
3985 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:253986
3987 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]4d07cdc2009-08-22 16:09:393988 // Instead of using GetURL here, we use url() (which is the "real" url of the
3989 // page) from the NavigationEntry because its reflects their origin rather
3990 // than the display one (returned by GetURL) which may be different (like
3991 // having "view-source:" on the front).
[email protected]fc33e9992010-04-08 19:40:133992 NavigationEntry* active_entry = nc.GetActiveEntry();
[email protected]c0f82ec52010-07-27 14:22:143993 bool is_chrome_internal = (active_entry ?
3994 active_entry->url().SchemeIs(chrome::kChromeUIScheme) : false);
3995 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
3996 !is_chrome_internal && SavePackage::IsSavableContents(
3997 current_tab->contents_mime_type()));
3998
[email protected]57c6a652009-05-04 07:58:343999 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254000 // TODO(pinkerton): Disable app-mode in the model until we implement it
4001 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4002#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344003 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234004 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:254005#endif
[email protected]9e823662010-10-13 23:36:004006
4007 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584008 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004009}
4010
4011void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374012 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004013
4014 command_updater_.UpdateCommandEnabled(
4015 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
4016 command_updater_.UpdateCommandEnabled(
4017 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
4018 command_updater_.UpdateCommandEnabled(
4019 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044020 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004021 UpdatePrintingState(restrictions);
4022}
4023
4024void Browser::UpdatePrintingState(int content_restrictions) {
4025 bool enabled = true;
4026 if (content_restrictions & CONTENT_RESTRICTION_PRINT) {
4027 enabled = false;
4028 } else if (g_browser_process->local_state()) {
[email protected]97b46382011-05-02 13:23:044029 enabled = g_browser_process->local_state()->
4030 GetBoolean(prefs::kPrintingEnabled);
[email protected]9e823662010-10-13 23:36:004031 }
4032 command_updater_.UpdateCommandEnabled(IDC_PRINT, enabled);
initial.commit09911bf2008-07-26 23:55:294033}
4034
[email protected]943d8122010-06-11 02:13:454035void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4036 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:144037 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:234038}
4039
[email protected]543432ee2010-10-22 16:32:134040void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044041 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424042 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134043 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4044 dev_tools_enabled);
4045 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4046 dev_tools_enabled);
4047 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4048 dev_tools_enabled);
4049}
4050
[email protected]a13f47d12011-04-14 11:41:584051void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044052 bool enabled =
4053 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4054 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584055
4056 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144057 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584058 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4059 enabled && CanBookmarkAllTabs());
4060}
4061
[email protected]97b46382011-05-02 13:23:044062void Browser::UpdateSaveAsState(int content_restrictions) {
4063 bool enabled = !(content_restrictions & CONTENT_RESTRICTION_SAVE);
4064 PrefService* state = g_browser_process->local_state();
4065 if (state)
4066 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4067
4068 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4069}
4070
4071void Browser::UpdateOpenFileState() {
4072 bool enabled = true;
4073 PrefService* local_state = g_browser_process->local_state();
4074 if (local_state)
4075 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4076
4077 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4078}
4079
[email protected]36b6dcb2008-11-12 01:19:574080///////////////////////////////////////////////////////////////////////////////
4081// Browser, UI update coalescing and handling (private):
4082
4083void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:494084 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294085}
4086
[email protected]36b6dcb2008-11-12 01:19:574087void Browser::ScheduleUIUpdate(const TabContents* source,
4088 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004089 if (!source)
4090 return;
4091
[email protected]2b4355c2009-04-04 17:55:464092 // Do some synchronous updates.
[email protected]36b6dcb2008-11-12 01:19:574093 if (changed_flags & TabContents::INVALIDATE_URL &&
4094 source == GetSelectedTabContents()) {
4095 // Only update the URL for the current tab. Note that we do not update
4096 // the navigation commands since those would have already been updated
4097 // synchronously by NavigationStateChanged.
4098 UpdateToolbar(false);
[email protected]8030f012009-09-25 18:09:374099 changed_flags &= ~TabContents::INVALIDATE_URL;
[email protected]36b6dcb2008-11-12 01:19:574100 }
[email protected]a5231662009-09-26 00:56:004101 if (changed_flags & TabContents::INVALIDATE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574102 // Update the loading state synchronously. This is so the throbber will
4103 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004104 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:404105 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4106 tab_handler_->GetTabStripModel()->GetIndexOfController(
4107 &source->controller()),
[email protected]6ebdc9b2010-09-27 16:55:574108 TabStripModelObserver::LOADING_ONLY);
4109 // The status bubble needs to be updated during INVALIDATE_LOAD too, but
4110 // we do that asynchronously by not stripping INVALIDATE_LOAD from
4111 // changed_flags.
[email protected]8030f012009-09-25 18:09:374112 }
4113
[email protected]f1cd5e82009-10-23 17:19:034114 if (changed_flags & TabContents::INVALIDATE_TITLE && !source->is_loading()) {
4115 // To correctly calculate whether the title changed while not loading
4116 // we need to process the update synchronously. This state only matters for
4117 // the TabStripModel, so we notify the TabStripModel now and notify others
4118 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:404119 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4120 tab_handler_->GetTabStripModel()->GetIndexOfController(
4121 &source->controller()),
[email protected]f1cd5e82009-10-23 17:19:034122 TabStripModelObserver::TITLE_NOT_LOADING);
4123 }
4124
[email protected]2b4355c2009-04-04 17:55:464125 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374126 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464127 return;
[email protected]36b6dcb2008-11-12 01:19:574128
4129 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404130 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574131
4132 if (chrome_updater_factory_.empty()) {
4133 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374134 MessageLoop::current()->PostDelayedTask(
4135 FROM_HERE,
[email protected]36b6dcb2008-11-12 01:19:574136 chrome_updater_factory_.NewRunnableMethod(
4137 &Browser::ProcessPendingUIUpdates),
[email protected]6ebdc9b2010-09-27 16:55:574138 kUIUpdateCoalescingTimeMS);
[email protected]36b6dcb2008-11-12 01:19:574139 }
4140}
4141
4142void Browser::ProcessPendingUIUpdates() {
4143#ifndef NDEBUG
4144 // Validate that all tabs we have pending updates for exist. This is scary
4145 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004146 // deleted tabs.
[email protected]85354982009-09-25 19:58:404147 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4148 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574149 bool found = false;
4150 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]a5231662009-09-26 00:56:004151 if (GetTabContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574152 found = true;
4153 break;
4154 }
4155 }
4156 DCHECK(found);
4157 }
4158#endif
4159
4160 chrome_updater_factory_.RevokeAll();
4161
[email protected]85354982009-09-25 19:58:404162 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4163 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574164 // Do not dereference |contents|, it may be out-of-date!
[email protected]85354982009-09-25 19:58:404165 const TabContents* contents = i->first;
4166 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574167
[email protected]a5231662009-09-26 00:56:004168 if (contents == GetSelectedTabContents()) {
4169 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344170
[email protected]9800de5e2011-03-11 18:19:494171 if (flags & TabContents::INVALIDATE_PAGE_ACTIONS) {
4172 LocationBar* location_bar = window()->GetLocationBar();
4173 if (location_bar)
4174 location_bar->UpdatePageActions();
4175 }
[email protected]6ebdc9b2010-09-27 16:55:574176 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]0dd3a0ab2011-02-18 08:17:444177 if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) {
4178 GetStatusBubble()->SetStatus(
4179 GetSelectedTabContentsWrapper()->GetStatusText());
4180 }
[email protected]a5231662009-09-26 00:56:004181
[email protected]f1cd5e82009-10-23 17:19:034182 if (flags & (TabContents::INVALIDATE_TAB |
4183 TabContents::INVALIDATE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254184// TODO(pinkerton): Disable app-mode in the model until we implement it
4185// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4186#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004187 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234188 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254189#endif
[email protected]a5231662009-09-26 00:56:004190 window_->UpdateTitleBar();
4191 }
[email protected]4d34e2e2009-05-26 22:55:284192 }
[email protected]36b6dcb2008-11-12 01:19:574193
[email protected]a5231662009-09-26 00:56:004194 // Updates that don't depend upon the selected state go here.
[email protected]f1cd5e82009-10-23 17:19:034195 if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:404196 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:494197 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034198 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574199 }
4200
4201 // We don't need to process INVALIDATE_STATE, since that's not visible.
4202 }
4203
4204 scheduled_updates_.clear();
4205}
4206
4207void Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
4208 if (!contents)
4209 return;
4210
[email protected]85354982009-09-25 19:58:404211 UpdateMap::iterator i = scheduled_updates_.find(contents);
4212 if (i != scheduled_updates_.end())
4213 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294214}
4215
[email protected]d938aed92009-01-22 19:49:334216
[email protected]36b6dcb2008-11-12 01:19:574217///////////////////////////////////////////////////////////////////////////////
4218// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294219
[email protected]36b6dcb2008-11-12 01:19:574220StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094221#if !defined(OS_MACOSX)
4222 // In kiosk mode, we want to always hide the status bubble.
4223 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4224 return NULL;
4225#endif
[email protected]9b032bf2009-07-21 17:34:234226 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294227}
4228
[email protected]36b6dcb2008-11-12 01:19:574229///////////////////////////////////////////////////////////////////////////////
4230// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294231
4232void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154233 SessionService* session_service =
4234 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294235 if (session_service) {
4236 for (int i = index; i < tab_count(); ++i) {
[email protected]81898992011-06-14 22:15:004237 TabContentsWrapper* tab = GetTabContentsWrapperAt(i);
4238 if (tab) {
initial.commit09911bf2008-07-26 23:55:294239 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:004240 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404241 session_service->SetPinnedState(
4242 session_id(),
[email protected]81898992011-06-14 22:15:004243 tab->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:404244 tab_handler_->GetTabStripModel()->IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294245 }
4246 }
4247 }
4248}
4249
[email protected]36b6dcb2008-11-12 01:19:574250///////////////////////////////////////////////////////////////////////////////
4251// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294252
[email protected]04b4a6c2008-08-02 00:44:474253void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214254 if (!is_attempting_to_close_browser_) {
4255 // Because we might invoke this after a delay it's possible for the value of
4256 // is_attempting_to_close_browser_ to have changed since we scheduled the
4257 // task.
4258 return;
4259 }
initial.commit09911bf2008-07-26 23:55:294260
[email protected]04b4a6c2008-08-02 00:44:474261 if (HasCompletedUnloadProcessing()) {
4262 // We've finished all the unload events and can proceed to close the
4263 // browser.
4264 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294265 return;
4266 }
4267
[email protected]04b4a6c2008-08-02 00:44:474268 // Process beforeunload tabs first. When that queue is empty, process
4269 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474270 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]06b42f032008-12-03 18:43:054271 TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244272 // Null check render_view_host here as this gets called on a PostTask and
4273 // the tab's render_view_host may have been nulled out.
4274 if (tab->render_view_host()) {
[email protected]ae23c272009-07-27 20:15:404275 tab->render_view_host()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244276 } else {
[email protected]08f0d612011-01-13 23:58:214277 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244278 }
[email protected]04b4a6c2008-08-02 00:44:474279 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294280 // We've finished firing all beforeunload events and can proceed with unload
4281 // events.
4282 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4283 // somewhere around here so that we have accurate measurements of shutdown
4284 // time.
[email protected]04b4a6c2008-08-02 00:44:474285 // TODO(ojan): We can probably fire all the unload events in parallel and
4286 // get a perf benefit from that in the cases where the tab hangs in it's
4287 // unload handler or takes a long time to page in.
[email protected]06b42f032008-12-03 18:43:054288 TabContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244289 // Null check render_view_host here as this gets called on a PostTask and
4290 // the tab's render_view_host may have been nulled out.
4291 if (tab->render_view_host()) {
[email protected]992db4c2011-05-12 15:37:154292 tab->render_view_host()->ClosePage();
[email protected]22484622009-06-10 21:17:244293 } else {
[email protected]08f0d612011-01-13 23:58:214294 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244295 }
initial.commit09911bf2008-07-26 23:55:294296 } else {
[email protected]04b4a6c2008-08-02 00:44:474297 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294298 }
4299}
4300
[email protected]d043c2cc2009-03-25 18:30:454301bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474302 return is_attempting_to_close_browser_ &&
4303 tabs_needing_before_unload_fired_.empty() &&
4304 tabs_needing_unload_fired_.empty();
4305}
4306
4307void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044308 // Closing of window can be canceled from:
4309 // - canceling beforeunload
4310 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474311 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284312 tabs_needing_before_unload_fired_.clear();
4313 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474314 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044315
4316 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4317 TabCloseableStateWatcher* watcher =
4318 g_browser_process->tab_closeable_state_watcher();
4319 if (watcher)
4320 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474321}
4322
[email protected]06b42f032008-12-03 18:43:054323bool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474324 DCHECK(is_attempting_to_close_browser_);
4325
[email protected]06b42f032008-12-03 18:43:054326 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4327 if (iter != set->end()) {
4328 set->erase(iter);
4329 return true;
[email protected]04b4a6c2008-08-02 00:44:474330 }
4331 return false;
4332}
initial.commit09911bf2008-07-26 23:55:294333
[email protected]08f0d612011-01-13 23:58:214334void Browser::ClearUnloadState(TabContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044335 // Closing of browser could be canceled (via IsClosingPermitted) between the
4336 // time when request was initiated and when this method is called, so check
4337 // for is_attempting_to_close_browser_ flag before proceeding.
4338 if (is_attempting_to_close_browser_) {
4339 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4340 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:214341 if (process_now) {
4342 ProcessPendingTabs();
4343 } else {
4344 MessageLoop::current()->PostTask(
4345 FROM_HERE,
4346 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
4347 }
[email protected]0b4d3382010-07-14 16:13:044348 }
initial.commit09911bf2008-07-26 23:55:294349}
4350
[email protected]36b6dcb2008-11-12 01:19:574351///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:064352// Browser, In-progress download termination handling (private):
4353
[email protected]460a2942010-12-15 19:43:154354void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present,
4355 bool* incognito_downloads_are_present) {
4356 *normal_downloads_are_present = false;
4357 *incognito_downloads_are_present = false;
4358
4359 // If there are no download in-progress, our job is done.
4360 DownloadManager* download_manager = NULL;
[email protected]803e4c82011-06-21 21:04:284361 // But first we need to check for the existence of the download manager, as
[email protected]460a2942010-12-15 19:43:154362 // GetDownloadManager() will unnecessarily try to create one if it does not
4363 // exist.
4364 if (profile()->HasCreatedDownloadManager())
4365 download_manager = profile()->GetDownloadManager();
4366 if (profile()->IsOffTheRecord()) {
4367 // Browser is incognito and so download_manager if present is for incognito
4368 // downloads.
4369 *incognito_downloads_are_present =
4370 (download_manager && download_manager->in_progress_count() != 0);
4371 // Check original profile.
4372 if (profile()->GetOriginalProfile()->HasCreatedDownloadManager())
4373 download_manager = profile()->GetOriginalProfile()->GetDownloadManager();
4374 }
4375
4376 *normal_downloads_are_present =
4377 (download_manager && download_manager->in_progress_count() != 0);
4378}
4379
[email protected]69444cc2009-04-09 20:40:064380bool Browser::CanCloseWithInProgressDownloads() {
4381 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
[email protected]7a22201c2009-10-16 16:50:374382 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
4383 // We need to hear from the user before we can close.
4384 return false;
4385 }
4386 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
[email protected]69444cc2009-04-09 20:40:064387 return true;
4388 }
[email protected]446295a2010-04-19 23:43:004389 // Indicated that normal (non-incognito) downloads are pending.
4390 bool normal_downloads_are_present = false;
4391 bool incognito_downloads_are_present = false;
[email protected]460a2942010-12-15 19:43:154392 CheckDownloadsInProgress(&normal_downloads_are_present,
[email protected]803e4c82011-06-21 21:04:284393 &incognito_downloads_are_present);
[email protected]446295a2010-04-19 23:43:004394 if (!normal_downloads_are_present && !incognito_downloads_are_present)
4395 return true;
4396
4397 if (is_attempting_to_close_browser_)
4398 return true;
4399
4400 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
4401 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
[email protected]69444cc2009-04-09 20:40:064402 return true;
4403
4404 // Let's figure out if we are the last window for our profile.
4405 // Note that we cannot just use BrowserList::GetBrowserCount as browser
4406 // windows closing is delayed and the returned count might include windows
4407 // that are being closed.
[email protected]446295a2010-04-19 23:43:004408 // The browser allowed to be closed only if:
4409 // 1. It is a regular browser and there are no regular downloads present or
4410 // this is not the last regular browser window.
4411 // 2. It is an incognito browser and there are no incognito downloads present
4412 // or this is not the last incognito browser window.
[email protected]69444cc2009-04-09 20:40:064413 int count = 0;
4414 for (BrowserList::const_iterator iter = BrowserList::begin();
4415 iter != BrowserList::end(); ++iter) {
4416 // Don't count this browser window or any other in the process of closing.
[email protected]b35b26b32011-05-05 20:35:144417 // Only consider tabbed browser windows, not popups.
[email protected]460a2942010-12-15 19:43:154418 Browser* const browser = *iter;
4419 if (browser == this
4420 || browser->is_attempting_to_close_browser_
[email protected]b35b26b32011-05-05 20:35:144421 || !browser->is_type_tabbed())
[email protected]69444cc2009-04-09 20:40:064422 continue;
4423
[email protected]446295a2010-04-19 23:43:004424 // Verify that this is not the last non-incognito or incognito browser,
4425 // depending on the pending downloads.
4426 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154427 browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004428 continue;
4429 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154430 !browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004431 continue;
4432
[email protected]69444cc2009-04-09 20:40:064433 // We test the original profile, because an incognito browser window keeps
4434 // the original profile alive (and its DownloadManager).
4435 // We also need to test explicitly the profile directly so that 2 incognito
4436 // profiles count as a match.
4437 if ((*iter)->profile() == profile() ||
4438 (*iter)->profile()->GetOriginalProfile() == profile())
4439 count++;
4440 }
4441 if (count > 0)
4442 return true;
4443
4444 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4445 window_->ConfirmBrowserCloseWithPendingDownloads();
4446
4447 // Return false so the browser does not close. We'll close if the user
4448 // confirms in the dialog.
4449 return false;
4450}
4451
4452///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574453// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:294454
[email protected]1a6b30a2009-08-19 03:52:114455// static
[email protected]de4e7632010-09-01 06:24:044456Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
[email protected]b35b26b32011-05-05 20:35:144457 return BrowserList::FindTabbedBrowser(profile, match_incognito);
[email protected]de4e7632010-09-01 06:24:044458}
4459
4460// static
[email protected]1a6b30a2009-08-19 03:52:114461Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:044462 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:054463 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:114464 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:294465 return browser;
4466}
4467
[email protected]9219d262011-02-15 21:05:124468void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]e7cfdbd2011-04-22 14:41:374469 // TabContents...
[email protected]9219d262011-02-15 21:05:124470 tab->tab_contents()->set_delegate(delegate);
4471 tab->set_delegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:374472
4473 // ...and all the helpers.
4474 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:144475 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]ddb85052011-05-18 14:40:274476 tab->download_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:124477 tab->search_engine_tab_helper()->set_delegate(delegate);
4478}
4479
[email protected]4f3dc372009-02-24 00:10:294480void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:584481 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:294482 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:004483 string16 find_text;
4484#if defined(OS_MACOSX)
4485 // We always want to search for the contents of the find pasteboard on OS X.
4486 find_text = GetFindPboardText();
4487#endif
[email protected]9c318862011-02-01 22:27:244488 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:384489 find_tab_helper()->StartFinding(find_text,
4490 forward_direction,
4491 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:294492 }
[email protected]fbd77592008-11-12 20:50:274493}
[email protected]cb17f7f2009-02-06 18:14:484494
[email protected]36b6dcb2008-11-12 01:19:574495void Browser::CloseFrame() {
4496 window_->Close();
initial.commit09911bf2008-07-26 23:55:294497}
4498
[email protected]3c9e1872010-11-18 16:17:494499void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:174500 DetachType type) {
4501 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:154502 // Save the current location bar state, but only if the tab being detached
4503 // is the selected tab. Because saving state can conditionally revert the
4504 // location bar, saving the current tab's location bar state to a
4505 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:494506 if (contents == GetSelectedTabContentsWrapper()) {
4507 LocationBar* location_bar = window()->GetLocationBar();
4508 if (location_bar)
4509 location_bar->SaveStateToContents(contents->tab_contents());
4510 }
[email protected]c37e3b62010-01-22 00:15:174511
[email protected]ecc523f62010-09-28 22:45:404512 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:174513 SyncHistoryWithTabs(0);
4514 }
4515
[email protected]9219d262011-02-15 21:05:124516 SetAsDelegate(contents, NULL);
[email protected]3c9e1872010-11-18 16:17:494517 RemoveScheduledUpdatesFor(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:174518
[email protected]ecc523f62010-09-28 22:45:404519 if (find_bar_controller_.get() &&
[email protected]1ea49d52011-04-12 17:44:444520 index == tab_handler_->GetTabStripModel()->active_index()) {
[email protected]c37e3b62010-01-22 00:15:174521 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:404522 }
[email protected]c37e3b62010-01-22 00:15:174523
[email protected]08f0d612011-01-13 23:58:214524 if (is_attempting_to_close_browser_) {
4525 // If this is the last tab with unload handlers, then ProcessPendingTabs
4526 // would call back into the TabStripModel (which is invoking this method on
4527 // us). Avoid that by passing in false so that the call to
4528 // ProcessPendingTabs is delayed.
4529 ClearUnloadState(contents->tab_contents(), false);
4530 }
4531
[email protected]93f230e02011-06-01 14:40:004532 registrar_.Remove(this, NotificationType::INTERSTITIAL_ATTACHED,
4533 Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:174534 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:054535 Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:174536}
4537
initial.commit09911bf2008-07-26 23:55:294538// static
[email protected]f87919d72011-02-02 18:46:164539void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:294540 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:514541 std::string window_pref(prefs::kBrowserWindowPlacement);
4542 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:294543 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:144544 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:164545 if (!prefs->FindPreference(window_pref.c_str())) {
4546 prefs->RegisterDictionaryPref(window_pref.c_str(),
4547 PrefService::UNSYNCABLE_PREF);
4548 }
initial.commit09911bf2008-07-26 23:55:294549}
[email protected]5c238752009-06-13 10:29:074550
[email protected]281918912010-05-27 22:05:134551void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
4552 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
4553 !service->entries().empty());
4554}
4555
4556void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
4557 if (!tab_restore_service_)
4558 return;
4559
4560 DCHECK_EQ(tab_restore_service_, service);
4561 tab_restore_service_->RemoveObserver(this);
4562 tab_restore_service_ = NULL;
4563}
[email protected]97b6c4f2010-09-27 19:31:264564
[email protected]3c9e1872010-11-18 16:17:494565// Centralized method for creating a TabContents, configuring and installing
4566// all its supporting objects and observers.
4567TabContentsWrapper* Browser::TabContentsFactory(
4568 Profile* profile,
4569 SiteInstance* site_instance,
4570 int routing_id,
4571 const TabContents* base_tab_contents,
4572 SessionStorageNamespace* session_storage_namespace) {
4573 TabContents* new_contents = new TabContents(profile, site_instance,
4574 routing_id, base_tab_contents,
4575 session_storage_namespace);
4576 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
4577 return wrapper;
4578}
4579
[email protected]6b723f82010-10-05 20:14:274580bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]35242602011-01-06 16:38:534581 if (!instant() || !instant()->is_active() || !instant()->IsCurrent() ||
4582 disposition == NEW_BACKGROUND_TAB) {
4583 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
4584 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:264585 return false;
[email protected]35242602011-01-06 16:38:534586 }
[email protected]97b6c4f2010-09-27 19:31:264587
4588 if (disposition == CURRENT_TAB) {
[email protected]6b723f82010-10-05 20:14:274589 instant()->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER);
[email protected]97b6c4f2010-09-27 19:31:264590 return true;
4591 }
[email protected]35242602011-01-06 16:38:534592 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:494593 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]6b723f82010-10-05 20:14:274594 INSTANT_COMMIT_PRESSED_ENTER);
[email protected]a0df03c122011-01-05 00:22:554595 // HideInstant is invoked after release so that InstantController is not
4596 // active when HideInstant asks it for its state.
4597 HideInstant();
[email protected]97b6c4f2010-09-27 19:31:264598 preview_contents->controller().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:404599 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:264600 preview_contents,
4601 -1,
[email protected]6b723f82010-10-05 20:14:274602 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:414603 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:374604 instant()->CompleteRelease(preview_contents);
[email protected]97b6c4f2010-09-27 19:31:264605 return true;
4606 }
4607 // The omnibox currently doesn't use other dispositions, so we don't attempt
4608 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
4609 // support for the new disposition.
4610 NOTREACHED();
4611 return false;
4612}
[email protected]2031cf9d2010-10-12 05:05:374613
4614void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:144615 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:374616 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:194617 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:294618 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:374619 }
4620}
[email protected]77d8d622010-12-15 10:30:124621
4622void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:274623 DCHECK(contents);
4624
4625 NavigationEntry* active_entry = contents->controller().GetActiveEntry();
4626 if (!active_entry)
4627 return;
4628
4629 ViewSource(contents, active_entry->url(), active_entry->content_state());
4630}
4631
4632void Browser::ViewSource(TabContentsWrapper* contents,
4633 const GURL& url,
4634 const std::string& content_state) {
[email protected]afd1e522011-04-27 23:29:594635 UserMetrics::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:124636 DCHECK(contents);
4637
4638 TabContentsWrapper* view_source_contents = contents->Clone();
4639 view_source_contents->controller().PruneAllButActive();
4640 NavigationEntry* active_entry =
4641 view_source_contents->controller().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:504642 if (!active_entry)
4643 return;
4644
[email protected]932b7a12011-03-09 12:50:274645 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
4646 url.spec());
4647 active_entry->set_virtual_url(view_source_url);
[email protected]1436beff2010-12-16 19:47:044648
[email protected]932b7a12011-03-09 12:50:274649 // Do not restore scroller position.
4650 active_entry->set_content_state(
4651 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
4652
[email protected]cd3d50d2010-12-18 21:03:294653 // Do not restore title, derive it from the url.
[email protected]6b2f7a82011-04-25 19:30:514654 active_entry->set_title(string16());
[email protected]77d8d622010-12-15 10:30:124655
[email protected]47b309f2010-12-28 17:35:564656 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:124657 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
4658 // If this is a tabbed browser, just create a duplicate tab inside the same
4659 // window next to the tab being duplicated.
4660 int index = tab_handler_->GetTabStripModel()->
4661 GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:414662 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:564663 TabStripModel::ADD_INHERIT_GROUP;
[email protected]77d8d622010-12-15 10:30:124664 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]47b309f2010-12-28 17:35:564665 view_source_contents,
[email protected]77d8d622010-12-15 10:30:124666 add_types);
4667 } else {
[email protected]b35b26b32011-05-05 20:35:144668 Browser* browser = Browser::CreateForType(TYPE_TABBED, profile_);
[email protected]77d8d622010-12-15 10:30:124669
4670 // Preserve the size of the original window. The new window has already
4671 // been given an offset by the OS, so we shouldn't copy the old bounds.
4672 BrowserWindow* new_window = browser->window();
4673 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
4674 window()->GetRestoredBounds().size()));
4675
4676 // We need to show the browser now. Otherwise ContainerWin assumes the
4677 // TabContents is invisible and won't size it.
4678 browser->window()->Show();
4679
4680 // The page transition below is only for the purpose of inserting the tab.
[email protected]47b309f2010-12-28 17:35:564681 browser->AddTab(view_source_contents, PageTransition::LINK);
[email protected]77d8d622010-12-15 10:30:124682 }
4683
[email protected]92371eb2011-04-28 11:50:154684 SessionService* session_service =
4685 SessionServiceFactory::GetForProfileIfExisting(profile_);
4686 if (session_service)
[email protected]81898992011-06-14 22:15:004687 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:124688}
[email protected]b9163e02011-04-20 16:03:374689
4690int Browser::GetContentRestrictionsForSelectedTab() {
4691 int content_restrictions = 0;
4692 TabContents* current_tab = GetSelectedTabContents();
4693 if (current_tab) {
4694 content_restrictions = current_tab->content_restrictions();
4695 NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
4696 // See comment in UpdateCommandsForTabState about why we call url().
4697 if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL()))
4698 content_restrictions |= CONTENT_RESTRICTION_SAVE;
4699 }
4700 return content_restrictions;
4701}
[email protected]09b29342011-06-24 19:18:484702
4703void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
4704 BookmarkBar::State state;
4705 if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
4706 profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)) {
4707 state = BookmarkBar::SHOW;
4708 } else {
4709 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
4710 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
4711 state = BookmarkBar::DETACHED;
4712 else
4713 state = BookmarkBar::HIDDEN;
4714 }
4715 if (state == bookmark_bar_state_)
4716 return;
4717
4718 bookmark_bar_state_ = state;
4719
4720 if (!window_)
4721 return; // This is called from the constructor when window_ is NULL.
4722
4723 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
4724 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
4725 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
4726 // end up querying state once they process the tab switch.
4727 return;
4728 }
4729
4730 BookmarkBar::AnimateChangeType animate_type =
4731 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
4732 BookmarkBar::ANIMATE_STATE_CHANGE :
4733 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
4734 window_->BookmarkBarStateChanged(animate_type);
4735}