blob: 098179b8d419e5763421b7b99ae0a393954d7531 [file] [log] [blame]
[email protected]35d06152011-01-10 22:19:421// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]7b5dc002010-11-16 23:08:105#include "chrome/browser/ui/browser.h"
[email protected]c61db1d2009-02-06 03:39:186
[email protected]aca02cf2010-05-03 18:56:017#if defined(OS_WIN)
[email protected]541434c2011-06-25 01:38:598#include <windows.h>
[email protected]dcd57762011-06-25 12:18:519#include <shellapi.h>
[email protected]aca02cf2010-05-03 18:56:0110#endif // OS_WIN
11
[email protected]5dcbc02f2010-01-26 22:32:0612#include <algorithm>
13#include <string>
14
[email protected]b02d0382009-11-30 21:19:5015#include "base/base_paths.h"
[email protected]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]0af8f132011-07-16 01:37:0220#include "base/string_number_conversions.h"
[email protected]65233052011-08-22 19:02:4821#include "base/string_util.h"
[email protected]34b99632011-01-01 01:01:0622#include "base/threading/thread.h"
23#include "base/threading/thread_restrictions.h"
[email protected]7f070d42011-03-09 20:25:3224#include "base/time.h"
[email protected]6524385ef2010-08-18 06:34:1325#include "base/utf_string_conversions.h"
[email protected]1a3aba82010-11-08 23:52:5426#include "chrome/app/chrome_command_ids.h"
[email protected]cf28ec52010-04-09 22:56:3427#include "chrome/browser/autofill/autofill_manager.h"
[email protected]a07676b22011-06-17 16:36:5328#include "chrome/browser/background/background_contents_service.h"
[email protected]a9afddb2009-02-12 17:49:4229#include "chrome/browser/bookmarks/bookmark_model.h"
[email protected]b3ac5c82009-10-08 20:56:5430#include "chrome/browser/bookmarks/bookmark_utils.h"
[email protected]5c238752009-06-13 10:29:0731#include "chrome/browser/browser_process.h"
[email protected]c61db1d2009-02-06 03:39:1832#include "chrome/browser/browser_shutdown.h"
[email protected]40d59ce52009-03-06 23:20:1433#include "chrome/browser/character_encoding.h"
[email protected]dce502762011-07-20 08:53:4934#include "chrome/browser/debugger/devtools_toggle_action.h"
35#include "chrome/browser/debugger/devtools_window.h"
[email protected]8a282712011-08-23 19:28:0036#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]59560e0b2009-06-04 03:30:2237#include "chrome/browser/download/download_item_model.h"
[email protected]59560e0b2009-06-04 03:30:2238#include "chrome/browser/download/download_started_animation.h"
[email protected]bb461532010-11-26 21:50:2339#include "chrome/browser/extensions/crx_installer.h"
[email protected]9fd542df2009-09-30 07:32:0140#include "chrome/browser/extensions/extension_browser_event_router.h"
[email protected]0c6da502009-08-14 22:32:3941#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
[email protected]6d7a6042010-08-12 20:12:4242#include "chrome/browser/extensions/extension_host.h"
[email protected]10abd192010-09-30 02:03:4943#include "chrome/browser/extensions/extension_prefs.h"
[email protected]eaa7dd182010-12-14 11:09:0044#include "chrome/browser/extensions/extension_service.h"
[email protected]36fb2c7c2011-04-04 15:49:0845#include "chrome/browser/extensions/extension_tab_helper.h"
[email protected]b17d41c2011-02-17 22:09:5946#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]b375c5d2011-05-03 21:15:0447#include "chrome/browser/favicon/favicon_tab_helper.h"
[email protected]3a29a6e2011-08-24 18:26:2148#include "chrome/browser/file_select_helper.h"
[email protected]820735792010-07-29 23:40:0149#include "chrome/browser/first_run/first_run.h"
[email protected]f7578f52010-08-30 22:22:4950#include "chrome/browser/google/google_url_tracker.h"
51#include "chrome/browser/google/google_util.h"
[email protected]6b723f82010-10-05 20:14:2752#include "chrome/browser/instant/instant_controller.h"
[email protected]5aab5e22010-12-08 22:13:2953#include "chrome/browser/instant/instant_unload_handler.h"
[email protected]90f39902009-10-03 04:25:3754#include "chrome/browser/net/browser_url_util.h"
[email protected]a239c3f2009-02-17 22:13:1955#include "chrome/browser/net/url_fixer_upper.h"
[email protected]2c4fb7b2011-04-02 06:33:2956#include "chrome/browser/notifications/notification_ui_manager.h"
[email protected]14a000d2010-04-29 21:44:2457#include "chrome/browser/platform_util.h"
[email protected]4e94ab32011-08-05 05:28:2758#include "chrome/browser/prefs/incognito_mode_prefs.h"
[email protected]37858e52010-08-26 00:22:0259#include "chrome/browser/prefs/pref_service.h"
[email protected]02337592010-09-27 18:38:2560#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
[email protected]8ecad5e2010-12-02 21:18:3361#include "chrome/browser/profiles/profile.h"
[email protected]81898992011-06-14 22:15:0062#include "chrome/browser/sessions/restore_tab_helper.h"
[email protected]85e921fb82009-02-11 23:19:4463#include "chrome/browser/sessions/session_service.h"
[email protected]92371eb2011-04-28 11:50:1564#include "chrome/browser/sessions/session_service_factory.h"
[email protected]c61db1d2009-02-06 03:39:1865#include "chrome/browser/sessions/session_types.h"
[email protected]92926d92010-09-02 18:35:0666#include "chrome/browser/sessions/tab_restore_service.h"
[email protected]92371eb2011-04-28 11:50:1567#include "chrome/browser/sessions/tab_restore_service_factory.h"
[email protected]066629f2009-10-17 00:28:1368#include "chrome/browser/sync/profile_sync_service.h"
[email protected]40f047972009-11-25 03:54:4069#include "chrome/browser/sync/sync_ui_util.h"
[email protected]0b4d3382010-07-14 16:13:0470#include "chrome/browser/tab_closeable_state_watcher.h"
[email protected]2c4fb7b2011-04-02 06:33:2971#include "chrome/browser/tab_contents/background_contents.h"
[email protected]7cceebac2011-03-03 00:32:2172#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
[email protected]1ab4ddf2011-07-21 04:48:0473#include "chrome/browser/tab_contents/tab_util.h"
[email protected]07d490bc2011-03-07 17:05:2674#include "chrome/browser/tabs/tab_finder.h"
[email protected]c848d3d92010-09-16 21:57:4575#include "chrome/browser/tabs/tab_strip_model.h"
[email protected]ffa6f592011-06-24 22:03:5776#include "chrome/browser/themes/theme_service.h"
77#include "chrome/browser/themes/theme_service_factory.h"
[email protected]3ab9cb82011-06-03 18:02:0778#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]e7cfdbd2011-04-22 14:41:3779#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]35699d572011-05-11 19:46:1480#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
[email protected]55452902011-06-01 21:57:4781#include "chrome/browser/ui/browser_dialogs.h"
[email protected]6768ac02011-04-06 17:41:0482#include "chrome/browser/ui/browser_list.h"
[email protected]fcca741b2011-06-17 22:46:3783#include "chrome/browser/ui/browser_navigator.h"
[email protected]afefa74e2011-07-26 05:04:2384#include "chrome/browser/ui/browser_synced_window_delegate.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]45300ad42010-12-02 15:51:1487#include "chrome/browser/ui/find_bar/find_bar.h"
88#include "chrome/browser/ui/find_bar/find_bar_controller.h"
[email protected]c90c6ca2011-02-16 20:11:3889#include "chrome/browser/ui/find_bar/find_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1990#include "chrome/browser/ui/omnibox/location_bar.h"
[email protected]fe90ca8e2011-04-08 20:40:4391#include "chrome/browser/ui/panels/panel.h"
92#include "chrome/browser/ui/panels/panel_manager.h"
[email protected]9219d262011-02-15 21:05:1293#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
[email protected]6a3ec2312010-12-02 19:30:1994#include "chrome/browser/ui/status_bubble.h"
95#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9a800652010-12-02 17:08:4496#include "chrome/browser/ui/tabs/dock_info.h"
[email protected]6a3ec2312010-12-02 19:30:1997#include "chrome/browser/ui/tabs/tab_menu_model.h"
[email protected]f847e6082011-03-24 00:08:2698#include "chrome/browser/ui/web_applications/web_app_ui.h"
[email protected]265a1492011-02-27 05:58:0799#include "chrome/browser/ui/webui/bug_report_ui.h"
[email protected]5c557f372011-02-26 15:09:20100#include "chrome/browser/ui/webui/options/content_settings_handler.h"
[email protected]9a800652010-12-02 17:08:44101#include "chrome/browser/ui/window_sizer.h"
[email protected]b1b73942010-05-26 20:11:54102#include "chrome/browser/upgrade_detector.h"
[email protected]86b54012009-11-19 09:18:50103#include "chrome/browser/web_applications/web_app.h"
[email protected]d938aed92009-01-22 19:49:33104#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:27105#include "chrome/common/chrome_notification_types.h"
[email protected]d938aed92009-01-22 19:49:33106#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:58107#include "chrome/common/extensions/extension.h"
[email protected]46fd1ea42011-02-16 15:59:33108#include "chrome/common/extensions/extension_constants.h"
[email protected]8a53ee042009-01-21 16:41:33109#include "chrome/common/pref_names.h"
[email protected]7664ab32011-02-01 23:35:25110#include "chrome/common/profiling.h"
[email protected]b689fce72009-03-17 22:45:34111#include "chrome/common/url_constants.h"
[email protected]bb461532010-11-26 21:50:23112#include "chrome/common/web_apps.h"
[email protected]b8148ac2011-07-13 22:03:25113#include "content/browser/browser_url_handler.h"
[email protected]3a29a6e2011-08-24 18:26:21114#include "content/browser/child_process_security_policy.h"
[email protected]b46442d7e2011-06-29 02:16:06115#include "content/browser/debugger/devtools_manager.h"
[email protected]71bf3f5e2011-08-15 21:05:22116#include "content/browser/download/download_item.h"
117#include "content/browser/download/download_manager.h"
[email protected]0ffaa482011-07-14 23:41:28118#include "content/browser/download/save_package.h"
[email protected]b6021d32011-02-26 01:25:54119#include "content/browser/host_zoom_map.h"
[email protected]a01efd22011-03-01 00:38:32120#include "content/browser/renderer_host/render_view_host.h"
121#include "content/browser/site_instance.h"
[email protected]a01efd22011-03-01 00:38:32122#include "content/browser/tab_contents/interstitial_page.h"
123#include "content/browser/tab_contents/navigation_controller.h"
124#include "content/browser/tab_contents/navigation_entry.h"
[email protected]a01efd22011-03-01 00:38:32125#include "content/browser/tab_contents/tab_contents_view.h"
[email protected]afd1e522011-04-27 23:29:59126#include "content/browser/user_metrics.h"
[email protected]763ec4ca2011-04-29 15:48:12127#include "content/common/content_restriction.h"
[email protected]7f070d42011-03-09 20:25:32128#include "content/common/notification_service.h"
[email protected]4dd57932011-03-17 06:06:12129#include "content/common/page_transition_types.h"
[email protected]216813952011-05-19 22:21:26130#include "content/common/page_zoom.h"
131#include "content/common/view_messages.h"
[email protected]a3e18c42009-03-04 23:36:05132#include "grit/chromium_strings.h"
133#include "grit/generated_resources.h"
134#include "grit/locale_settings.h"
[email protected]8a53ee042009-01-21 16:41:33135#include "net/base/cookie_monster.h"
[email protected]8a53ee042009-01-21 16:41:33136#include "net/base/net_util.h"
137#include "net/base/registry_controlled_domain.h"
138#include "net/url_request/url_request_context.h"
[email protected]f67678062011-01-07 17:33:39139#include "ui/base/animation/animation.h"
[email protected]c051a1b2011-01-21 23:30:17140#include "ui/base/l10n/l10n_util.h"
[email protected]08397d52011-02-05 01:53:38141#include "ui/gfx/point.h"
[email protected]1436beff2010-12-16 19:47:04142#include "webkit/glue/webkit_glue.h"
[email protected]d938aed92009-01-22 19:49:33143#include "webkit/glue/window_open_disposition.h"
[email protected]8a53ee042009-01-21 16:41:33144
145#if defined(OS_WIN)
[email protected]36d5e5592010-11-15 20:45:59146#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
[email protected]12f520c2010-01-06 18:11:15147#include "chrome/browser/shell_integration.h"
[email protected]b17d41c2011-02-17 22:09:59148#include "chrome/browser/ssl/ssl_error_info.h"
[email protected]a5d1e1e2010-09-23 19:34:12149#include "chrome/browser/task_manager/task_manager.h"
[email protected]6a3ec2312010-12-02 19:30:19150#include "chrome/browser/ui/view_ids.h"
151#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
[email protected]dcd57762011-06-25 12:18:51152#include "ui/base/win/shell.h"
[email protected]8a53ee042009-01-21 16:41:33153#endif // OS_WIN
[email protected]e1acf6f2008-10-27 20:43:33154
[email protected]6a4f5af22009-09-23 22:43:00155#if defined(OS_MACOSX)
[email protected]8aee8ed32011-06-14 20:16:41156#include "content/browser/find_pasteboard.h"
[email protected]6a4f5af22009-09-23 22:43:00157#endif
158
[email protected]b7969202010-05-14 21:29:26159#if defined(OS_CHROMEOS)
[email protected]6a2a61d2010-11-22 03:25:35160#include "chrome/browser/chromeos/boot_times_loader.h"
[email protected]efda32f92011-07-06 22:47:04161#include "chrome/browser/ui/webui/active_downloads_ui.h"
162#else
163#include "chrome/browser/download/download_shelf.h"
[email protected]b7969202010-05-14 21:29:26164#endif
165
[email protected]cb6dbc52011-08-10 17:34:39166#if defined(FILE_MANAGER_EXTENSION)
167#include "chrome/browser/extensions/file_manager_util.h"
168#endif
169
[email protected]8a53ee042009-01-21 16:41:33170using base::TimeDelta;
initial.commit09911bf2008-07-26 23:55:29171
[email protected]36b6dcb2008-11-12 01:19:57172///////////////////////////////////////////////////////////////////////////////
initial.commit09911bf2008-07-26 23:55:29173
[email protected]505323e22009-01-24 02:47:58174namespace {
175
[email protected]91a79232010-11-10 18:15:08176// The URL to be loaded to display Help.
[email protected]8332c162011-01-26 12:01:54177const char kHelpContentUrl[] =
[email protected]91a79232010-11-10 18:15:08178#if defined(OS_CHROMEOS)
[email protected]8332c162011-01-26 12:01:54179 #if defined(OFFICIAL_BUILD)
180 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html";
181 #else
[email protected]95fc6f92011-04-13 00:37:20182 "https://www.google.com/support/chromeos/";
[email protected]8332c162011-01-26 12:01:54183 #endif
[email protected]91a79232010-11-10 18:15:08184#else
[email protected]95fc6f92011-04-13 00:37:20185 "https://www.google.com/support/chrome/";
[email protected]91a79232010-11-10 18:15:08186#endif
187
188// The URL to be opened when the Help link on the Autofill dialog is clicked.
189const char kAutofillHelpUrl[] =
190#if defined(OS_CHROMEOS)
[email protected]95fc6f92011-04-13 00:37:20191 "https://www.google.com/support/chromeos/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08192#else
[email protected]95fc6f92011-04-13 00:37:20193 "https://www.google.com/support/chrome/bin/answer.py?answer=142893";
[email protected]91a79232010-11-10 18:15:08194#endif
195
196// The URL to be loaded to display the "Report a broken page" form.
197const char kBrokenPageUrl[] =
[email protected]95fc6f92011-04-13 00:37:20198 "https://www.google.com/support/chrome/bin/request.py?contact_type="
[email protected]91a79232010-11-10 18:15:08199 "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
200
201// The URL for the privacy dashboard.
202const char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
203
204// How long we wait before updating the browser chrome while loading a page.
205const int kUIUpdateCoalescingTimeMS = 200;
206
207const char kHashMark[] = "#";
208
[email protected]50dc3deb2011-07-07 01:07:19209// Returns |true| if entry has an internal chrome:// URL, |false| otherwise.
210bool HasInternalURL(const NavigationEntry* entry) {
211 if (!entry)
212 return false;
213
214 // Check the |virtual_url()| first. This catches regular chrome:// URLs
215 // including URLs that were rewritten (such as chrome://bookmarks).
216 if (entry->virtual_url().SchemeIs(chrome::kChromeUIScheme))
217 return true;
218
219 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually
220 // view-source: of a chrome:// URL.
221 if (entry->virtual_url().SchemeIs(chrome::kViewSourceScheme))
222 return entry->url().SchemeIs(chrome::kChromeUIScheme);
223
224 return false;
225}
226
[email protected]505323e22009-01-24 02:47:58227} // namespace
228
[email protected]e838eaf2010-10-13 18:53:33229extern bool g_log_bug53991;
230
[email protected]b35b26b32011-05-05 20:35:14231////////////////////////////////////////////////////////////////////////////////
232// Browser, CreateParams:
233
234Browser::CreateParams::CreateParams(Type type, Profile* profile)
235 : type(type),
236 profile(profile) {
237}
238
[email protected]36b6dcb2008-11-12 01:19:57239///////////////////////////////////////////////////////////////////////////////
240// Browser, Constructors, Creation, Showing:
initial.commit09911bf2008-07-26 23:55:29241
[email protected]299dabd2008-11-19 02:27:16242Browser::Browser(Type type, Profile* profile)
[email protected]15952e462008-11-14 00:29:05243 : type_(type),
244 profile_(profile),
[email protected]f3e99e32008-07-30 04:48:39245 window_(NULL),
[email protected]ecc523f62010-09-28 22:45:40246 ALLOW_THIS_IN_INITIALIZER_LIST(
247 tab_handler_(TabHandler::CreateTabHandler(this))),
[email protected]1fc025202009-01-20 23:03:14248 command_updater_(this),
initial.commit09911bf2008-07-26 23:55:29249 toolbar_model_(this),
[email protected]15952e462008-11-14 00:29:05250 chrome_updater_factory_(this),
251 is_attempting_to_close_browser_(false),
[email protected]69444cc2009-04-09 20:40:06252 cancel_download_confirmation_state_(NOT_PROMPTED),
[email protected]400eaf82011-08-22 15:47:39253 show_state_(ui::SHOW_STATE_DEFAULT),
[email protected]867125a02009-12-10 06:01:48254 method_factory_(this),
255 block_command_execution_(false),
256 last_blocked_command_id_(-1),
[email protected]eabfdae92009-12-11 06:13:51257 last_blocked_command_disposition_(CURRENT_TAB),
[email protected]fb7da4132011-03-15 15:51:00258 pending_web_app_action_(NONE),
259 ALLOW_THIS_IN_INITIALIZER_LIST(
260 tab_restore_service_delegate_(
[email protected]09b29342011-06-24 19:18:48261 new BrowserTabRestoreServiceDelegate(this))),
[email protected]afefa74e2011-07-26 05:04:23262 ALLOW_THIS_IN_INITIALIZER_LIST(
263 synced_window_delegate_(
264 new BrowserSyncedWindowDelegate(this))),
[email protected]09b29342011-06-24 19:18:48265 bookmark_bar_state_(BookmarkBar::HIDDEN) {
[email protected]432115822011-07-10 15:52:27266 registrar_.Add(this, content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED,
[email protected]0cb94102009-05-22 19:51:21267 NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27268 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
[email protected]0c6da502009-08-14 22:32:39269 NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27270 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]ad0c2e1b2010-01-30 00:00:10271 NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27272 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]0cb94102009-05-22 19:51:21273 NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27274 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
[email protected]0dfe05c2011-02-23 23:03:36275 NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27276 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
[email protected]371ed7a2009-08-25 15:22:46277 NotificationService::AllSources());
[email protected]ffa6f592011-06-24 22:03:57278 registrar_.Add(
[email protected]432115822011-07-10 15:52:27279 this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
[email protected]ffa6f592011-06-24 22:03:57280 Source<ThemeService>(ThemeServiceFactory::GetForProfile(profile_)));
[email protected]432115822011-07-10 15:52:27281 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENT_SETTINGS_CHANGED,
[email protected]9a9a9e22011-05-13 22:20:35282 NotificationService::AllSources());
[email protected]0b4e22322011-08-11 19:50:34283 // We listen to all notification sources because the bookmark bar
284 // state needs to stay in sync between the incognito and normal profiles.
[email protected]432115822011-07-10 15:52:27285 registrar_.Add(this,
286 chrome::NOTIFICATION_BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
[email protected]0b4e22322011-08-11 19:50:34287 NotificationService::AllBrowserContextsAndSources());
initial.commit09911bf2008-07-26 23:55:29288
[email protected]91e1bd82009-09-03 22:04:40289 // Need to know when to alert the user of theme install delay.
[email protected]432115822011-07-10 15:52:27290 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_READY_FOR_INSTALL,
[email protected]91e1bd82009-09-03 22:04:40291 NotificationService::AllSources());
292
[email protected]9e823662010-10-13 23:36:00293 PrefService* local_state = g_browser_process->local_state();
[email protected]97b46382011-05-02 13:23:04294 if (local_state) {
295 local_pref_registrar_.Init(local_state);
296 local_pref_registrar_.Add(prefs::kPrintingEnabled, this);
297 local_pref_registrar_.Add(prefs::kAllowFileSelectionDialogs, this);
[email protected]3819f2ee2011-08-21 09:44:38298 local_pref_registrar_.Add(prefs::kMetricsReportingEnabled, this);
[email protected]97b46382011-05-02 13:23:04299 }
300
301 profile_pref_registrar_.Init(profile_->GetPrefs());
302 profile_pref_registrar_.Add(prefs::kDevToolsDisabled, this);
303 profile_pref_registrar_.Add(prefs::kEditBookmarksEnabled, this);
[email protected]a007e732011-08-05 13:32:19304 profile_pref_registrar_.Add(prefs::kEnableBookmarkBar, this);
[email protected]97b46382011-05-02 13:23:04305 profile_pref_registrar_.Add(prefs::kInstantEnabled, this);
[email protected]4e94ab32011-08-05 05:28:27306 profile_pref_registrar_.Add(prefs::kIncognitoModeAvailability, this);
[email protected]3819f2ee2011-08-21 09:44:38307 profile_pref_registrar_.Add(prefs::kSearchSuggestEnabled, this);
[email protected]9e823662010-10-13 23:36:00308
initial.commit09911bf2008-07-26 23:55:29309 InitCommandState();
310 BrowserList::AddBrowser(this);
311
[email protected]97b46382011-05-02 13:23:04312 // NOTE: These prefs all need to be explicitly destroyed in the destructor
313 // or you'll get a nasty surprise when you run the incognito tests.
initial.commit09911bf2008-07-26 23:55:29314 encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
315 profile_->GetPrefs(), NULL);
[email protected]b9c505b2010-04-30 15:05:10316 use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
[email protected]ac86c982011-05-11 13:26:05317 use_compact_navigation_bar_.Init(prefs::kUseCompactNavigationBar,
318 profile_->GetPrefs(),
319 this);
[email protected]97b46382011-05-02 13:23:04320
[email protected]b9c505b2010-04-30 15:05:10321 if (!TabMenuModel::AreVerticalTabsEnabled()) {
322 // If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
323 // might show vertical tabs but not show an option to turn them off.
324 use_vertical_tabs_.SetValue(false);
325 }
[email protected]ac86c982011-05-11 13:26:05326 if (!TabMenuModel::IsCompactNavigationModeEnabled()) {
327 // If the compact navigation bar isn't enabled, explicitly turn it off.
328 // Otherwise we might show the compact navigation bar but not show an option
329 // to turn it off.
330 use_compact_navigation_bar_.SetValue(false);
331 }
332
[email protected]b3344872010-05-03 15:52:29333 UpdateTabStripModelInsertionPolicy();
[email protected]281918912010-05-27 22:05:13334
[email protected]92371eb2011-04-28 11:50:15335 tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]281918912010-05-27 22:05:13336 if (tab_restore_service_) {
337 tab_restore_service_->AddObserver(this);
338 TabRestoreServiceChanged(tab_restore_service_);
339 }
[email protected]d3b98c82010-07-14 07:45:59340
341 if (profile_->GetProfileSyncService())
342 profile_->GetProfileSyncService()->AddObserver(this);
[email protected]03bb953d2010-09-14 21:38:30343
[email protected]2031cf9d2010-10-12 05:05:37344 CreateInstantIfNecessary();
[email protected]07d490bc2011-03-07 17:05:26345
346 // Make sure TabFinder has been created. This does nothing if TabFinder is
347 // not enabled.
348 TabFinder::GetInstance();
[email protected]09b29342011-06-24 19:18:48349
350 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_INIT);
initial.commit09911bf2008-07-26 23:55:29351}
352
353Browser::~Browser() {
[email protected]5044da82010-10-27 01:09:16354 VLOG_IF(1, g_log_bug53991) << "~Browser: " << profile_->IsOffTheRecord()
355 << "; stillActive="
356 << BrowserList::IsOffTheRecordSessionActive();
[email protected]e838eaf2010-10-13 18:53:33357
[email protected]d3b98c82010-07-14 07:45:59358 if (profile_->GetProfileSyncService())
359 profile_->GetProfileSyncService()->RemoveObserver(this);
360
initial.commit09911bf2008-07-26 23:55:29361 BrowserList::RemoveBrowser(this);
362
[email protected]7be64502011-05-03 17:51:47363#if !defined(OS_MACOSX)
initial.commit09911bf2008-07-26 23:55:29364 if (!BrowserList::HasBrowserWithProfile(profile_)) {
365 // We're the last browser window with this profile. We need to nuke the
366 // TabRestoreService, which will start the shutdown of the
367 // NavigationControllers and allow for proper shutdown. If we don't do this
368 // chrome won't shutdown cleanly, and may end up crashing when some
369 // thread tries to use the IO thread (or another thread) that is no longer
370 // valid.
[email protected]fbc947b2009-06-19 13:28:24371 // This isn't a valid assumption for Mac OS, as it stays running after
372 // the last browser has closed. The Mac equivalent is in its app
373 // controller.
[email protected]92371eb2011-04-28 11:50:15374 TabRestoreServiceFactory::ResetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29375 }
[email protected]fbc947b2009-06-19 13:28:24376#endif
initial.commit09911bf2008-07-26 23:55:29377
[email protected]92371eb2011-04-28 11:50:15378 SessionService* session_service =
379 SessionServiceFactory::GetForProfile(profile_);
initial.commit09911bf2008-07-26 23:55:29380 if (session_service)
381 session_service->WindowClosed(session_id_);
382
[email protected]92371eb2011-04-28 11:50:15383 TabRestoreService* tab_restore_service =
384 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]d8375fd2008-11-25 22:45:39385 if (tab_restore_service)
[email protected]fb7da4132011-03-15 15:51:00386 tab_restore_service->BrowserClosed(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:39387
[email protected]97b46382011-05-02 13:23:04388 profile_pref_registrar_.RemoveAll();
389 local_pref_registrar_.RemoveAll();
390
[email protected]9a8c4022011-01-25 14:25:33391 encoding_auto_detect_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33392 use_vertical_tabs_.Destroy();
[email protected]ac86c982011-05-11 13:26:05393 use_compact_navigation_bar_.Destroy();
[email protected]9a8c4022011-01-25 14:25:33394
initial.commit09911bf2008-07-26 23:55:29395 if (profile_->IsOffTheRecord() &&
[email protected]474e5db2011-08-12 13:02:23396 !BrowserList::IsOffTheRecordSessionActiveForProfile(profile_)) {
[email protected]0d1add32011-04-07 00:06:50397 // An incognito profile is no longer needed, this indirectly
[email protected]860f55492009-03-27 19:50:59398 // frees its cache and cookies.
399 profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
initial.commit09911bf2008-07-26 23:55:29400 }
401
402 // There may be pending file dialogs, we need to tell them that we've gone
403 // away so they don't try and call back to us.
404 if (select_file_dialog_.get())
405 select_file_dialog_->ListenerDestroyed();
[email protected]281918912010-05-27 22:05:13406
407 TabRestoreServiceDestroyed(tab_restore_service_);
initial.commit09911bf2008-07-26 23:55:29408}
409
[email protected]15952e462008-11-14 00:29:05410// static
411Browser* Browser::Create(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14412 Browser* browser = new Browser(TYPE_TABBED, profile);
413 browser->InitBrowserWindow();
414 return browser;
415}
416
417// static
418Browser* Browser::CreateWithParams(const CreateParams& params) {
419 Browser* browser = new Browser(params.type, params.profile);
420 browser->app_name_ = params.app_name;
421 if (!params.initial_bounds.IsEmpty())
422 browser->set_override_bounds(params.initial_bounds);
[email protected]9800de5e2011-03-11 18:19:49423 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:05424 return browser;
425}
[email protected]6104acf2008-11-11 22:27:34426
[email protected]15952e462008-11-14 00:29:05427// static
[email protected]9ee17e8c2010-08-10 19:17:31428Browser* Browser::CreateForType(Type type, Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14429 CreateParams params(type, profile);
430 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05431}
432
433// static
[email protected]b35b26b32011-05-05 20:35:14434Browser* Browser::CreateForApp(Type type,
435 const std::string& app_name,
[email protected]5c209242011-06-06 20:36:17436 const gfx::Rect& window_bounds,
[email protected]b35b26b32011-05-05 20:35:14437 Profile* profile) {
438 DCHECK(type != TYPE_TABBED);
439 DCHECK(!app_name.empty());
[email protected]f075fe0a22010-04-26 04:06:43440
[email protected]b35b26b32011-05-05 20:35:14441 RegisterAppPrefs(app_name, profile);
442
443#if !defined(OS_CHROMEOS)
444 if (type == TYPE_PANEL &&
445 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
446 // The panel UI is not fully implemented, so we default to TYPE_POPUP when
447 // the panel switch is not enabled. See crbug/55943.
448 type = TYPE_POPUP;
[email protected]5530ac652010-09-25 05:35:49449 }
[email protected]b35b26b32011-05-05 20:35:14450#endif
[email protected]f075fe0a22010-04-26 04:06:43451
[email protected]b35b26b32011-05-05 20:35:14452 CreateParams params(type, profile);
453 params.app_name = app_name;
[email protected]5c209242011-06-06 20:36:17454 if (!window_bounds.IsEmpty())
455 params.initial_bounds = window_bounds;
[email protected]605cfad2010-06-22 20:49:35456
[email protected]b35b26b32011-05-05 20:35:14457 return CreateWithParams(params);
[email protected]15952e462008-11-14 00:29:05458}
459
[email protected]8e48e982009-12-25 11:22:46460// static
461Browser* Browser::CreateForDevTools(Profile* profile) {
[email protected]b35b26b32011-05-05 20:35:14462 CreateParams params(TYPE_POPUP, profile);
463 params.app_name = DevToolsWindow::kDevToolsApp;
464 return CreateWithParams(params);
[email protected]8e48e982009-12-25 11:22:46465}
466
[email protected]9800de5e2011-03-11 18:19:49467void Browser::InitBrowserWindow() {
[email protected]15952e462008-11-14 00:29:05468 DCHECK(!window_);
[email protected]9c45b7182009-08-04 16:44:43469
[email protected]9800de5e2011-03-11 18:19:49470 window_ = CreateBrowserWindow();
[email protected]15952e462008-11-14 00:29:05471
[email protected]80cf3562009-11-17 08:17:24472#if defined(OS_WIN)
[email protected]45446a52010-11-04 17:41:00473 {
474 // TODO: This might hit the disk
475 // http://code.google.com/p/chromium/issues/detail?id=61638
476 base::ThreadRestrictions::ScopedAllowIO allow_io;
477
478 // Set the app user model id for this application to that of the application
479 // name. See http://crbug.com/7028.
[email protected]dcd57762011-06-25 12:18:51480 ui::win::SetAppIdForWindow(
[email protected]b35b26b32011-05-05 20:35:14481 is_app() ?
[email protected]45446a52010-11-04 17:41:00482 ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
483 ShellIntegration::GetChromiumAppId(profile_->GetPath()),
484 window()->GetNativeHandle());
485 }
[email protected]80cf3562009-11-17 08:17:24486#endif
487
[email protected]14d8c66e2009-09-22 00:32:52488 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27489 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
[email protected]14d8c66e2009-09-22 00:32:52490 Source<Browser>(this),
491 NotificationService::NoDetails());
492
[email protected]ac86c982011-05-11 13:26:05493 if (use_compact_navigation_bar_.GetValue()) {
494 // This enables the compact navigation bar host.
495 UseCompactNavigationBarChanged();
496 }
497
[email protected]15952e462008-11-14 00:29:05498 // Show the First Run information bubble if we've been told to.
499 PrefService* local_state = g_browser_process->local_state();
[email protected]be3877f2009-01-14 15:51:10500 if (!local_state)
501 return;
[email protected]da6ce5602009-12-07 23:09:32502 if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
[email protected]15952e462008-11-14 00:29:05503 local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50504 FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07505 if (local_state->
[email protected]da6ce5602009-12-07 23:09:32506 FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
[email protected]adfe1882010-04-13 23:01:07507 local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50508 bubble_type = FirstRun::OEM_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07509 } else if (local_state->
510 FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
511 local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
[email protected]450028dd2010-08-28 00:24:50512 bubble_type = FirstRun::MINIMAL_BUBBLE;
[email protected]adfe1882010-04-13 23:01:07513 }
[email protected]15952e462008-11-14 00:29:05514 // Reset the preference so we don't show the bubble for subsequent windows.
515 local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
[email protected]adfe1882010-04-13 23:01:07516 window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
initial.commit09911bf2008-07-26 23:55:29517 }
[email protected]f69c8852010-10-12 02:36:46518 if (local_state->FindPreference(
[email protected]663bd9e2011-03-21 01:07:01519 prefs::kAutofillPersonalDataManagerFirstRun) &&
520 local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
[email protected]f69c8852010-10-12 02:36:46521 // Notify PDM that this is a first run.
522#if defined(OS_WIN)
523 ImportAutofillDataWin(profile_->GetPersonalDataManager());
524#endif // defined(OS_WIN)
525 // Reset the preference so we don't call it again for subsequent windows.
[email protected]663bd9e2011-03-21 01:07:01526 local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
[email protected]f69c8852010-10-12 02:36:46527 }
initial.commit09911bf2008-07-26 23:55:29528}
529
[email protected]36b6dcb2008-11-12 01:19:57530///////////////////////////////////////////////////////////////////////////////
[email protected]5c238752009-06-13 10:29:07531// Getters & Setters
532
[email protected]b77cb302009-10-29 04:09:17533FindBarController* Browser::GetFindBarController() {
534 if (!find_bar_controller_.get()) {
[email protected]632983f2011-08-08 22:51:24535 FindBar* find_bar = window_->CreateFindBar();
[email protected]b77cb302009-10-29 04:09:17536 find_bar_controller_.reset(new FindBarController(find_bar));
537 find_bar->SetFindBarController(find_bar_controller_.get());
[email protected]9c318862011-02-01 22:27:24538 find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
[email protected]b77cb302009-10-29 04:09:17539 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
540 }
541 return find_bar_controller_.get();
542}
543
[email protected]24db8a072009-10-29 20:35:37544bool Browser::HasFindBarController() const {
545 return find_bar_controller_.get() != NULL;
546}
547
[email protected]b35b26b32011-05-05 20:35:14548bool Browser::is_app() const {
549 return !app_name_.empty();
550}
551
552bool Browser::is_devtools() const {
553 return app_name_ == DevToolsWindow::kDevToolsApp;
554}
555
[email protected]5c238752009-06-13 10:29:07556///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57557// Browser, Creation Helpers:
558
559// static
[email protected]15952e462008-11-14 00:29:05560void Browser::OpenEmptyWindow(Profile* profile) {
561 Browser* browser = Browser::Create(profile);
[email protected]36b6dcb2008-11-12 01:19:57562 browser->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:05563 browser->window()->Show();
initial.commit09911bf2008-07-26 23:55:29564}
565
[email protected]36b6dcb2008-11-12 01:19:57566// static
[email protected]fbc947b2009-06-19 13:28:24567void Browser::OpenWindowWithRestoredTabs(Profile* profile) {
[email protected]92371eb2011-04-28 11:50:15568 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
[email protected]fbc947b2009-06-19 13:28:24569 if (service)
570 service->RestoreMostRecentEntry(NULL);
571}
572
573// static
[email protected]36b6dcb2008-11-12 01:19:57574void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
[email protected]cecc93a2010-10-05 15:58:55575 Browser* browser = GetOrCreateTabbedBrowser(
576 profile->GetOffTheRecordProfile());
577 browser->AddSelectedTabWithURL(url, PageTransition::LINK);
[email protected]15952e462008-11-14 00:29:05578 browser->window()->Show();
[email protected]2baf83d2008-07-30 05:58:17579}
580
[email protected]36b6dcb2008-11-12 01:19:57581// static
[email protected]d83a5602010-09-16 00:22:48582TabContents* Browser::OpenApplication(
583 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02584 const Extension* extension,
[email protected]24bf2022010-10-14 16:34:39585 extension_misc::LaunchContainer container,
[email protected]7e41c2b2011-05-06 10:31:16586 WindowOpenDisposition disposition) {
[email protected]56869382010-05-11 21:45:46587 TabContents* tab = NULL;
[email protected]4033bd92011-03-08 19:27:04588 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
589 prefs->SetActiveBit(extension->id(), true);
[email protected]e3acb7c2010-05-11 19:23:37590
[email protected]9b217652010-10-08 22:04:23591 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
592
[email protected]bbadaa782010-04-28 21:21:53593 switch (container) {
[email protected]d83a5602010-09-16 00:22:48594 case extension_misc::LAUNCH_WINDOW:
595 case extension_misc::LAUNCH_PANEL:
[email protected]bbadaa782010-04-28 21:21:53596 tab = Browser::OpenApplicationWindow(profile, extension, container,
[email protected]0e71e4152010-12-07 04:16:26597 GURL(), NULL);
[email protected]c28071ad2010-03-12 17:28:56598 break;
[email protected]d83a5602010-09-16 00:22:48599 case extension_misc::LAUNCH_TAB: {
[email protected]7e41c2b2011-05-06 10:31:16600 tab = Browser::OpenApplicationTab(profile, extension, disposition);
[email protected]c28071ad2010-03-12 17:28:56601 break;
602 }
603 default:
604 NOTREACHED();
[email protected]bbadaa782010-04-28 21:21:53605 break;
[email protected]c28071ad2010-03-12 17:28:56606 }
[email protected]bbadaa782010-04-28 21:21:53607 return tab;
[email protected]c28071ad2010-03-12 17:28:56608}
609
610// static
[email protected]bbadaa782010-04-28 21:21:53611TabContents* Browser::OpenApplicationWindow(
612 Profile* profile,
[email protected]9adb9692010-10-29 23:14:02613 const Extension* extension,
[email protected]d83a5602010-09-16 00:22:48614 extension_misc::LaunchContainer container,
[email protected]0e71e4152010-12-07 04:16:26615 const GURL& url_input,
616 Browser** app_browser) {
[email protected]f381dfa2010-04-29 04:41:37617 GURL url;
618 if (!url_input.is_empty()) {
619 if (extension)
[email protected]cced75a2011-05-20 08:31:12620 DCHECK(extension->web_extent().MatchesURL(url_input));
[email protected]f381dfa2010-04-29 04:41:37621 url = url_input;
622 } else {
[email protected]ae5909e2011-02-23 14:34:18623 DCHECK(extension); // Empty url and no extension. Nothing to open.
[email protected]f381dfa2010-04-29 04:41:37624 url = extension->GetFullLaunchURL();
625 }
626
[email protected]2f1c09d2011-01-14 14:58:14627 std::string app_name;
628 if (extension)
629 app_name =
630 web_app::GenerateApplicationNameFromExtensionId(extension->id());
631 else
632 app_name = web_app::GenerateApplicationNameFromURL(url);
633
[email protected]b35b26b32011-05-05 20:35:14634 Type type = extension && (container == extension_misc::LAUNCH_PANEL) ?
635 TYPE_PANEL : TYPE_POPUP;
[email protected]94ce7252010-12-20 21:46:33636
[email protected]5c209242011-06-06 20:36:17637 gfx::Rect window_bounds;
638 if (extension) {
639 window_bounds.set_width(extension->launch_width());
640 window_bounds.set_height(extension->launch_height());
641 }
[email protected]94ce7252010-12-20 21:46:33642
[email protected]5c209242011-06-06 20:36:17643 Browser* browser = Browser::CreateForApp(type, app_name, window_bounds,
[email protected]b35b26b32011-05-05 20:35:14644 profile);
[email protected]011396a2011-04-13 23:35:28645
[email protected]0e71e4152010-12-07 04:16:26646 if (app_browser)
647 *app_browser = browser;
648
[email protected]3c9e1872010-11-18 16:17:49649 TabContentsWrapper* wrapper =
[email protected]cecc93a2010-10-05 15:58:55650 browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
[email protected]3c9e1872010-11-18 16:17:49651 TabContents* contents = wrapper->tab_contents();
[email protected]cecc93a2010-10-05 15:58:55652 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
653 contents->render_view_host()->SyncRendererPrefs();
654 browser->window()->Show();
[email protected]bbadaa782010-04-28 21:21:53655
[email protected]68f009f2009-02-26 19:43:35656 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
657 // focus explicitly.
[email protected]cecc93a2010-10-05 15:58:55658 contents->view()->SetInitialFocus();
[email protected]0e71e4152010-12-07 04:16:26659 return contents;
660}
[email protected]eabfdae92009-12-11 06:13:51661
[email protected]0e71e4152010-12-07 04:16:26662TabContents* Browser::OpenAppShortcutWindow(Profile* profile,
663 const GURL& url,
664 bool update_shortcut) {
665 Browser* app_browser;
666 TabContents* tab = OpenApplicationWindow(
667 profile,
668 NULL, // this is a URL app. No extension.
669 extension_misc::LAUNCH_WINDOW,
670 url,
671 &app_browser);
672
673 if (!tab)
674 return NULL;
675
676 if (update_shortcut) {
[email protected]f45d2a72010-03-08 23:28:35677 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
678 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
679 // the web app info is available, TabContents notifies Browser via
[email protected]867a73e12010-03-19 20:45:46680 // OnDidGetApplicationInfo, which calls
681 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
682 // pending web app action.
[email protected]0e71e4152010-12-07 04:16:26683 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
[email protected]f45d2a72010-03-08 23:28:35684 }
[email protected]0e71e4152010-12-07 04:16:26685 return tab;
[email protected]c28071ad2010-03-12 17:28:56686}
687
688// static
[email protected]bbadaa782010-04-28 21:21:53689TabContents* Browser::OpenApplicationTab(Profile* profile,
[email protected]9adb9692010-10-29 23:14:02690 const Extension* extension,
[email protected]7e41c2b2011-05-06 10:31:16691 WindowOpenDisposition disposition) {
[email protected]b35b26b32011-05-05 20:35:14692 Browser* browser = BrowserList::FindTabbedBrowser(profile, false);
[email protected]cecc93a2010-10-05 15:58:55693 TabContents* contents = NULL;
[email protected]ea86bfb2011-02-08 18:15:44694 if (!browser)
[email protected]cecc93a2010-10-05 15:58:55695 return contents;
[email protected]c28071ad2010-03-12 17:28:56696
[email protected]10abd192010-09-30 02:03:49697 // Check the prefs for overridden mode.
[email protected]14908b72011-04-20 06:54:36698 ExtensionService* extension_service = profile->GetExtensionService();
699 DCHECK(extension_service);
[email protected]b283a7532010-08-12 21:24:59700
[email protected]10abd192010-09-30 02:03:49701 ExtensionPrefs::LaunchType launch_type =
[email protected]14908b72011-04-20 06:54:36702 extension_service->extension_prefs()->GetLaunchType(
[email protected]4e595682011-02-09 17:07:02703 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
[email protected]9b217652010-10-08 22:04:23704 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
[email protected]eaca0ad12011-04-18 15:53:41705 int add_type = TabStripModel::ADD_ACTIVE;
[email protected]10abd192010-09-30 02:03:49706 if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
707 add_type |= TabStripModel::ADD_PINNED;
708
[email protected]37fcf262011-01-26 19:39:15709 // For extensions lacking launch urls, determine a reasonable fallback.
710 GURL extension_url = extension->GetFullLaunchURL();
711 if (!extension_url.is_valid()) {
712 extension_url = extension->options_url();
713 if (!extension_url.is_valid())
714 extension_url = GURL(chrome::kChromeUIExtensionsURL);
715 }
716
[email protected]10abd192010-09-30 02:03:49717 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
718 // cases.
[email protected]37fcf262011-01-26 19:39:15719 browser::NavigateParams params(browser, extension_url,
[email protected]616381f02010-11-02 15:15:33720 PageTransition::START_PAGE);
721 params.tabstrip_add_types = add_type;
[email protected]7e41c2b2011-05-06 10:31:16722 params.disposition = disposition;
[email protected]24bf2022010-10-14 16:34:39723
[email protected]7e41c2b2011-05-06 10:31:16724 if (disposition == CURRENT_TAB) {
725 TabContents* existing_tab = browser->GetSelectedTabContents();
[email protected]24bf2022010-10-14 16:34:39726 TabStripModel* model = browser->tabstrip_model();
[email protected]3c9e1872010-11-18 16:17:49727 int tab_index = model->GetWrapperIndex(existing_tab);
[email protected]24bf2022010-10-14 16:34:39728
729 existing_tab->OpenURL(extension->GetFullLaunchURL(), existing_tab->GetURL(),
[email protected]7e41c2b2011-05-06 10:31:16730 disposition, PageTransition::LINK);
[email protected]616381f02010-11-02 15:15:33731 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
[email protected]24bf2022010-10-14 16:34:39732 model->SetTabPinned(tab_index, true);
[email protected]3c9e1872010-11-18 16:17:49733 tab_index = model->GetWrapperIndex(existing_tab);
[email protected]7dfec4212010-11-01 22:12:26734 }
[email protected]eaca0ad12011-04-18 15:53:41735 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
736 model->ActivateTabAt(tab_index, true);
[email protected]24bf2022010-10-14 16:34:39737
738 contents = existing_tab;
739 } else {
[email protected]616381f02010-11-02 15:15:33740 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:49741 contents = params.target_contents->tab_contents();
[email protected]24bf2022010-10-14 16:34:39742 }
743
[email protected]7bd42fc2011-02-09 17:32:42744 // TODO(skerner): If we are already in full screen mode, and the user
745 // set the app to open as a regular or pinned tab, what should happen?
746 // Today we open the tab, but stay in full screen mode. Should we leave
747 // full screen mode in this case?
748 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
749 !browser->window()->IsFullscreen())
750 browser->ToggleFullscreenMode();
[email protected]10abd192010-09-30 02:03:49751
[email protected]cecc93a2010-10-05 15:58:55752 return contents;
[email protected]c28071ad2010-03-12 17:28:56753}
754
755// static
[email protected]90a8bf252010-03-12 00:09:47756void Browser::OpenBookmarkManagerWindow(Profile* profile) {
757 Browser* browser = Browser::Create(profile);
[email protected]0af8f132011-07-16 01:37:02758 browser->OpenBookmarkManager();
[email protected]90a8bf252010-03-12 00:09:47759 browser->window()->Show();
760}
761
[email protected]057d959a2010-03-12 02:56:20762#if defined(OS_MACOSX)
[email protected]90a8bf252010-03-12 00:09:47763// static
[email protected]91a5b3e2009-10-30 19:32:22764void Browser::OpenHistoryWindow(Profile* profile) {
765 Browser* browser = Browser::Create(profile);
766 browser->ShowHistoryTab();
767 browser->window()->Show();
768}
769
770// static
771void Browser::OpenDownloadsWindow(Profile* profile) {
772 Browser* browser = Browser::Create(profile);
773 browser->ShowDownloadsTab();
774 browser->window()->Show();
775}
776
777// static
[email protected]1fdff702009-10-22 00:36:18778void Browser::OpenHelpWindow(Profile* profile) {
779 Browser* browser = Browser::Create(profile);
[email protected]202802e42011-07-06 11:40:46780 browser->ShowHelpTab();
[email protected]1fdff702009-10-22 00:36:18781 browser->window()->Show();
782}
[email protected]4a42d272010-06-18 01:29:42783
[email protected]eca258132010-11-15 23:33:08784// static
[email protected]4a42d272010-06-18 01:29:42785void Browser::OpenOptionsWindow(Profile* profile) {
786 Browser* browser = Browser::Create(profile);
[email protected]fee320542011-03-02 01:30:49787 browser->OpenOptionsDialog();
[email protected]4a42d272010-06-18 01:29:42788 browser->window()->Show();
789}
[email protected]c8de64a2011-01-25 17:10:23790
791// static
[email protected]ddddfda2011-07-14 23:19:39792void Browser::OpenClearBrowsingDataDialogWindow(Profile* profile) {
[email protected]c8de64a2011-01-25 17:10:23793 Browser* browser = Browser::Create(profile);
794 browser->OpenClearBrowsingDataDialog();
795 browser->window()->Show();
796}
797
798// static
799void Browser::OpenImportSettingsDialogWindow(Profile* profile) {
800 Browser* browser = Browser::Create(profile);
801 browser->OpenImportSettingsDialog();
802 browser->window()->Show();
803}
[email protected]b99081b2011-03-10 17:43:47804
805// static
806void Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
807 Browser* browser = Browser::Create(profile);
808 browser->OpenInstantConfirmDialog();
809 browser->window()->Show();
810}
[email protected]1fdff702009-10-22 00:36:18811#endif
812
[email protected]ccb55cf52010-03-06 22:02:04813// static
814void Browser::OpenExtensionsWindow(Profile* profile) {
815 Browser* browser = Browser::Create(profile);
816 browser->ShowExtensionsTab();
817 browser->window()->Show();
818}
819
[email protected]29d70252011-04-28 02:16:58820// static
821void Browser::NewWindowWithProfile(Profile* profile) {
822 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
823 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:15824 SessionServiceFactory::GetForProfile(profile->GetOriginalProfile());
[email protected]29d70252011-04-28 02:16:58825 if (!session_service ||
826 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
827 Browser::OpenEmptyWindow(profile->GetOriginalProfile());
828 }
829}
[email protected]ccb55cf52010-03-06 22:02:04830
[email protected]36b6dcb2008-11-12 01:19:57831///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:57832// Browser, State Storage and Retrieval for UI:
833
[email protected]57ecc4b2010-08-11 03:02:51834std::string Browser::GetWindowPlacementKey() const {
835 std::string name(prefs::kBrowserWindowPlacement);
[email protected]36b6dcb2008-11-12 01:19:57836 if (!app_name_.empty()) {
[email protected]57ecc4b2010-08-11 03:02:51837 name.append("_");
[email protected]36b6dcb2008-11-12 01:19:57838 name.append(app_name_);
839 }
[email protected]bc9a5152008-11-15 00:32:04840 return name;
841}
[email protected]36b6dcb2008-11-12 01:19:57842
[email protected]bc9a5152008-11-15 00:32:04843bool Browser::ShouldSaveWindowPlacement() const {
[email protected]b35b26b32011-05-05 20:35:14844 switch (type_) {
845 case TYPE_TABBED:
846 return true;
847 case TYPE_POPUP:
[email protected]bd6cdf22011-06-21 08:11:51848 // Only save the window placement of popups if they are restored,
849 // or the window belongs to DevTools.
850 return browser_defaults::kRestorePopups || is_devtools();
[email protected]b35b26b32011-05-05 20:35:14851 case TYPE_PANEL:
852 // Do not save the window placement of panels.
853 return false;
854 default:
855 return false;
856 }
[email protected]bc9a5152008-11-15 00:32:04857}
[email protected]36b6dcb2008-11-12 01:19:57858
[email protected]400eaf82011-08-22 15:47:39859void Browser::SaveWindowPlacement(const gfx::Rect& bounds,
860 ui::WindowShowState show_state) {
[email protected]bc9a5152008-11-15 00:32:04861 // Save to the session storage service, used when reloading a past session.
862 // Note that we don't want to be the ones who cause lazy initialization of
863 // the session service. This function gets called during initial window
864 // showing, and we don't want to bring in the session service this early.
[email protected]92371eb2011-04-28 11:50:15865 SessionService* session_service =
866 SessionServiceFactory::GetForProfileIfExisting(profile());
867 if (session_service)
[email protected]400eaf82011-08-22 15:47:39868 session_service->SetWindowBounds(session_id_, bounds, show_state);
[email protected]36b6dcb2008-11-12 01:19:57869}
870
[email protected]15952e462008-11-14 00:29:05871gfx::Rect Browser::GetSavedWindowBounds() const {
[email protected]bb975362009-01-21 01:00:22872 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]15952e462008-11-14 00:29:05873 bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
874 bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
875 if (record_mode || playback_mode) {
876 // In playback/record mode we always fix the size of the browser and
877 // move it to (0,0). The reason for this is two reasons: First we want
878 // resize/moves in the playback to still work, and Second we want
879 // playbacks to work (as much as possible) on machines w/ different
880 // screen sizes.
881 return gfx::Rect(0, 0, 800, 600);
882 }
883
884 gfx::Rect restored_bounds = override_bounds_;
885 bool maximized;
[email protected]f87919d72011-02-02 18:46:16886 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05887 &restored_bounds, &maximized);
888 return restored_bounds;
889}
890
891// TODO(beng): obtain maximized state some other way so we don't need to go
892// through all this hassle.
[email protected]400eaf82011-08-22 15:47:39893ui::WindowShowState Browser::GetSavedWindowShowState() const {
[email protected]bb975362009-01-21 01:00:22894 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
[email protected]400eaf82011-08-22 15:47:39895 return ui::SHOW_STATE_MAXIMIZED;
[email protected]15952e462008-11-14 00:29:05896
[email protected]400eaf82011-08-22 15:47:39897 if (show_state_ != ui::SHOW_STATE_DEFAULT)
898 return show_state_;
[email protected]2e716622009-03-09 21:11:01899
900 // An explicit maximized state was not set. Query the window sizer.
[email protected]15952e462008-11-14 00:29:05901 gfx::Rect restored_bounds;
[email protected]2e716622009-03-09 21:11:01902 bool maximized = false;
[email protected]f87919d72011-02-02 18:46:16903 WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
[email protected]15952e462008-11-14 00:29:05904 &restored_bounds, &maximized);
[email protected]400eaf82011-08-22 15:47:39905 return maximized ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
[email protected]36b6dcb2008-11-12 01:19:57906}
907
908SkBitmap Browser::GetCurrentPageIcon() const {
[email protected]b375c5d2011-05-03 21:15:04909 TabContentsWrapper* contents = GetSelectedTabContentsWrapper();
[email protected]ce5348a82008-12-18 18:36:23910 // |contents| can be NULL since GetCurrentPageIcon() is called by the window
911 // during the window's creation (before tabs have been added).
[email protected]b375c5d2011-05-03 21:15:04912 return contents ? contents->favicon_tab_helper()->GetFavicon() : SkBitmap();
[email protected]36b6dcb2008-11-12 01:19:57913}
914
[email protected]731f8a42009-07-20 22:07:32915string16 Browser::GetWindowTitleForCurrentTab() const {
[email protected]3c9e1872010-11-18 16:17:49916 TabContents* contents = GetSelectedTabContents();
[email protected]dda5dfa32009-07-10 00:33:29917 string16 title;
[email protected]c7c42332008-11-15 01:10:54918
[email protected]731f8a42009-07-20 22:07:32919 // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
920 // window during the window's creation (before tabs have been added).
[email protected]36b6dcb2008-11-12 01:19:57921 if (contents) {
[email protected]dda5dfa32009-07-10 00:33:29922 title = contents->GetTitle();
[email protected]36b6dcb2008-11-12 01:19:57923 FormatTitleForDisplay(&title);
924 }
925 if (title.empty())
[email protected]0dd3a0ab2011-02-18 08:17:44926 title = TabContentsWrapper::GetDefaultTitle();
[email protected]36b6dcb2008-11-12 01:19:57927
[email protected]16779842009-07-08 23:45:29928#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
[email protected]22a3daa2009-11-09 22:03:33929 // On Mac or ChromeOS, we don't want to suffix the page title with
930 // the application name.
[email protected]d904bc82009-07-07 00:41:04931 return title;
[email protected]7be64502011-05-03 17:51:47932#else
[email protected]edb5e6a2009-04-08 23:46:17933 int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
[email protected]dff529732010-04-01 23:50:55934 // Don't append the app name to window titles on app frames and app popups
[email protected]b35b26b32011-05-05 20:35:14935 if (is_app())
[email protected]edb5e6a2009-04-08 23:46:17936 string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
[email protected]dda5dfa32009-07-10 00:33:29937 return l10n_util::GetStringFUTF16(string_id, title);
[email protected]57e68dba2009-05-15 21:30:50938#endif
[email protected]36b6dcb2008-11-12 01:19:57939}
940
941// static
[email protected]dda5dfa32009-07-10 00:33:29942void Browser::FormatTitleForDisplay(string16* title) {
[email protected]36b6dcb2008-11-12 01:19:57943 size_t current_index = 0;
944 size_t match_index;
[email protected]57ecc4b2010-08-11 03:02:51945 while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
[email protected]810a52ef2010-01-08 01:22:15946 title->replace(match_index, 1, string16());
[email protected]36b6dcb2008-11-12 01:19:57947 current_index = match_index;
948 }
949}
950
951///////////////////////////////////////////////////////////////////////////////
952// Browser, OnBeforeUnload handling:
953
[email protected]460a2942010-12-15 19:43:15954bool Browser::TabsNeedBeforeUnloadFired() {
955 if (tabs_needing_before_unload_fired_.empty()) {
956 for (int i = 0; i < tab_count(); ++i) {
957 TabContents* contents = GetTabContentsAt(i);
958 if (contents->NeedToFireBeforeUnload())
959 tabs_needing_before_unload_fired_.insert(contents);
960 }
961 }
962 return !tabs_needing_before_unload_fired_.empty();
963}
964
[email protected]36b6dcb2008-11-12 01:19:57965bool Browser::ShouldCloseWindow() {
[email protected]69444cc2009-04-09 20:40:06966 if (!CanCloseWithInProgressDownloads())
967 return false;
968
969 if (HasCompletedUnloadProcessing())
[email protected]0b4d3382010-07-14 16:13:04970 return IsClosingPermitted();
[email protected]69444cc2009-04-09 20:40:06971
[email protected]36b6dcb2008-11-12 01:19:57972 is_attempting_to_close_browser_ = true;
973
[email protected]460a2942010-12-15 19:43:15974 if (!TabsNeedBeforeUnloadFired())
[email protected]0b4d3382010-07-14 16:13:04975 return IsClosingPermitted();
[email protected]36b6dcb2008-11-12 01:19:57976
977 ProcessPendingTabs();
978 return false;
979}
980
981void Browser::OnWindowClosing() {
982 if (!ShouldCloseWindow())
983 return;
984
[email protected]911f8152010-03-18 16:46:40985 bool exiting = false;
986
[email protected]c984d9f2010-07-20 20:52:20987 // Application should shutdown on last window close if the user is explicitly
988 // trying to quit, or if there is nothing keeping the browser alive (such as
989 // AppController on the Mac, or BackgroundContentsService for background
990 // pages).
991 bool should_quit_if_last_browser =
992 browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
[email protected]7dc8c6b2010-04-09 17:02:50993
994 if (should_quit_if_last_browser && BrowserList::size() == 1) {
[email protected]36b6dcb2008-11-12 01:19:57995 browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
[email protected]911f8152010-03-18 16:46:40996 exiting = true;
997 }
[email protected]36b6dcb2008-11-12 01:19:57998
[email protected]92371eb2011-04-28 11:50:15999 // Don't use GetForProfileIfExisting here, we want to force creation of the
[email protected]36b6dcb2008-11-12 01:19:571000 // session service so that user can restore what was open.
[email protected]92371eb2011-04-28 11:50:151001 SessionService* session_service =
1002 SessionServiceFactory::GetForProfile(profile());
[email protected]36b6dcb2008-11-12 01:19:571003 if (session_service)
1004 session_service->WindowClosing(session_id());
1005
[email protected]92371eb2011-04-28 11:50:151006 TabRestoreService* tab_restore_service =
1007 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]b35b26b32011-05-05 20:35:141008 if (tab_restore_service && is_type_tabbed() && tab_count())
[email protected]fb7da4132011-03-15 15:51:001009 tab_restore_service->BrowserClosing(tab_restore_service_delegate());
[email protected]d8375fd2008-11-25 22:45:391010
[email protected]911f8152010-03-18 16:46:401011 // TODO(sky): convert session/tab restore to use notification.
1012 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:271013 chrome::NOTIFICATION_BROWSER_CLOSING,
[email protected]911f8152010-03-18 16:46:401014 Source<Browser>(this),
1015 Details<bool>(&exiting));
1016
[email protected]36b6dcb2008-11-12 01:19:571017 CloseAllTabs();
1018}
1019
[email protected]28788c7d2011-05-20 23:03:451020void Browser::OnWindowActivated() {
1021 // On some platforms we want to automatically reload tabs that are
1022 // killed when the user selects them.
1023 TabContents* contents = GetSelectedTabContents();
1024 if (contents && contents->crashed_status() ==
1025 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
1026 if (CommandLine::ForCurrentProcess()->HasSwitch(
1027 switches::kReloadKilledTabs)) {
1028 Reload(CURRENT_TAB);
1029 }
1030 }
1031}
1032
[email protected]69444cc2009-04-09 20:40:061033////////////////////////////////////////////////////////////////////////////////
1034// In-progress download termination handling:
1035
1036void Browser::InProgressDownloadResponse(bool cancel_downloads) {
1037 if (cancel_downloads) {
1038 cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
1039 CloseWindow();
1040 return;
1041 }
1042
1043 // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
1044 // close again we'll show the warning again.
1045 cancel_download_confirmation_state_ = NOT_PROMPTED;
1046
1047 // Show the download page so the user can figure-out what downloads are still
1048 // in-progress.
1049 ShowDownloadsTab();
1050}
1051
[email protected]69444cc2009-04-09 20:40:061052////////////////////////////////////////////////////////////////////////////////
[email protected]c848d3d92010-09-16 21:57:451053// Browser, TabStripModel pass-thrus:
1054
1055int Browser::tab_count() const {
[email protected]ecc523f62010-09-28 22:45:401056 return tab_handler_->GetTabStripModel()->count();
[email protected]c848d3d92010-09-16 21:57:451057}
1058
[email protected]1ea49d52011-04-12 17:44:441059int Browser::active_index() const {
1060 return tab_handler_->GetTabStripModel()->active_index();
[email protected]c848d3d92010-09-16 21:57:451061}
1062
1063int Browser::GetIndexOfController(
1064 const NavigationController* controller) const {
[email protected]ecc523f62010-09-28 22:45:401065 return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
[email protected]c848d3d92010-09-16 21:57:451066}
1067
[email protected]3c9e1872010-11-18 16:17:491068TabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
[email protected]fb7e74922011-06-09 01:39:421069 return tabstrip_model()->GetActiveTabContents();
[email protected]3c9e1872010-11-18 16:17:491070}
[email protected]b375c5d2011-05-03 21:15:041071
[email protected]3c9e1872010-11-18 16:17:491072TabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
1073 return tabstrip_model()->GetTabContentsAt(index);
[email protected]c848d3d92010-09-16 21:57:451074}
1075
1076TabContents* Browser::GetSelectedTabContents() const {
[email protected]3c9e1872010-11-18 16:17:491077 TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
1078 if (wrapper)
1079 return wrapper->tab_contents();
1080 return NULL;
1081}
1082
1083TabContents* Browser::GetTabContentsAt(int index) const {
1084 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
1085 if (wrapper)
1086 return wrapper->tab_contents();
1087 return NULL;
[email protected]c848d3d92010-09-16 21:57:451088}
1089
[email protected]eaca0ad12011-04-18 15:53:411090void Browser::ActivateTabAt(int index, bool user_gesture) {
1091 tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
[email protected]c848d3d92010-09-16 21:57:451092}
1093
[email protected]fb7da4132011-03-15 15:51:001094bool Browser::IsTabPinned(int index) const {
1095 return tabstrip_model()->IsTabPinned(index);
1096}
1097
[email protected]c848d3d92010-09-16 21:57:451098void Browser::CloseAllTabs() {
[email protected]ecc523f62010-09-28 22:45:401099 tab_handler_->GetTabStripModel()->CloseAllTabs();
[email protected]c848d3d92010-09-16 21:57:451100}
1101
1102////////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:571103// Browser, Tab adding/showing functions:
1104
[email protected]95bf8a5b2010-12-22 16:04:071105bool Browser::IsTabStripEditable() const {
1106 return window()->IsTabStripEditable();
1107}
1108
[email protected]b3344872010-05-03 15:52:291109int Browser::GetIndexForInsertionDuringRestore(int relative_index) {
[email protected]ecc523f62010-09-28 22:45:401110 return (tab_handler_->GetTabStripModel()->insertion_policy() ==
1111 TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
[email protected]b3344872010-05-03 15:52:291112}
1113
[email protected]3c9e1872010-11-18 16:17:491114TabContentsWrapper* Browser::AddSelectedTabWithURL(const GURL& url,
[email protected]cecc93a2010-10-05 15:58:551115 PageTransition::Type transition) {
[email protected]616381f02010-11-02 15:15:331116 browser::NavigateParams params(this, url, transition);
1117 params.disposition = NEW_FOREGROUND_TAB;
1118 browser::Navigate(&params);
1119 return params.target_contents;
[email protected]36b6dcb2008-11-12 01:19:571120}
1121
[email protected]3c9e1872010-11-18 16:17:491122TabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
[email protected]d99cdfd2009-10-08 18:58:111123 PageTransition::Type type) {
[email protected]ecc523f62010-09-28 22:45:401124 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]eaca0ad12011-04-18 15:53:411125 tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
[email protected]3c9e1872010-11-18 16:17:491126 return tab_contents->tab_contents();
[email protected]36b6dcb2008-11-12 01:19:571127}
1128
[email protected]e0c7c262009-04-23 23:09:431129void Browser::AddTabContents(TabContents* new_contents,
1130 WindowOpenDisposition disposition,
1131 const gfx::Rect& initial_pos,
1132 bool user_gesture) {
1133 AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1134}
1135
1136void Browser::CloseTabContents(TabContents* contents) {
1137 CloseContents(contents);
1138}
1139
[email protected]b86451c2011-08-16 02:13:441140gfx::NativeWindow Browser::BrowserShowHtmlDialog(
1141 HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window) {
1142 return window_->ShowHTMLDialog(delegate, parent_window);
[email protected]e0c7c262009-04-23 23:09:431143}
1144
1145void Browser::BrowserRenderWidgetShowing() {
1146 RenderWidgetShowing();
1147}
1148
[email protected]c9bd2e82011-04-15 23:28:191149void Browser::BookmarkBarSizeChanged(bool is_animating) {
1150 window_->ToolbarSizeChanged(is_animating);
[email protected]e0c7c262009-04-23 23:09:431151}
1152
[email protected]ce3fa3c2009-04-20 19:55:571153TabContents* Browser::AddRestoredTab(
[email protected]36b6dcb2008-11-12 01:19:571154 const std::vector<TabNavigation>& navigations,
1155 int tab_index,
1156 int selected_navigation,
[email protected]98aa0b52010-05-06 17:03:081157 const std::string& extension_app_id,
[email protected]5c0e6482009-07-14 20:20:091158 bool select,
[email protected]5e369672009-11-03 23:48:301159 bool pin,
[email protected]6ee12c42010-09-14 09:36:071160 bool from_last_session,
1161 SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041162 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1163 TabContentsWrapper* wrapper = TabContentsFactory(
1164 profile(),
1165 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]3c9e1872010-11-18 16:17:491166 MSG_ROUTING_NONE,
1167 GetSelectedTabContents(),
[email protected]ecc523f62010-09-28 22:45:401168 session_storage_namespace);
[email protected]3c9e1872010-11-18 16:17:491169 TabContents* new_tab = wrapper->tab_contents();
[email protected]36fb2c7c2011-04-04 15:49:081170 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]03838e22011-06-06 15:27:141171 std::vector<NavigationEntry*> entries;
1172 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1173 profile_, navigations, &entries);
1174 new_tab->controller().Restore(
1175 selected_navigation, from_last_session, &entries);
1176 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571177
[email protected]eaca0ad12011-04-18 15:53:411178 int add_types = select ? TabStripModel::ADD_ACTIVE :
[email protected]981b992e2011-03-28 21:05:211179 TabStripModel::ADD_NONE;
1180 if (pin) {
1181 tab_index = std::min(tab_index, tabstrip_model()->IndexOfFirstNonMiniTab());
1182 add_types |= TabStripModel::ADD_PINNED;
1183 }
1184 tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1185 add_types);
[email protected]c93a9dd2010-04-22 20:25:181186 if (select) {
[email protected]77bc6732009-04-20 22:01:031187 window_->Activate();
[email protected]c93a9dd2010-04-22 20:25:181188 } else {
1189 // We set the size of the view here, before WebKit does its initial
1190 // layout. If we don't, the initial layout of background tabs will be
1191 // performed with a view width of 0, which may cause script outputs and
1192 // anchor link location calculations to be incorrect even after a new
1193 // layout with proper view dimensions. TabStripModel::AddTabContents()
1194 // contains similar logic.
1195 new_tab->view()->SizeContents(window_->GetRestoredBounds().size());
1196 new_tab->HideContents();
1197 }
[email protected]92371eb2011-04-28 11:50:151198 SessionService* session_service =
1199 SessionServiceFactory::GetForProfileIfExisting(profile_);
1200 if (session_service)
[email protected]81898992011-06-14 22:15:001201 session_service->TabRestored(wrapper, pin);
[email protected]ce3fa3c2009-04-20 19:55:571202 return new_tab;
[email protected]36b6dcb2008-11-12 01:19:571203}
1204
1205void Browser::ReplaceRestoredTab(
1206 const std::vector<TabNavigation>& navigations,
[email protected]5e369672009-11-03 23:48:301207 int selected_navigation,
[email protected]fca656c2010-02-10 20:30:101208 bool from_last_session,
[email protected]6ee12c42010-09-14 09:36:071209 const std::string& extension_app_id,
1210 SessionStorageNamespace* session_storage_namespace) {
[email protected]1ab4ddf2011-07-21 04:48:041211 GURL restore_url = navigations.at(selected_navigation).virtual_url();
1212 TabContentsWrapper* wrapper = TabContentsFactory(
1213 profile(),
1214 tab_util::GetSiteInstanceForNewTab(NULL, profile_, restore_url),
[email protected]ecc523f62010-09-28 22:45:401215 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:491216 GetSelectedTabContents(),
[email protected]6ee12c42010-09-14 09:36:071217 session_storage_namespace);
[email protected]36fb2c7c2011-04-04 15:49:081218 wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
[email protected]3c9e1872010-11-18 16:17:491219 TabContents* replacement = wrapper->tab_contents();
[email protected]03838e22011-06-06 15:27:141220 std::vector<NavigationEntry*> entries;
1221 TabNavigation::CreateNavigationEntriesFromTabNavigations(
1222 profile_, navigations, &entries);
1223 replacement->controller().Restore(
1224 selected_navigation, from_last_session, &entries);
1225 DCHECK_EQ(0u, entries.size());
[email protected]36b6dcb2008-11-12 01:19:571226
[email protected]ecc523f62010-09-28 22:45:401227 tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
[email protected]1ea49d52011-04-12 17:44:441228 tab_handler_->GetTabStripModel()->active_index(),
[email protected]3c9e1872010-11-18 16:17:491229 wrapper);
[email protected]36b6dcb2008-11-12 01:19:571230}
1231
[email protected]a8eff102009-04-14 15:23:431232bool Browser::CanRestoreTab() {
[email protected]281918912010-05-27 22:05:131233 return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
[email protected]a8eff102009-04-14 15:23:431234}
1235
[email protected]3698f172010-03-17 20:50:291236bool Browser::NavigateToIndexWithDisposition(int index,
1237 WindowOpenDisposition disp) {
1238 NavigationController& controller =
[email protected]cb84d642010-06-10 00:56:281239 GetOrCloneTabForDisposition(disp)->controller();
1240 if (index < 0 || index >= controller.entry_count())
[email protected]3698f172010-03-17 20:50:291241 return false;
[email protected]cb84d642010-06-10 00:56:281242 controller.GoToIndex(index);
1243 return true;
[email protected]3698f172010-03-17 20:50:291244}
1245
[email protected]fee320542011-03-02 01:30:491246browser::NavigateParams Browser::GetSingletonTabNavigateParams(
1247 const GURL& url) {
[email protected]616381f02010-11-02 15:15:331248 browser::NavigateParams params(this, url, PageTransition::AUTO_BOOKMARK);
1249 params.disposition = SINGLETON_TAB;
[email protected]7d329992011-04-15 18:20:021250 params.window_action = browser::NavigateParams::SHOW_WINDOW;
[email protected]588300d2011-04-28 21:06:351251 params.user_gesture = true;
[email protected]fee320542011-03-02 01:30:491252 return params;
1253}
1254
1255void Browser::ShowSingletonTab(const GURL& url) {
1256 browser::NavigateParams params(GetSingletonTabNavigateParams(url));
[email protected]616381f02010-11-02 15:15:331257 browser::Navigate(&params);
[email protected]36b6dcb2008-11-12 01:19:571258}
[email protected]d938aed92009-01-22 19:49:331259
[email protected]ddddfda2011-07-14 23:19:391260void Browser::ShowSingletonTabOverwritingNTP(
1261 const browser::NavigateParams& params) {
1262 browser::NavigateParams local_params(params);
1263 TabContents* contents = GetSelectedTabContents();
[email protected]842a648c2011-07-20 23:23:161264 if (contents) {
1265 const GURL& contents_url = contents->GetURL();
1266 if ((contents_url == GURL(chrome::kChromeUINewTabURL) ||
1267 contents_url == GURL(chrome::kAboutBlankURL)) &&
1268 browser::GetIndexOfSingletonTab(&local_params) < 0) {
1269 local_params.disposition = CURRENT_TAB;
1270 }
[email protected]ddddfda2011-07-14 23:19:391271 }
1272
1273 browser::Navigate(&local_params);
1274}
1275
[email protected]227393e2011-06-29 21:28:391276void Browser::WindowFullscreenStateChanged() {
1277 UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1278 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
[email protected]ae2622c2009-07-30 23:47:581279}
1280
[email protected]36b6dcb2008-11-12 01:19:571281///////////////////////////////////////////////////////////////////////////////
1282// Browser, Assorted browser commands:
1283
[email protected]cb84d642010-06-10 00:56:281284TabContents* Browser::GetOrCloneTabForDisposition(
[email protected]3698f172010-03-17 20:50:291285 WindowOpenDisposition disposition) {
[email protected]3c9e1872010-11-18 16:17:491286 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]bbafdc72011-07-06 22:27:171287 switch (disposition) {
1288 case NEW_FOREGROUND_TAB:
1289 case NEW_BACKGROUND_TAB: {
1290 current_tab = current_tab->Clone();
1291 tab_handler_->GetTabStripModel()->AddTabContents(
1292 current_tab, -1, PageTransition::LINK,
1293 disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
1294 TabStripModel::ADD_NONE);
1295 break;
1296 }
1297 case NEW_WINDOW: {
1298 current_tab = current_tab->Clone();
1299 Browser* browser = Browser::Create(profile_);
1300 browser->tabstrip_model()->AddTabContents(
1301 current_tab, -1, PageTransition::LINK, TabStripModel::ADD_ACTIVE);
1302 browser->window()->Show();
1303 break;
1304 }
1305 default:
1306 break;
[email protected]3698f172010-03-17 20:50:291307 }
[email protected]3c9e1872010-11-18 16:17:491308 return current_tab->tab_contents();
[email protected]3698f172010-03-17 20:50:291309}
1310
[email protected]b3344872010-05-03 15:52:291311void Browser::UpdateTabStripModelInsertionPolicy() {
[email protected]ecc523f62010-09-28 22:45:401312 tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
[email protected]b3344872010-05-03 15:52:291313 TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
1314}
1315
1316void Browser::UseVerticalTabsChanged() {
1317 UpdateTabStripModelInsertionPolicy();
1318 window()->ToggleTabStripMode();
1319}
1320
[email protected]ac86c982011-05-11 13:26:051321void Browser::UseCompactNavigationBarChanged() {
1322 window_->ToggleUseCompactNavigationBar();
1323}
1324
[email protected]018cf362010-05-05 22:43:221325bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1326 bool check_fullscreen) const {
1327 // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1328 // other platforms, we hide some controls when in fullscreen mode.
1329 bool hide_ui_for_fullscreen = false;
1330#if !defined(OS_MACOSX)
1331 hide_ui_for_fullscreen = check_fullscreen && window_ &&
1332 window_->IsFullscreen();
1333#endif
1334
[email protected]8b8e7c92010-08-19 18:05:561335 unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
[email protected]018cf362010-05-05 22:43:221336
1337#if !defined(OS_CHROMEOS)
1338 // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1339 // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1340 features |= FEATURE_DOWNLOADSHELF;
1341#endif // !defined(OS_CHROMEOS)
1342
[email protected]b35b26b32011-05-05 20:35:141343 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221344 features |= FEATURE_BOOKMARKBAR;
[email protected]018cf362010-05-05 22:43:221345
1346 if (!hide_ui_for_fullscreen) {
[email protected]b35b26b32011-05-05 20:35:141347 if (!is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221348 features |= FEATURE_TITLEBAR;
1349
[email protected]b35b26b32011-05-05 20:35:141350 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221351 features |= FEATURE_TABSTRIP;
1352
[email protected]b35b26b32011-05-05 20:35:141353 if (is_type_tabbed())
[email protected]018cf362010-05-05 22:43:221354 features |= FEATURE_TOOLBAR;
1355
[email protected]b35b26b32011-05-05 20:35:141356 if (!is_app())
[email protected]018cf362010-05-05 22:43:221357 features |= FEATURE_LOCATIONBAR;
1358 }
1359 return !!(features & feature);
1360}
1361
[email protected]0b4d3382010-07-14 16:13:041362bool Browser::IsClosingPermitted() {
1363 TabCloseableStateWatcher* watcher =
1364 g_browser_process->tab_closeable_state_watcher();
1365 bool can_close = !watcher || watcher->CanCloseBrowser(this);
1366 if (!can_close && is_attempting_to_close_browser_)
1367 CancelWindowClose();
1368 return can_close;
1369}
1370
[email protected]43c9dc722011-08-20 02:05:091371bool Browser::CanGoBack() const {
1372 return GetSelectedTabContentsWrapper()->controller().CanGoBack();
1373}
1374
[email protected]485fba42009-03-24 23:27:291375void Browser::GoBack(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591376 UserMetrics::RecordAction(UserMetricsAction("Back"));
[email protected]fbd77592008-11-12 20:50:271377
[email protected]3c9e1872010-11-18 16:17:491378 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
[email protected]43c9dc722011-08-20 02:05:091379 if (CanGoBack()) {
[email protected]cb84d642010-06-10 00:56:281380 TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
[email protected]d497b0782010-03-29 19:19:061381 // If we are on an interstitial page and clone the tab, it won't be copied
1382 // to the new tab, so we don't need to go back.
[email protected]3c9e1872010-11-18 16:17:491383 if (current_tab->tab_contents()->showing_interstitial_page() &&
1384 (new_tab != current_tab->tab_contents()))
[email protected]d497b0782010-03-29 19:19:061385 return;
[email protected]cb84d642010-06-10 00:56:281386 new_tab->controller().GoBack();
[email protected]485fba42009-03-24 23:27:291387 }
[email protected]36b6dcb2008-11-12 01:19:571388}
1389
[email protected]43c9dc722011-08-20 02:05:091390bool Browser::CanGoForward() const {
1391 return GetSelectedTabContentsWrapper()->controller().CanGoForward();
1392}
1393
[email protected]3698f172010-03-17 20:50:291394void Browser::GoForward(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591395 UserMetrics::RecordAction(UserMetricsAction("Forward"));
[email protected]43c9dc722011-08-20 02:05:091396 if (CanGoForward())
[email protected]cb84d642010-06-10 00:56:281397 GetOrCloneTabForDisposition(disposition)->controller().GoForward();
[email protected]36b6dcb2008-11-12 01:19:571398}
1399
[email protected]cb84d642010-06-10 00:56:281400void Browser::Reload(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591401 UserMetrics::RecordAction(UserMetricsAction("Reload"));
[email protected]cb84d642010-06-10 00:56:281402 ReloadInternal(disposition, false);
[email protected]1ccb3568d2010-02-19 10:51:161403}
[email protected]fbd77592008-11-12 20:50:271404
[email protected]cb84d642010-06-10 00:56:281405void Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591406 UserMetrics::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
[email protected]cb84d642010-06-10 00:56:281407 ReloadInternal(disposition, true);
[email protected]1ccb3568d2010-02-19 10:51:161408}
1409
[email protected]cb84d642010-06-10 00:56:281410void Browser::ReloadInternal(WindowOpenDisposition disposition,
1411 bool ignore_cache) {
[email protected]36b6dcb2008-11-12 01:19:571412 // If we are showing an interstitial, treat this as an OpenURL.
1413 TabContents* current_tab = GetSelectedTabContents();
[email protected]cb84d642010-06-10 00:56:281414 if (current_tab && current_tab->showing_interstitial_page()) {
1415 NavigationEntry* entry = current_tab->controller().GetActiveEntry();
1416 DCHECK(entry); // Should exist if interstitial is showing.
1417 OpenURL(entry->url(), GURL(), disposition, PageTransition::RELOAD);
1418 return;
[email protected]36b6dcb2008-11-12 01:19:571419 }
[email protected]cb84d642010-06-10 00:56:281420
1421 // As this is caused by a user action, give the focus to the page.
[email protected]3c9e1872010-11-18 16:17:491422 TabContents* tab = GetOrCloneTabForDisposition(disposition);
1423 if (!tab->FocusLocationBarByDefault())
1424 tab->Focus();
[email protected]cb84d642010-06-10 00:56:281425 if (ignore_cache)
[email protected]3c9e1872010-11-18 16:17:491426 tab->controller().ReloadIgnoringCache(true);
[email protected]cb84d642010-06-10 00:56:281427 else
[email protected]3c9e1872010-11-18 16:17:491428 tab->controller().Reload(true);
[email protected]36b6dcb2008-11-12 01:19:571429}
1430
[email protected]485fba42009-03-24 23:27:291431void Browser::Home(WindowOpenDisposition disposition) {
[email protected]afd1e522011-04-27 23:29:591432 UserMetrics::RecordAction(UserMetricsAction("Home"));
[email protected]485fba42009-03-24 23:27:291433 OpenURL(GetHomePage(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
[email protected]36b6dcb2008-11-12 01:19:571434}
1435
[email protected]fbd77592008-11-12 20:50:271436void Browser::OpenCurrentURL() {
[email protected]afd1e522011-04-27 23:29:591437 UserMetrics::RecordAction(UserMetricsAction("LoadURL"));
[email protected]7745b822009-01-27 20:15:351438 LocationBar* location_bar = window_->GetLocationBar();
[email protected]9800de5e2011-03-11 18:19:491439 if (!location_bar)
1440 return;
1441
[email protected]9d0306ea2009-09-02 19:38:391442 WindowOpenDisposition open_disposition =
1443 location_bar->GetWindowOpenDisposition();
[email protected]6b723f82010-10-05 20:14:271444 if (OpenInstant(open_disposition))
[email protected]03bb953d2010-09-14 21:38:301445 return;
[email protected]03bb953d2010-09-14 21:38:301446
[email protected]537de682011-08-08 18:10:141447 GURL url(location_bar->GetInputString());
[email protected]07d490bc2011-03-07 17:05:261448
1449 if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1450 Browser* existing_browser = NULL;
1451 TabContents* existing_tab = TabFinder::GetInstance()->FindTab(
1452 this, url, &existing_browser);
1453 if (existing_tab) {
1454 existing_browser->ActivateContents(existing_tab);
1455 return;
1456 }
1457 }
1458
[email protected]616381f02010-11-02 15:15:331459 browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1460 params.disposition = open_disposition;
[email protected]514576a2010-07-01 22:51:251461 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1462 // inherit the opener. In some cases the tabstrip will determine the group
1463 // should be inherited, in which case the group is inherited instead of the
1464 // opener.
[email protected]616381f02010-11-02 15:15:331465 params.tabstrip_add_types =
1466 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1467 browser::Navigate(&params);
[email protected]46fd1ea42011-02-16 15:59:331468
[email protected]6e37fe32011-03-02 09:06:521469 DCHECK(profile_->GetExtensionService());
1470 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:331471 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1472 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1473 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1474 }
[email protected]fbd77592008-11-12 20:50:271475}
1476
[email protected]84214982008-12-10 18:49:101477void Browser::Stop() {
[email protected]afd1e522011-04-27 23:29:591478 UserMetrics::RecordAction(UserMetricsAction("Stop"));
[email protected]3c9e1872010-11-18 16:17:491479 GetSelectedTabContentsWrapper()->tab_contents()->Stop();
[email protected]84214982008-12-10 18:49:101480}
1481
1482void Browser::NewWindow() {
[email protected]4e94ab32011-08-05 05:28:271483 IncognitoModePrefs::Availability incognito_avail =
1484 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
[email protected]047e7272010-06-03 19:53:351485 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
[email protected]4e94ab32011-08-05 05:28:271486 incognito_avail != IncognitoModePrefs::DISABLED &&
[email protected]6b0dd2ab2011-07-26 02:31:081487 (CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito) ||
[email protected]4e94ab32011-08-05 05:28:271488 incognito_avail == IncognitoModePrefs::FORCED)) {
[email protected]047e7272010-06-03 19:53:351489 NewIncognitoWindow();
1490 return;
1491 }
[email protected]afd1e522011-04-27 23:29:591492 UserMetrics::RecordAction(UserMetricsAction("NewWindow"));
[email protected]c9b19942010-03-26 15:58:081493 SessionService* session_service =
[email protected]92371eb2011-04-28 11:50:151494 SessionServiceFactory::GetForProfile(profile_->GetOriginalProfile());
[email protected]c9b19942010-03-26 15:58:081495 if (!session_service ||
1496 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1497 Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1498 }
[email protected]84214982008-12-10 18:49:101499}
1500
1501void Browser::NewIncognitoWindow() {
[email protected]4e94ab32011-08-05 05:28:271502 if (IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) ==
1503 IncognitoModePrefs::DISABLED) {
[email protected]6e6f6cb2011-01-27 13:26:551504 NewWindow();
1505 return;
1506 }
1507
[email protected]afd1e522011-04-27 23:29:591508 UserMetrics::RecordAction(UserMetricsAction("NewIncognitoWindow"));
[email protected]84214982008-12-10 18:49:101509 Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1510}
1511
[email protected]84214982008-12-10 18:49:101512void Browser::CloseWindow() {
[email protected]afd1e522011-04-27 23:29:591513 UserMetrics::RecordAction(UserMetricsAction("CloseWindow"));
[email protected]84214982008-12-10 18:49:101514 window_->Close();
1515}
1516
[email protected]fbd77592008-11-12 20:50:271517void Browser::NewTab() {
[email protected]afd1e522011-04-27 23:29:591518 UserMetrics::RecordAction(UserMetricsAction("NewTab"));
[email protected]b7969202010-05-14 21:29:261519
[email protected]b35b26b32011-05-05 20:35:141520 if (is_type_tabbed()) {
[email protected]fbd77592008-11-12 20:50:271521 AddBlankTab(true);
[email protected]49bb7ea32011-02-02 17:58:061522 GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271523 } else {
[email protected]1a6b30a2009-08-19 03:52:111524 Browser* b = GetOrCreateTabbedBrowser(profile_);
[email protected]fbd77592008-11-12 20:50:271525 b->AddBlankTab(true);
[email protected]15952e462008-11-14 00:29:051526 b->window()->Show();
[email protected]e54f30d2009-01-14 21:17:111527 // The call to AddBlankTab above did not set the focus to the tab as its
1528 // window was not active, so we have to do it explicitly.
1529 // See http://crbug.com/6380.
[email protected]3c9e1872010-11-18 16:17:491530 b->GetSelectedTabContentsWrapper()->view()->RestoreFocus();
[email protected]fbd77592008-11-12 20:50:271531 }
1532}
1533
1534void Browser::CloseTab() {
[email protected]afd1e522011-04-27 23:29:591535 UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
[email protected]90b1a7a2011-03-17 21:28:211536 if (CanCloseTab())
1537 tab_handler_->GetTabStripModel()->CloseSelectedTabs();
[email protected]fbd77592008-11-12 20:50:271538}
1539
[email protected]fbd77592008-11-12 20:50:271540void Browser::SelectNextTab() {
[email protected]afd1e522011-04-27 23:29:591541 UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"));
[email protected]ecc523f62010-09-28 22:45:401542 tab_handler_->GetTabStripModel()->SelectNextTab();
[email protected]fbd77592008-11-12 20:50:271543}
1544
1545void Browser::SelectPreviousTab() {
[email protected]afd1e522011-04-27 23:29:591546 UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"));
[email protected]ecc523f62010-09-28 22:45:401547 tab_handler_->GetTabStripModel()->SelectPreviousTab();
[email protected]fbd77592008-11-12 20:50:271548}
1549
[email protected]91ac9202010-07-30 18:32:351550void Browser::OpenTabpose() {
1551#if defined(OS_MACOSX)
[email protected]aac169d2011-03-18 19:53:031552 if (!CommandLine::ForCurrentProcess()->HasSwitch(
1553 switches::kEnableExposeForTabs)) {
1554 return;
1555 }
1556
[email protected]afd1e522011-04-27 23:29:591557 UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"));
[email protected]91ac9202010-07-30 18:32:351558 window()->OpenTabpose();
1559#else
1560 NOTREACHED();
1561#endif
1562}
1563
[email protected]9ac7fcb2009-09-14 18:22:521564void Browser::MoveTabNext() {
[email protected]afd1e522011-04-27 23:29:591565 UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"));
[email protected]ecc523f62010-09-28 22:45:401566 tab_handler_->GetTabStripModel()->MoveTabNext();
[email protected]9ac7fcb2009-09-14 18:22:521567}
1568
1569void Browser::MoveTabPrevious() {
[email protected]afd1e522011-04-27 23:29:591570 UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"));
[email protected]ecc523f62010-09-28 22:45:401571 tab_handler_->GetTabStripModel()->MoveTabPrevious();
[email protected]9ac7fcb2009-09-14 18:22:521572}
1573
[email protected]fbd77592008-11-12 20:50:271574void Browser::SelectNumberedTab(int index) {
1575 if (index < tab_count()) {
[email protected]afd1e522011-04-27 23:29:591576 UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"));
[email protected]eaca0ad12011-04-18 15:53:411577 tab_handler_->GetTabStripModel()->ActivateTabAt(index, true);
[email protected]fbd77592008-11-12 20:50:271578 }
1579}
1580
1581void Browser::SelectLastTab() {
[email protected]afd1e522011-04-27 23:29:591582 UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"));
[email protected]ecc523f62010-09-28 22:45:401583 tab_handler_->GetTabStripModel()->SelectLastTab();
[email protected]fbd77592008-11-12 20:50:271584}
1585
1586void Browser::DuplicateTab() {
[email protected]afd1e522011-04-27 23:29:591587 UserMetrics::RecordAction(UserMetricsAction("Duplicate"));
[email protected]1ea49d52011-04-12 17:44:441588 DuplicateContentsAt(active_index());
[email protected]fbd77592008-11-12 20:50:271589}
1590
1591void Browser::RestoreTab() {
[email protected]afd1e522011-04-27 23:29:591592 UserMetrics::RecordAction(UserMetricsAction("RestoreTab"));
[email protected]92371eb2011-04-28 11:50:151593 TabRestoreService* service =
1594 TabRestoreServiceFactory::GetForProfile(profile_);
[email protected]fbd77592008-11-12 20:50:271595 if (!service)
1596 return;
1597
[email protected]fb7da4132011-03-15 15:51:001598 service->RestoreMostRecentEntry(tab_restore_service_delegate());
[email protected]fbd77592008-11-12 20:50:271599}
1600
[email protected]0c4c3882009-10-01 21:42:141601void Browser::WriteCurrentURLToClipboard() {
1602 // TODO(ericu): There isn't currently a metric for this. Should there be?
1603 // We don't appear to track the action when it comes from the
1604 // RenderContextViewMenu.
[email protected]0c4c3882009-10-01 21:42:141605
1606 TabContents* contents = GetSelectedTabContents();
1607 if (!contents->ShouldDisplayURL())
1608 return;
1609
[email protected]90f39902009-10-03 04:25:371610 chrome_browser_net::WriteURLToClipboard(
[email protected]0c4c3882009-10-01 21:42:141611 contents->GetURL(),
[email protected]9f284f132010-08-31 06:14:171612 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0c4c3882009-10-01 21:42:141613 g_browser_process->clipboard());
1614}
1615
[email protected]fbd77592008-11-12 20:50:271616void Browser::ConvertPopupToTabbedBrowser() {
[email protected]afd1e522011-04-27 23:29:591617 UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"));
[email protected]1ea49d52011-04-12 17:44:441618 int tab_strip_index = tab_handler_->GetTabStripModel()->active_index();
[email protected]3c9e1872010-11-18 16:17:491619 TabContentsWrapper* contents =
[email protected]ecc523f62010-09-28 22:45:401620 tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
[email protected]15952e462008-11-14 00:29:051621 Browser* browser = Browser::Create(profile_);
1622 browser->tabstrip_model()->AppendTabContents(contents, true);
1623 browser->window()->Show();
[email protected]fbd77592008-11-12 20:50:271624}
1625
[email protected]9282cea2009-02-18 18:49:001626void Browser::ToggleFullscreenMode() {
[email protected]34930432009-11-09 00:12:091627#if !defined(OS_MACOSX)
1628 // In kiosk mode, we always want to be fullscreen. When the browser first
1629 // starts we're not yet fullscreen, so let the initial toggle go through.
1630 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
1631 window_->IsFullscreen())
1632 return;
1633#endif
1634
[email protected]afd1e522011-04-27 23:29:591635 UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
[email protected]9282cea2009-02-18 18:49:001636 window_->SetFullscreen(!window_->IsFullscreen());
[email protected]227393e2011-06-29 21:28:391637
1638 // Once the window has become fullscreen it'll call back to
1639 // WindowFullscreenStateChanged(). We don't do this immediately as
1640 // BrowserWindow::SetFullscreen() asks for bookmark_bar_state_, so we let the
1641 // BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
1642
1643 // TODO: convert mac to invoke WindowFullscreenStateChanged once it updates
1644 // the necessary state of the frame.
1645#if defined(OS_MACOSX)
1646 WindowFullscreenStateChanged();
[email protected]ae2622c2009-07-30 23:47:581647#endif
[email protected]9282cea2009-02-18 18:49:001648}
1649
[email protected]d3766932011-08-04 22:18:231650#if defined(OS_MACOSX)
1651void Browser::TogglePresentationMode() {
1652 window_->SetPresentationMode(!window_->InPresentationMode());
1653 WindowFullscreenStateChanged();
1654}
1655#endif
1656
[email protected]da17b372010-01-22 23:37:221657#if defined(OS_CHROMEOS)
[email protected]f97d7f632010-06-01 21:08:331658void Browser::Search() {
1659 // If the NTP is showing, close it.
[email protected]692c5342011-05-25 19:16:211660 const GURL& url = GetSelectedTabContents()->GetURL();
[email protected]89f550b2011-06-08 18:34:031661 if (url.SchemeIs(chrome::kChromeUIScheme) &&
1662 url.host() == chrome::kChromeUINewTabHost) {
[email protected]f97d7f632010-06-01 21:08:331663 CloseTab();
1664 return;
1665 }
[email protected]64559862010-09-23 19:00:161666
1667 // Exit fullscreen to show omnibox.
[email protected]ebdda9092010-10-22 17:59:101668 if (window_->IsFullscreen()) {
[email protected]64559862010-09-23 19:00:161669 ToggleFullscreenMode();
[email protected]ebdda9092010-10-22 17:59:101670 // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1671 // visible at this point. Wait for next event cycle which toggles
1672 // the visibility of omnibox before creating new tab.
1673 MessageLoop::current()->PostTask(
1674 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search));
1675 return;
1676 }
[email protected]64559862010-09-23 19:00:161677
[email protected]f97d7f632010-06-01 21:08:331678 // Otherwise just open it.
1679 NewTab();
1680}
[email protected]d14af522010-12-02 03:54:501681
1682void Browser::ShowKeyboardOverlay() {
1683 window_->ShowKeyboardOverlay(window_->GetNativeHandle());
1684}
[email protected]20d17242009-10-26 20:21:051685#endif
1686
[email protected]fbd77592008-11-12 20:50:271687void Browser::Exit() {
[email protected]afd1e522011-04-27 23:29:591688 UserMetrics::RecordAction(UserMetricsAction("Exit"));
[email protected]bc63a072011-06-28 21:12:571689 BrowserList::AttemptUserExit();
[email protected]fbd77592008-11-12 20:50:271690}
1691
[email protected]36b6dcb2008-11-12 01:19:571692void Browser::BookmarkCurrentPage() {
[email protected]afd1e522011-04-27 23:29:591693 UserMetrics::RecordAction(UserMetricsAction("Star"));
[email protected]fbd77592008-11-12 20:50:271694
[email protected]76624fde2009-10-09 18:13:231695 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]36b6dcb2008-11-12 01:19:571696 if (!model || !model->IsLoaded())
1697 return; // Ignore requests until bookmarks are loaded.
1698
[email protected]76624fde2009-10-09 18:13:231699 GURL url;
[email protected]261cd762010-08-20 05:45:371700 string16 title;
[email protected]b375c5d2011-05-03 21:15:041701 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
1702 bookmark_utils::GetURLAndTitleToBookmark(tab->tab_contents(), &url, &title);
[email protected]c50d0d42009-03-03 17:37:441703 bool was_bookmarked = model->IsBookmarked(url);
[email protected]ef0d04c2010-12-15 23:34:211704 if (!was_bookmarked && profile_->IsOffTheRecord()) {
[email protected]2c910b72011-03-08 21:16:321705 // If we're incognito the favicon may not have been saved. Save it now
[email protected]ef0d04c2010-12-15 23:34:211706 // so that bookmarks have an icon for the page.
[email protected]b375c5d2011-05-03 21:15:041707 tab->favicon_tab_helper()->SaveFavicon();
[email protected]ef0d04c2010-12-15 23:34:211708 }
[email protected]261cd762010-08-20 05:45:371709 model->SetURLStarred(url, title, true);
[email protected]11dbbd22009-11-06 18:55:041710 // Make sure the model actually added a bookmark before showing the star. A
1711 // bookmark isn't created if the url is invalid.
1712 if (window_->IsActive() && model->IsBookmarked(url)) {
[email protected]5f2731c52009-02-28 00:41:271713 // Only show the bubble if the window is active, otherwise we may get into
1714 // weird situations were the bubble is deleted as soon as it is shown.
[email protected]c50d0d42009-03-03 17:37:441715 window_->ShowBookmarkBubble(url, was_bookmarked);
[email protected]5f2731c52009-02-28 00:41:271716 }
[email protected]36b6dcb2008-11-12 01:19:571717}
1718
[email protected]40bdb6d92009-02-25 00:22:271719void Browser::SavePage() {
[email protected]afd1e522011-04-27 23:29:591720 UserMetrics::RecordAction(UserMetricsAction("SavePage"));
[email protected]15d04ae2010-10-30 01:04:501721 TabContents* current_tab = GetSelectedTabContents();
1722 if (current_tab && current_tab->contents_mime_type() == "application/pdf")
[email protected]afd1e522011-04-27 23:29:591723 UserMetrics::RecordAction(UserMetricsAction("PDF.SavePage"));
[email protected]c7dd2f62011-07-18 15:57:591724 GetSelectedTabContents()->OnSavePage();
[email protected]40bdb6d92009-02-25 00:22:271725}
1726
[email protected]77d8d622010-12-15 10:30:121727void Browser::ViewSelectedSource() {
1728 ViewSource(GetSelectedTabContentsWrapper());
[email protected]36b6dcb2008-11-12 01:19:571729}
initial.commit09911bf2008-07-26 23:55:291730
[email protected]4801ecc2009-04-05 04:52:581731void Browser::ShowFindBar() {
[email protected]b77cb302009-10-29 04:09:171732 GetFindBarController()->Show();
[email protected]4801ecc2009-04-05 04:52:581733}
1734
[email protected]a3e18c42009-03-04 23:36:051735bool Browser::SupportsWindowFeature(WindowFeature feature) const {
[email protected]018cf362010-05-05 22:43:221736 return SupportsWindowFeatureImpl(feature, true);
1737}
[email protected]f5bf8ccf2010-02-05 18:19:251738
[email protected]018cf362010-05-05 22:43:221739bool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1740 return SupportsWindowFeatureImpl(feature, false);
[email protected]a3e18c42009-03-04 23:36:051741}
1742
[email protected]89d6e6e2009-12-03 23:06:511743void Browser::EmailPageLocation() {
[email protected]afd1e522011-04-27 23:29:591744 UserMetrics::RecordAction(UserMetricsAction("EmailPageLocation"));
[email protected]d221a392011-05-24 14:34:241745 TabContents* tc = GetSelectedTabContents();
1746 DCHECK(tc);
1747
1748 std::string title = EscapeQueryParamValue(UTF16ToUTF8(tc->GetTitle()), false);
1749 std::string page_url = EscapeQueryParamValue(tc->GetURL().spec(), false);
1750 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
1751 title + "&body=%0A%0A" + page_url;
1752 platform_util::OpenExternal(GURL(mailto));
[email protected]89d6e6e2009-12-03 23:06:511753}
1754
[email protected]fbd77592008-11-12 20:50:271755void Browser::Print() {
[email protected]8980e0d2011-05-27 19:16:231756 if (switches::IsPrintPreviewEnabled())
1757 GetSelectedTabContentsWrapper()->print_view_manager()->PrintPreviewNow();
1758 else
[email protected]49fe2262011-04-15 20:56:151759 GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
[email protected]fbd77592008-11-12 20:50:271760}
1761
[email protected]fbd77592008-11-12 20:50:271762void Browser::ToggleEncodingAutoDetect() {
[email protected]afd1e522011-04-27 23:29:591763 UserMetrics::RecordAction(UserMetricsAction("AutoDetectChange"));
[email protected]fbd77592008-11-12 20:50:271764 encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
[email protected]a697f4c2009-09-14 22:30:181765 // If "auto detect" is turned on, then any current override encoding
1766 // is cleared. This also implicitly performs a reload.
1767 // OTOH, if "auto detect" is turned off, we don't change the currently
1768 // active encoding.
1769 if (encoding_auto_detect_.GetValue()) {
1770 TabContents* contents = GetSelectedTabContents();
1771 if (contents)
[email protected]b2fe07d12010-02-09 14:38:081772 contents->ResetOverrideEncoding();
[email protected]a697f4c2009-09-14 22:30:181773 }
[email protected]fbd77592008-11-12 20:50:271774}
1775
1776void Browser::OverrideEncoding(int encoding_id) {
[email protected]afd1e522011-04-27 23:29:591777 UserMetrics::RecordAction(UserMetricsAction("OverrideEncoding"));
[email protected]41fc0322009-09-04 22:23:401778 const std::string selected_encoding =
[email protected]fbd77592008-11-12 20:50:271779 CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
[email protected]57c6a652009-05-04 07:58:341780 TabContents* contents = GetSelectedTabContents();
1781 if (!selected_encoding.empty() && contents)
[email protected]b2fe07d12010-02-09 14:38:081782 contents->SetOverrideEncoding(selected_encoding);
[email protected]fbd77592008-11-12 20:50:271783 // Update the list of recently selected encodings.
[email protected]41fc0322009-09-04 22:23:401784 std::string new_selected_encoding_list;
[email protected]ddd231e2010-06-29 20:35:191785 if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1786 profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
[email protected]41fc0322009-09-04 22:23:401787 encoding_id,
1788 &new_selected_encoding_list)) {
[email protected]fbd77592008-11-12 20:50:271789 profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
[email protected]ddd231e2010-06-29 20:35:191790 new_selected_encoding_list);
[email protected]fbd77592008-11-12 20:50:271791 }
[email protected]36b6dcb2008-11-12 01:19:571792}
1793
[email protected]84214982008-12-10 18:49:101794void Browser::Cut() {
[email protected]afd1e522011-04-27 23:29:591795 UserMetrics::RecordAction(UserMetricsAction("Cut"));
[email protected]20012dd42010-01-25 04:46:231796 window()->Cut();
[email protected]36b6dcb2008-11-12 01:19:571797}
1798
[email protected]84214982008-12-10 18:49:101799void Browser::Copy() {
[email protected]afd1e522011-04-27 23:29:591800 UserMetrics::RecordAction(UserMetricsAction("Copy"));
[email protected]20012dd42010-01-25 04:46:231801 window()->Copy();
[email protected]36b6dcb2008-11-12 01:19:571802}
1803
[email protected]84214982008-12-10 18:49:101804void Browser::Paste() {
[email protected]afd1e522011-04-27 23:29:591805 UserMetrics::RecordAction(UserMetricsAction("Paste"));
[email protected]20012dd42010-01-25 04:46:231806 window()->Paste();
[email protected]84214982008-12-10 18:49:101807}
1808
1809void Browser::Find() {
[email protected]afd1e522011-04-27 23:29:591810 UserMetrics::RecordAction(UserMetricsAction("Find"));
[email protected]4f3dc372009-02-24 00:10:291811 FindInPage(false, false);
[email protected]84214982008-12-10 18:49:101812}
1813
1814void Browser::FindNext() {
[email protected]afd1e522011-04-27 23:29:591815 UserMetrics::RecordAction(UserMetricsAction("FindNext"));
[email protected]4f3dc372009-02-24 00:10:291816 FindInPage(true, true);
[email protected]84214982008-12-10 18:49:101817}
1818
1819void Browser::FindPrevious() {
[email protected]afd1e522011-04-27 23:29:591820 UserMetrics::RecordAction(UserMetricsAction("FindPrevious"));
[email protected]4f3dc372009-02-24 00:10:291821 FindInPage(true, false);
[email protected]84214982008-12-10 18:49:101822}
1823
[email protected]40bd6582009-12-04 23:49:511824void Browser::Zoom(PageZoom::Function zoom_function) {
[email protected]0bffaa322011-07-18 17:37:541825 if (is_devtools())
1826 return;
1827
[email protected]896220042010-03-23 18:14:281828 static const UserMetricsAction kActions[] = {
[email protected]0bffaa322011-07-18 17:37:541829 UserMetricsAction("ZoomMinus"),
1830 UserMetricsAction("ZoomNormal"),
1831 UserMetricsAction("ZoomPlus")
1832 };
[email protected]896220042010-03-23 18:14:281833
[email protected]afd1e522011-04-27 23:29:591834 UserMetrics::RecordAction(kActions[zoom_function - PageZoom::ZOOM_OUT]);
[email protected]3c9e1872010-11-18 16:17:491835 TabContentsWrapper* tab_contents = GetSelectedTabContentsWrapper();
[email protected]216813952011-05-19 22:21:261836 RenderViewHost* host = tab_contents->render_view_host();
1837 host->Send(new ViewMsg_Zoom(host->routing_id(), zoom_function));
[email protected]84214982008-12-10 18:49:101838}
1839
1840void Browser::FocusToolbar() {
[email protected]afd1e522011-04-27 23:29:591841 UserMetrics::RecordAction(UserMetricsAction("FocusToolbar"));
[email protected]84214982008-12-10 18:49:101842 window_->FocusToolbar();
1843}
1844
[email protected]bdb7ff62010-07-20 01:56:521845void Browser::FocusAppMenu() {
[email protected]afd1e522011-04-27 23:29:591846 UserMetrics::RecordAction(UserMetricsAction("FocusAppMenu"));
[email protected]bdb7ff62010-07-20 01:56:521847 window_->FocusAppMenu();
[email protected]cc824372010-03-31 15:33:011848}
1849
[email protected]84214982008-12-10 18:49:101850void Browser::FocusLocationBar() {
[email protected]afd1e522011-04-27 23:29:591851 UserMetrics::RecordAction(UserMetricsAction("FocusLocation"));
[email protected]a26dc362010-04-23 01:48:581852 window_->SetFocusToLocationBar(true);
[email protected]84214982008-12-10 18:49:101853}
1854
[email protected]83548a42010-06-18 13:53:371855void Browser::FocusBookmarksToolbar() {
[email protected]afd1e522011-04-27 23:29:591856 UserMetrics::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
[email protected]83548a42010-06-18 13:53:371857 window_->FocusBookmarksToolbar();
1858}
1859
1860void Browser::FocusChromeOSStatus() {
[email protected]afd1e522011-04-27 23:29:591861 UserMetrics::RecordAction(UserMetricsAction("FocusChromeOSStatus"));
[email protected]83548a42010-06-18 13:53:371862 window_->FocusChromeOSStatus();
1863}
1864
1865void Browser::FocusNextPane() {
[email protected]afd1e522011-04-27 23:29:591866 UserMetrics::RecordAction(UserMetricsAction("FocusNextPane"));
[email protected]83548a42010-06-18 13:53:371867 window_->RotatePaneFocus(true);
1868}
1869
1870void Browser::FocusPreviousPane() {
[email protected]afd1e522011-04-27 23:29:591871 UserMetrics::RecordAction(UserMetricsAction("FocusPreviousPane"));
[email protected]83548a42010-06-18 13:53:371872 window_->RotatePaneFocus(false);
1873}
1874
[email protected]84214982008-12-10 18:49:101875void Browser::FocusSearch() {
1876 // TODO(beng): replace this with FocusLocationBar
[email protected]afd1e522011-04-27 23:29:591877 UserMetrics::RecordAction(UserMetricsAction("FocusSearch"));
[email protected]7745b822009-01-27 20:15:351878 window_->GetLocationBar()->FocusSearch();
[email protected]84214982008-12-10 18:49:101879}
1880
1881void Browser::OpenFile() {
[email protected]afd1e522011-04-27 23:29:591882 UserMetrics::RecordAction(UserMetricsAction("OpenFile"));
[email protected]9d1d8ad52011-03-11 22:58:171883#if defined(OS_CHROMEOS) && !defined(FILE_MANAGER_EXTENSION)
[email protected]f59f1162010-04-23 21:19:291884 FileBrowseUI::OpenPopup(profile_,
1885 "",
1886 FileBrowseUI::kPopupWidth,
1887 FileBrowseUI::kPopupHeight);
1888#else
[email protected]84214982008-12-10 18:49:101889 if (!select_file_dialog_.get())
1890 select_file_dialog_ = SelectFileDialog::Create(this);
1891
[email protected]35896a32010-06-09 08:42:511892 const FilePath directory = profile_->last_selected_directory();
1893
[email protected]84214982008-12-10 18:49:101894 // TODO(beng): figure out how to juggle this.
[email protected]d56bcd22009-03-16 19:51:561895 gfx::NativeWindow parent_window = window_->GetNativeHandle();
[email protected]84214982008-12-10 18:49:101896 select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
[email protected]35896a32010-06-09 08:42:511897 string16(), directory,
[email protected]b949f1112009-04-12 20:03:081898 NULL, 0, FILE_PATH_LITERAL(""),
[email protected]d9898912011-04-15 21:10:001899 GetSelectedTabContents(),
[email protected]d56bcd22009-03-16 19:51:561900 parent_window, NULL);
[email protected]f59f1162010-04-23 21:19:291901#endif
[email protected]84214982008-12-10 18:49:101902}
1903
1904void Browser::OpenCreateShortcutsDialog() {
[email protected]afd1e522011-04-27 23:29:591905 UserMetrics::RecordAction(UserMetricsAction("CreateShortcut"));
[email protected]7be64502011-05-03 17:51:471906#if !defined(OS_MACOSX)
[email protected]3c9e1872010-11-18 16:17:491907 TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1908 DCHECK(current_tab &&
1909 web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
1910 "Menu item should be disabled.";
[email protected]ed5431872009-11-17 08:39:511911
1912 NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
1913 if (!entry)
1914 return;
1915
[email protected]eabfdae92009-12-11 06:13:511916 // RVH's GetApplicationInfo should not be called before it returns.
1917 DCHECK(pending_web_app_action_ == NONE);
1918 pending_web_app_action_ = CREATE_SHORTCUT;
1919
[email protected]a2cf65eb2010-01-18 08:20:381920 // Start fetching web app info for CreateApplicationShortcut dialog and show
1921 // the dialog when the data is available in OnDidGetApplicationInfo.
[email protected]553602e12011-04-05 17:01:181922 current_tab->extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]98f6e022009-06-05 22:49:531923#else
1924 NOTIMPLEMENTED();
1925#endif
[email protected]36b6dcb2008-11-12 01:19:571926}
1927
[email protected]2a8a98122010-07-16 11:58:481928void Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
[email protected]e3791ce92011-08-09 01:03:321929 if (action == DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE)
1930 UserMetrics::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1931 else
1932 UserMetrics::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1933
[email protected]aebdd072011-07-07 12:36:591934 DevToolsWindow::ToggleDevToolsWindow(
[email protected]3c9e1872010-11-18 16:17:491935 GetSelectedTabContentsWrapper()->render_view_host(), action);
[email protected]fbd77592008-11-12 20:50:271936}
1937
[email protected]adb6a84d2011-02-07 16:58:401938void Browser::OpenTaskManager(bool highlight_background_resources) {
[email protected]afd1e522011-04-27 23:29:591939 UserMetrics::RecordAction(UserMetricsAction("TaskManager"));
[email protected]adb6a84d2011-02-07 16:58:401940 if (highlight_background_resources)
1941 window_->ShowBackgroundPages();
1942 else
1943 window_->ShowTaskManager();
[email protected]84214982008-12-10 18:49:101944}
1945
[email protected]84214982008-12-10 18:49:101946void Browser::OpenBugReportDialog() {
[email protected]afd1e522011-04-27 23:29:591947 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]40916632011-07-02 01:11:011948 browser::ShowHtmlBugReportView(this, std::string(), 0);
[email protected]84214982008-12-10 18:49:101949}
[email protected]44b2c8852009-03-18 00:57:491950
[email protected]84214982008-12-10 18:49:101951void Browser::ToggleBookmarkBar() {
[email protected]afd1e522011-04-27 23:29:591952 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarksBar"));
[email protected]84214982008-12-10 18:49:101953 window_->ToggleBookmarkBar();
1954}
1955
[email protected]84214982008-12-10 18:49:101956void Browser::OpenBookmarkManager() {
[email protected]afd1e522011-04-27 23:29:591957 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"));
[email protected]0af8f132011-07-16 01:37:021958 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"));
1959 ShowSingletonTabOverwritingNTP(
1960 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIBookmarksURL)));
1961}
1962
[email protected]4c9ee222011-08-17 19:51:351963void Browser::OpenBookmarkManagerWithHash(const std::string& action,
1964 int64 node_id) {
[email protected]0af8f132011-07-16 01:37:021965 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"));
1966 UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"));
[email protected]f6c13362011-08-16 12:39:521967 browser::NavigateParams params(GetSingletonTabNavigateParams(
1968 GURL(chrome::kChromeUIBookmarksURL).Resolve(
[email protected]4c9ee222011-08-17 19:51:351969 StringPrintf("/#%s%s", action.c_str(),
1970 base::Int64ToString(node_id).c_str()))));
[email protected]f6c13362011-08-16 12:39:521971 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1972 ShowSingletonTabOverwritingNTP(params);
[email protected]84214982008-12-10 18:49:101973}
[email protected]8bf80e922009-03-09 20:56:361974
[email protected]4c9ee222011-08-17 19:51:351975void Browser::OpenBookmarkManagerForNode(int64 node_id) {
1976 OpenBookmarkManagerWithHash("", node_id);
1977}
1978
1979void Browser::OpenBookmarkManagerEditNode(int64 node_id) {
1980 OpenBookmarkManagerWithHash("e=", node_id);
1981}
1982
1983void Browser::OpenBookmarkManagerAddNodeIn(int64 node_id) {
1984 OpenBookmarkManagerWithHash("a=", node_id);
1985}
1986
[email protected]fdb98512009-08-26 01:37:101987void Browser::ShowAppMenu() {
[email protected]366069f2011-01-11 09:36:121988 // We record the user metric for this event in WrenchMenu::RunMenu.
[email protected]fdb98512009-08-26 01:37:101989 window_->ShowAppMenu();
1990}
1991
[email protected]8bf80e922009-03-09 20:56:361992void Browser::ShowHistoryTab() {
[email protected]afd1e522011-04-27 23:29:591993 UserMetrics::RecordAction(UserMetricsAction("ShowHistory"));
[email protected]ddddfda2011-07-14 23:19:391994 ShowSingletonTabOverwritingNTP(
1995 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIHistoryURL)));
[email protected]8bf80e922009-03-09 20:56:361996}
[email protected]84214982008-12-10 18:49:101997
1998void Browser::ShowDownloadsTab() {
[email protected]afd1e522011-04-27 23:29:591999 UserMetrics::RecordAction(UserMetricsAction("ShowDownloads"));
[email protected]efda32f92011-07-06 22:47:042000#if !defined(OS_CHROMEOS)
2001 // ChromiumOS uses ActiveDownloadsUI instead of of DownloadShelf.
[email protected]3d037ce72011-04-04 17:43:452002 if (window()) {
2003 DownloadShelf* shelf = window()->GetDownloadShelf();
2004 if (shelf->IsShowing())
2005 shelf->Close();
2006 }
[email protected]efda32f92011-07-06 22:47:042007#endif
[email protected]ddddfda2011-07-14 23:19:392008 ShowSingletonTabOverwritingNTP(
2009 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIDownloadsURL)));
[email protected]84214982008-12-10 18:49:102010}
2011
[email protected]34085a32009-11-06 22:49:482012void Browser::ShowExtensionsTab() {
[email protected]afd1e522011-04-27 23:29:592013 UserMetrics::RecordAction(UserMetricsAction("ShowExtensions"));
[email protected]ddddfda2011-07-14 23:19:392014 ShowSingletonTabOverwritingNTP(
2015 GetSingletonTabNavigateParams(GURL(chrome::kChromeUIExtensionsURL)));
[email protected]34085a32009-11-06 22:49:482016}
2017
[email protected]c1bbaa82010-11-08 11:17:052018void Browser::ShowAboutConflictsTab() {
[email protected]afd1e522011-04-27 23:29:592019 UserMetrics::RecordAction(UserMetricsAction("AboutConflicts"));
[email protected]fee320542011-03-02 01:30:492020 ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
[email protected]c1bbaa82010-11-08 11:17:052021}
2022
[email protected]10e457c2010-04-29 03:35:232023void Browser::ShowBrokenPageTab(TabContents* contents) {
[email protected]afd1e522011-04-27 23:29:592024 UserMetrics::RecordAction(UserMetricsAction("ReportBug"));
[email protected]10e457c2010-04-29 03:35:232025 string16 page_title = contents->GetTitle();
2026 NavigationEntry* entry = contents->controller().GetActiveEntry();
2027 if (!entry)
2028 return;
2029 std::string page_url = entry->url().spec();
2030 std::vector<std::string> subst;
2031 subst.push_back(UTF16ToASCII(page_title));
2032 subst.push_back(page_url);
2033 std::string report_page_url =
2034 ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
[email protected]fee320542011-03-02 01:30:492035 ShowSingletonTab(GURL(report_page_url));
[email protected]10e457c2010-04-29 03:35:232036}
2037
[email protected]12e816bde2010-09-14 19:59:292038void Browser::ShowOptionsTab(const std::string& sub_page) {
[email protected]fcca741b2011-06-17 22:46:372039 browser::NavigateParams params(GetSingletonTabNavigateParams(
2040 GURL(chrome::kChromeUISettingsURL + sub_page)));
[email protected]fee320542011-03-02 01:30:492041 params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
[email protected]fcca741b2011-06-17 22:46:372042
[email protected]ddddfda2011-07-14 23:19:392043 ShowSingletonTabOverwritingNTP(params);
[email protected]4a42d272010-06-18 01:29:422044}
2045
[email protected]84214982008-12-10 18:49:102046void Browser::OpenClearBrowsingDataDialog() {
[email protected]afd1e522011-04-27 23:29:592047 UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"));
[email protected]445177652011-03-09 02:04:052048 ShowOptionsTab(chrome::kClearBrowserDataSubPage);
[email protected]84214982008-12-10 18:49:102049}
2050
[email protected]84214982008-12-10 18:49:102051void Browser::OpenOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592052 UserMetrics::RecordAction(UserMetricsAction("ShowOptions"));
[email protected]fcca741b2011-06-17 22:46:372053 ShowOptionsTab("");
[email protected]fbd77592008-11-12 20:50:272054}
2055
2056void Browser::OpenPasswordManager() {
[email protected]afd1e522011-04-27 23:29:592057 UserMetrics::RecordAction(UserMetricsAction("Options_ShowPasswordManager"));
[email protected]e8ce8bb2011-03-10 03:10:042058 ShowOptionsTab(chrome::kPasswordManagerSubPage);
[email protected]fbd77592008-11-12 20:50:272059}
2060
[email protected]1bdf29e2009-05-11 23:45:252061void Browser::OpenImportSettingsDialog() {
[email protected]afd1e522011-04-27 23:29:592062 UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"));
[email protected]445177652011-03-09 02:04:052063 ShowOptionsTab(chrome::kImportDataSubPage);
[email protected]1bdf29e2009-05-11 23:45:252064}
[email protected]1bdf29e2009-05-11 23:45:252065
[email protected]b99081b2011-03-10 17:43:472066void Browser::OpenInstantConfirmDialog() {
2067 ShowOptionsTab(chrome::kInstantConfirmPage);
2068}
2069
[email protected]ca38d8e2009-08-20 18:08:162070void Browser::OpenSyncMyBookmarksDialog() {
[email protected]40f047972009-11-25 03:54:402071 sync_ui_util::OpenSyncMyBookmarksDialog(
[email protected]c8de64a2011-01-25 17:10:232072 profile_, this, ProfileSyncService::START_FROM_WRENCH);
[email protected]ca38d8e2009-08-20 18:08:162073}
[email protected]ca38d8e2009-08-20 18:08:162074
[email protected]fbd77592008-11-12 20:50:272075void Browser::OpenAboutChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592076 UserMetrics::RecordAction(UserMetricsAction("AboutChrome"));
[email protected]976e69f2010-08-13 18:28:172077#if defined(OS_CHROMEOS)
[email protected]01c3857e2011-06-09 04:35:482078 std::string chrome_settings(chrome::kChromeUISettingsURL);
2079 ShowSingletonTab(GURL(chrome_settings.append(chrome::kAboutOptionsSubPage)));
[email protected]976e69f2010-08-13 18:28:172080#else
[email protected]2d46c842008-11-14 19:24:312081 window_->ShowAboutChromeDialog();
[email protected]976e69f2010-08-13 18:28:172082#endif
[email protected]fbd77592008-11-12 20:50:272083}
2084
[email protected]b1b73942010-05-26 20:11:542085void Browser::OpenUpdateChromeDialog() {
[email protected]afd1e522011-04-27 23:29:592086 UserMetrics::RecordAction(UserMetricsAction("UpdateChrome"));
[email protected]b1b73942010-05-26 20:11:542087 window_->ShowUpdateChromeDialog();
2088}
2089
[email protected]202802e42011-07-06 11:40:462090void Browser::ShowHelpTab() {
[email protected]0a4a0be2010-11-09 10:42:472091 GURL help_url(kHelpContentUrl);
[email protected]0a4a0be2010-11-09 10:42:472092 GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
[email protected]202802e42011-07-06 11:40:462093 ShowSingletonTab(localized_help_url);
[email protected]fbd77592008-11-12 20:50:272094}
2095
[email protected]31cc1c022010-10-15 20:03:472096void Browser::OpenPrivacyDashboardTabAndActivate() {
[email protected]3e0505452010-11-02 21:45:242097 OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
2098 NEW_FOREGROUND_TAB, PageTransition::LINK);
[email protected]31cc1c022010-10-15 20:03:472099 window_->Activate();
2100}
2101
[email protected]663bd9e2011-03-21 01:07:012102void Browser::OpenAutofillHelpTabAndActivate() {
[email protected]91a79232010-11-10 18:15:082103 GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
2104 AddSelectedTabWithURL(help_url, PageTransition::LINK);
[email protected]bb8fe2d2010-06-28 20:04:222105}
2106
[email protected]024617a2010-08-20 05:08:052107void Browser::OpenSearchEngineOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592108 UserMetrics::RecordAction(UserMetricsAction("EditSearchEngines"));
[email protected]445177652011-03-09 02:04:052109 ShowOptionsTab(chrome::kSearchEnginesSubPage);
[email protected]024617a2010-08-20 05:08:052110}
2111
[email protected]45c52c9d2011-07-19 12:08:142112#if defined(FILE_MANAGER_EXTENSION)
[email protected]ec2fd5a2011-04-30 06:16:052113void Browser::OpenFileManager() {
2114 UserMetrics::RecordAction(UserMetricsAction("OpenFileManager"));
[email protected]45c52c9d2011-07-19 12:08:142115 ShowSingletonTab(GURL(chrome::kChromeUIFileManagerURL));
[email protected]ec2fd5a2011-04-30 06:16:052116}
[email protected]45c52c9d2011-07-19 12:08:142117#endif
[email protected]ec2fd5a2011-04-30 06:16:052118
[email protected]45c52c9d2011-07-19 12:08:142119#if defined(OS_CHROMEOS)
[email protected]5dcbc02f2010-01-26 22:32:062120void Browser::OpenSystemOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592121 UserMetrics::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"));
[email protected]445177652011-03-09 02:04:052122 ShowOptionsTab(chrome::kSystemOptionsSubPage);
[email protected]5dcbc02f2010-01-26 22:32:062123}
2124
2125void Browser::OpenInternetOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592126 UserMetrics::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"));
[email protected]445177652011-03-09 02:04:052127 ShowOptionsTab(chrome::kInternetOptionsSubPage);
[email protected]024617a2010-08-20 05:08:052128}
2129
2130void Browser::OpenLanguageOptionsDialog() {
[email protected]afd1e522011-04-27 23:29:592131 UserMetrics::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"));
[email protected]445177652011-03-09 02:04:052132 ShowOptionsTab(chrome::kLanguageOptionsSubPage);
[email protected]be715072009-07-07 15:43:202133}
[email protected]46b92f852010-10-06 13:12:052134
2135void Browser::OpenSystemTabAndActivate() {
2136 OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
2137 NEW_FOREGROUND_TAB, PageTransition::LINK);
2138 window_->Activate();
2139}
2140
[email protected]38017612010-10-13 18:46:002141void Browser::OpenMobilePlanTabAndActivate() {
2142 OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
2143 NEW_FOREGROUND_TAB, PageTransition::LINK);
2144 window_->Activate();
2145}
[email protected]be715072009-07-07 15:43:202146#endif
2147
[email protected]a003d8e2010-10-02 21:03:352148void Browser::OpenPluginsTabAndActivate() {
[email protected]37ae3f22011-07-12 03:56:142149 OpenURL(GURL(chrome::kChromeUIPluginsURL), GURL(),
[email protected]a003d8e2010-10-02 21:03:352150 NEW_FOREGROUND_TAB, PageTransition::LINK);
2151 window_->Activate();
2152}
2153
[email protected]36b6dcb2008-11-12 01:19:572154///////////////////////////////////////////////////////////////////////////////
2155
2156// static
[email protected]79117172009-08-28 16:11:442157void Browser::SetNewHomePagePrefs(PrefService* prefs) {
[email protected]8fe6e1c2010-05-27 08:21:542158 const PrefService::Preference* home_page_pref =
2159 prefs->FindPreference(prefs::kHomePage);
2160 if (home_page_pref &&
2161 !home_page_pref->IsManaged() &&
[email protected]ddd231e2010-06-29 20:35:192162 !prefs->HasPrefPath(prefs::kHomePage)) {
[email protected]b41eb732009-09-30 16:49:332163 prefs->SetString(prefs::kHomePage,
[email protected]ddd231e2010-06-29 20:35:192164 GoogleURLTracker::kDefaultGoogleHomepage);
2165 }
[email protected]8fe6e1c2010-05-27 08:21:542166 const PrefService::Preference* home_page_is_new_tab_page_pref =
2167 prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2168 if (home_page_is_new_tab_page_pref &&
2169 !home_page_is_new_tab_page_pref->IsManaged() &&
2170 !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
[email protected]b41eb732009-09-30 16:49:332171 prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
[email protected]79117172009-08-28 16:11:442172}
2173
2174// static
[email protected]36b6dcb2008-11-12 01:19:572175void Browser::RegisterPrefs(PrefService* prefs) {
[email protected]36b6dcb2008-11-12 01:19:572176 prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
[email protected]8b8e7c92010-08-19 18:05:562177 prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
[email protected]f87919d72011-02-02 18:46:162178 prefs->RegisterIntegerPref(prefs::kMultipleProfilePrefMigration, 0);
[email protected]d9898912011-04-15 21:10:002179 prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
[email protected]09d81f82010-12-15 16:46:422180 // Educated guess: Chrome has a bundled Flash version supporting
2181 // clearing LSO data, Chromium hasn't.
2182#if defined(GOOGLE_CHROME_BUILD)
2183 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, true);
2184#else
2185 prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, false);
2186#endif
[email protected]36b6dcb2008-11-12 01:19:572187}
2188
2189// static
2190void Browser::RegisterUserPrefs(PrefService* prefs) {
[email protected]0d220832009-11-06 00:45:182191 prefs->RegisterStringPref(prefs::kHomePage,
[email protected]d36f941b2011-05-09 06:19:162192 chrome::kChromeUINewTabURL,
2193 PrefService::SYNCABLE_PREF);
2194 prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage,
2195 true,
2196 PrefService::SYNCABLE_PREF);
2197 prefs->RegisterBooleanPref(prefs::kShowHomeButton,
2198 false,
2199 PrefService::SYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092200#if defined(OS_MACOSX)
2201 // This really belongs in platform code, but there's no good place to
2202 // initialize it between the time when the AppController is created
2203 // (where there's no profile) and the time the controller gets another
2204 // crack at the start of the main event loop. By that time, BrowserInit
2205 // has already created the browser window, and it's too late: we need the
2206 // pref to be already initialized. Doing it here also saves us from having
2207 // to hard-code pref registration in the several unit tests that use
2208 // this preference.
[email protected]d36f941b2011-05-09 06:19:162209 prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled,
2210 false,
2211 PrefService::SYNCABLE_PREF);
2212 prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar,
2213 true,
2214 PrefService::UNSYNCABLE_PREF);
[email protected]93a2c7242009-07-07 18:43:092215#endif
[email protected]d36f941b2011-05-09 06:19:162216 prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory,
2217 true,
2218 PrefService::SYNCABLE_PREF);
2219 prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory,
2220 true,
2221 PrefService::SYNCABLE_PREF);
2222 prefs->RegisterBooleanPref(prefs::kDeleteCache,
2223 true,
2224 PrefService::SYNCABLE_PREF);
2225 prefs->RegisterBooleanPref(prefs::kDeleteCookies,
2226 true,
2227 PrefService::SYNCABLE_PREF);
2228 prefs->RegisterBooleanPref(prefs::kDeletePasswords,
2229 false,
2230 PrefService::SYNCABLE_PREF);
2231 prefs->RegisterBooleanPref(prefs::kDeleteFormData,
2232 false,
2233 PrefService::SYNCABLE_PREF);
2234 prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod,
2235 0,
2236 PrefService::SYNCABLE_PREF);
2237 prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser,
2238 true,
2239 PrefService::UNSYNCABLE_PREF);
2240 prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint,
2241 true,
2242 PrefService::UNSYNCABLE_PREF);
2243 prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop,
2244 true,
2245 PrefService::UNSYNCABLE_PREF);
2246 prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu,
2247 true,
2248 PrefService::UNSYNCABLE_PREF);
2249 prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar,
2250 true,
2251 PrefService::UNSYNCABLE_PREF);
2252 prefs->RegisterBooleanPref(prefs::kUseVerticalTabs,
2253 false,
2254 PrefService::UNSYNCABLE_PREF);
[email protected]ac86c982011-05-11 13:26:052255 prefs->RegisterBooleanPref(prefs::kUseCompactNavigationBar,
2256 false,
2257 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162258 prefs->RegisterBooleanPref(prefs::kEnableTranslate,
2259 true,
2260 PrefService::SYNCABLE_PREF);
2261 prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar,
2262 true,
2263 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162264 prefs->RegisterStringPref(prefs::kCloudPrintEmail,
2265 std::string(),
2266 PrefService::UNSYNCABLE_PREF);
2267 prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled,
2268 true,
2269 PrefService::UNSYNCABLE_PREF);
2270 prefs->RegisterBooleanPref(prefs::kDevToolsDisabled,
2271 false,
2272 PrefService::UNSYNCABLE_PREF);
[email protected]d36f941b2011-05-09 06:19:162273 prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation,
2274 -1,
2275 PrefService::UNSYNCABLE_PREF);
2276 prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement,
2277 PrefService::UNSYNCABLE_PREF);
[email protected]2f0a6472011-08-23 03:40:572278 // TODO(sky): remove this. It's used in tracking 91396.
2279#if defined(OS_WIN)
2280 prefs->CheckIfValueDestroyed(prefs::kBrowserWindowPlacement,
2281 base::Value::TYPE_DICTIONARY);
2282#endif
[email protected]d36f941b2011-05-09 06:19:162283 prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement,
2284 PrefService::UNSYNCABLE_PREF);
[email protected]d5e5b2a52011-08-16 11:27:122285 prefs->RegisterBooleanPref(prefs::kImportBookmarks,
2286 true,
2287 PrefService::UNSYNCABLE_PREF);
2288 prefs->RegisterBooleanPref(prefs::kImportHistory,
2289 true,
2290 PrefService::UNSYNCABLE_PREF);
2291 prefs->RegisterBooleanPref(prefs::kImportHomepage,
2292 true,
2293 PrefService::UNSYNCABLE_PREF);
2294 prefs->RegisterBooleanPref(prefs::kImportSearchEngine,
2295 true,
2296 PrefService::UNSYNCABLE_PREF);
2297 prefs->RegisterBooleanPref(prefs::kImportSavedPasswords,
2298 true,
2299 PrefService::UNSYNCABLE_PREF);
2300
[email protected]2bf2bd92011-03-31 07:12:442301 // We need to register the type of these preferences in order to query
[email protected]d36f941b2011-05-09 06:19:162302 // them even though they're only typically controlled via policy.
2303 prefs->RegisterBooleanPref(prefs::kDisable3DAPIs,
2304 false,
2305 PrefService::UNSYNCABLE_PREF);
2306 prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated,
2307 false,
2308 PrefService::UNSYNCABLE_PREF);
2309 prefs->RegisterBooleanPref(prefs::kPluginsAlwaysAuthorize,
2310 false,
2311 PrefService::UNSYNCABLE_PREF);
2312 prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing,
2313 true,
2314 PrefService::UNSYNCABLE_PREF);
2315 prefs->RegisterBooleanPref(prefs::kEnableReferrers,
2316 true,
2317 PrefService::UNSYNCABLE_PREF);
[email protected]36b6dcb2008-11-12 01:19:572318}
2319
2320// static
[email protected]ecc523f62010-09-28 22:45:402321bool Browser::RunUnloadEventsHelper(TabContents* contents) {
2322 // If the TabContents is not connected yet, then there's no unload
2323 // handler we can fire even if the TabContents has an unload listener.
2324 // One case where we hit this is in a tab that has an infinite loop
2325 // before load.
[email protected]5aab5e22010-12-08 22:13:292326 if (contents->NeedToFireBeforeUnload()) {
[email protected]ecc523f62010-09-28 22:45:402327 // If the page has unload listeners, then we tell the renderer to fire
2328 // them. Once they have fired, we'll get a message back saying whether
2329 // to proceed closing the page or not, which sends us back to this method
[email protected]5aab5e22010-12-08 22:13:292330 // with the NeedToFireBeforeUnload bit cleared.
[email protected]ecc523f62010-09-28 22:45:402331 contents->render_view_host()->FirePageBeforeUnload(false);
2332 return true;
2333 }
2334 return false;
2335}
2336
2337// static
[email protected]36b6dcb2008-11-12 01:19:572338Browser* Browser::GetBrowserForController(
2339 const NavigationController* controller, int* index_result) {
2340 BrowserList::const_iterator it;
2341 for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
[email protected]ecc523f62010-09-28 22:45:402342 int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
2343 controller);
[email protected]36b6dcb2008-11-12 01:19:572344 if (index != TabStripModel::kNoTab) {
2345 if (index_result)
2346 *index_result = index;
2347 return *it;
2348 }
2349 }
2350
2351 return NULL;
2352}
2353
[email protected]3a29a6e2011-08-24 18:26:212354// static
2355void Browser::RunFileChooserHelper(
2356 TabContents* tab, const ViewHostMsg_RunFileChooser_Params& params) {
2357 Profile* profile =
2358 Profile::FromBrowserContext(tab->browser_context());
2359
2360 // This object is destroyed when the file selection is performed or
2361 // cancelled.
2362 FileSelectHelper* file_select_helper = new FileSelectHelper(profile);
2363
2364 file_select_helper->RunFileChooser(tab->render_view_host(), tab, params);
2365}
2366
2367// static
2368void Browser::EnumerateDirectoryHelper(TabContents* tab, int request_id,
2369 const FilePath& path) {
2370 ChildProcessSecurityPolicy* policy =
2371 ChildProcessSecurityPolicy::GetInstance();
2372 if (!policy->CanReadDirectory(tab->render_view_host()->process()->id(),
2373 path)) {
2374 return;
2375 }
2376
2377 Profile* profile =
2378 Profile::FromBrowserContext(tab->browser_context());
2379
2380 // This object is destroyed when the enumeration is performed or
2381 // cancelled.
2382 FileSelectHelper* file_select_helper = new FileSelectHelper(profile);
2383
2384 file_select_helper->EnumerateDirectory(request_id,
2385 tab->render_view_host(),
2386 path);
2387}
2388
[email protected]485fba42009-03-24 23:27:292389void Browser::ExecuteCommandWithDisposition(
2390 int id, WindowOpenDisposition disposition) {
[email protected]1fc025202009-01-20 23:03:142391 // No commands are enabled if there is not yet any selected tab.
2392 // TODO(pkasting): It seems like we should not need this, because either
2393 // most/all commands should not have been enabled yet anyway or the ones that
2394 // are enabled should be global, or safe themselves against having no selected
2395 // tab. However, Ben says he tried removing this before and got lots of
2396 // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2397 // window construction. This probably could use closer examination someday.
[email protected]3c9e1872010-11-18 16:17:492398 if (!GetSelectedTabContentsWrapper())
[email protected]1fc025202009-01-20 23:03:142399 return;
2400
[email protected]59c9f002010-11-19 00:38:052401 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2402 << id;
[email protected]36b6dcb2008-11-12 01:19:572403
[email protected]867125a02009-12-10 06:01:482404 // If command execution is blocked then just record the command and return.
2405 if (block_command_execution_) {
2406 // We actually only allow no more than one blocked command, otherwise some
2407 // commands maybe lost.
[email protected]5dcbc02f2010-01-26 22:32:062408 DCHECK_EQ(last_blocked_command_id_, -1);
[email protected]867125a02009-12-10 06:01:482409 last_blocked_command_id_ = id;
2410 last_blocked_command_disposition_ = disposition;
2411 return;
2412 }
2413
[email protected]fbd77592008-11-12 20:50:272414 // The order of commands in this switch statement must match the function
2415 // declaration order in browser.h!
[email protected]36b6dcb2008-11-12 01:19:572416 switch (id) {
[email protected]84214982008-12-10 18:49:102417 // Navigation commands
[email protected]cb84d642010-06-10 00:56:282418 case IDC_BACK: GoBack(disposition); break;
2419 case IDC_FORWARD: GoForward(disposition); break;
2420 case IDC_RELOAD: Reload(disposition); break;
2421 case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2422 case IDC_HOME: Home(disposition); break;
2423 case IDC_OPEN_CURRENT_URL: OpenCurrentURL(); break;
[email protected]cb84d642010-06-10 00:56:282424 case IDC_STOP: Stop(); break;
[email protected]36b6dcb2008-11-12 01:19:572425
[email protected]84214982008-12-10 18:49:102426 // Window management commands
[email protected]cb84d642010-06-10 00:56:282427 case IDC_NEW_WINDOW: NewWindow(); break;
2428 case IDC_NEW_INCOGNITO_WINDOW: NewIncognitoWindow(); break;
[email protected]cb84d642010-06-10 00:56:282429 case IDC_CLOSE_WINDOW: CloseWindow(); break;
2430 case IDC_NEW_TAB: NewTab(); break;
2431 case IDC_CLOSE_TAB: CloseTab(); break;
2432 case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
2433 case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
[email protected]91ac9202010-07-30 18:32:352434 case IDC_TABPOSE: OpenTabpose(); break;
[email protected]cb84d642010-06-10 00:56:282435 case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
2436 case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
[email protected]36b6dcb2008-11-12 01:19:572437 case IDC_SELECT_TAB_0:
2438 case IDC_SELECT_TAB_1:
2439 case IDC_SELECT_TAB_2:
2440 case IDC_SELECT_TAB_3:
2441 case IDC_SELECT_TAB_4:
2442 case IDC_SELECT_TAB_5:
2443 case IDC_SELECT_TAB_6:
[email protected]cb525c82008-12-08 23:04:542444 case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
[email protected]cb84d642010-06-10 00:56:282445 break;
2446 case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
2447 case IDC_DUPLICATE_TAB: DuplicateTab(); break;
2448 case IDC_RESTORE_TAB: RestoreTab(); break;
2449 case IDC_COPY_URL: WriteCurrentURLToClipboard(); break;
2450 case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
2451 case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
[email protected]d3766932011-08-04 22:18:232452#if defined(OS_MACOSX)
2453 case IDC_PRESENTATION_MODE: TogglePresentationMode(); break;
2454#endif
[email protected]cb84d642010-06-10 00:56:282455 case IDC_EXIT: Exit(); break;
2456 case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break;
[email protected]ac86c982011-05-11 13:26:052457 case IDC_COMPACT_NAVBAR: ToggleUseCompactNavigationBar(); break;
[email protected]da17b372010-01-22 23:37:222458#if defined(OS_CHROMEOS)
[email protected]cb84d642010-06-10 00:56:282459 case IDC_SEARCH: Search(); break;
[email protected]d14af522010-12-02 03:54:502460 case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
[email protected]20d17242009-10-26 20:21:052461#endif
[email protected]36b6dcb2008-11-12 01:19:572462
[email protected]84214982008-12-10 18:49:102463 // Page-related commands
[email protected]cb84d642010-06-10 00:56:282464 case IDC_SAVE_PAGE: SavePage(); break;
2465 case IDC_BOOKMARK_PAGE: BookmarkCurrentPage(); break;
2466 case IDC_BOOKMARK_ALL_TABS: BookmarkAllTabs(); break;
[email protected]77d8d622010-12-15 10:30:122467 case IDC_VIEW_SOURCE: ViewSelectedSource(); break;
[email protected]cb84d642010-06-10 00:56:282468 case IDC_EMAIL_PAGE_LOCATION: EmailPageLocation(); break;
2469 case IDC_PRINT: Print(); break;
2470 case IDC_ENCODING_AUTO_DETECT: ToggleEncodingAutoDetect(); break;
[email protected]36b6dcb2008-11-12 01:19:572471 case IDC_ENCODING_UTF8:
2472 case IDC_ENCODING_UTF16LE:
2473 case IDC_ENCODING_ISO88591:
2474 case IDC_ENCODING_WINDOWS1252:
[email protected]1c5bf632008-12-11 20:30:492475 case IDC_ENCODING_GBK:
[email protected]36b6dcb2008-11-12 01:19:572476 case IDC_ENCODING_GB18030:
2477 case IDC_ENCODING_BIG5HKSCS:
2478 case IDC_ENCODING_BIG5:
2479 case IDC_ENCODING_KOREAN:
2480 case IDC_ENCODING_SHIFTJIS:
2481 case IDC_ENCODING_ISO2022JP:
2482 case IDC_ENCODING_EUCJP:
2483 case IDC_ENCODING_THAI:
2484 case IDC_ENCODING_ISO885915:
2485 case IDC_ENCODING_MACINTOSH:
2486 case IDC_ENCODING_ISO88592:
2487 case IDC_ENCODING_WINDOWS1250:
2488 case IDC_ENCODING_ISO88595:
2489 case IDC_ENCODING_WINDOWS1251:
2490 case IDC_ENCODING_KOI8R:
2491 case IDC_ENCODING_KOI8U:
2492 case IDC_ENCODING_ISO88597:
2493 case IDC_ENCODING_WINDOWS1253:
2494 case IDC_ENCODING_ISO88594:
2495 case IDC_ENCODING_ISO885913:
2496 case IDC_ENCODING_WINDOWS1257:
2497 case IDC_ENCODING_ISO88593:
2498 case IDC_ENCODING_ISO885910:
2499 case IDC_ENCODING_ISO885914:
2500 case IDC_ENCODING_ISO885916:
[email protected]36b6dcb2008-11-12 01:19:572501 case IDC_ENCODING_WINDOWS1254:
2502 case IDC_ENCODING_ISO88596:
2503 case IDC_ENCODING_WINDOWS1256:
2504 case IDC_ENCODING_ISO88598:
[email protected]e13271f2009-03-07 00:26:002505 case IDC_ENCODING_ISO88598I:
[email protected]36b6dcb2008-11-12 01:19:572506 case IDC_ENCODING_WINDOWS1255:
[email protected]cb84d642010-06-10 00:56:282507 case IDC_ENCODING_WINDOWS1258: OverrideEncoding(id); break;
[email protected]36b6dcb2008-11-12 01:19:572508
[email protected]84214982008-12-10 18:49:102509 // Clipboard commands
[email protected]cb84d642010-06-10 00:56:282510 case IDC_CUT: Cut(); break;
2511 case IDC_COPY: Copy(); break;
2512 case IDC_PASTE: Paste(); break;
[email protected]84214982008-12-10 18:49:102513
2514 // Find-in-page
[email protected]cb84d642010-06-10 00:56:282515 case IDC_FIND: Find(); break;
2516 case IDC_FIND_NEXT: FindNext(); break;
2517 case IDC_FIND_PREVIOUS: FindPrevious(); break;
[email protected]84214982008-12-10 18:49:102518
2519 // Zoom
[email protected]cb84d642010-06-10 00:56:282520 case IDC_ZOOM_PLUS: Zoom(PageZoom::ZOOM_IN); break;
2521 case IDC_ZOOM_NORMAL: Zoom(PageZoom::RESET); break;
2522 case IDC_ZOOM_MINUS: Zoom(PageZoom::ZOOM_OUT); break;
[email protected]84214982008-12-10 18:49:102523
2524 // Focus various bits of UI
[email protected]cb84d642010-06-10 00:56:282525 case IDC_FOCUS_TOOLBAR: FocusToolbar(); break;
2526 case IDC_FOCUS_LOCATION: FocusLocationBar(); break;
2527 case IDC_FOCUS_SEARCH: FocusSearch(); break;
[email protected]bdb7ff62010-07-20 01:56:522528 case IDC_FOCUS_MENU_BAR: FocusAppMenu(); break;
[email protected]83548a42010-06-18 13:53:372529 case IDC_FOCUS_BOOKMARKS: FocusBookmarksToolbar(); break;
2530 case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus(); break;
2531 case IDC_FOCUS_NEXT_PANE: FocusNextPane(); break;
2532 case IDC_FOCUS_PREVIOUS_PANE: FocusPreviousPane(); break;
[email protected]84214982008-12-10 18:49:102533
2534 // Show various bits of UI
[email protected]cb84d642010-06-10 00:56:282535 case IDC_OPEN_FILE: OpenFile(); break;
2536 case IDC_CREATE_SHORTCUTS: OpenCreateShortcutsDialog(); break;
[email protected]2a8a98122010-07-16 11:58:482537 case IDC_DEV_TOOLS: ToggleDevToolsWindow(
2538 DEVTOOLS_TOGGLE_ACTION_NONE);
2539 break;
2540 case IDC_DEV_TOOLS_CONSOLE: ToggleDevToolsWindow(
2541 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2542 break;
2543 case IDC_DEV_TOOLS_INSPECT: ToggleDevToolsWindow(
2544 DEVTOOLS_TOGGLE_ACTION_INSPECT);
2545 break;
[email protected]adb6a84d2011-02-07 16:58:402546 case IDC_TASK_MANAGER: OpenTaskManager(false); break;
2547 case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true); break;
[email protected]1c41a932010-11-22 23:41:232548 case IDC_FEEDBACK: OpenBugReportDialog(); break;
[email protected]44b2c8852009-03-18 00:57:492549
[email protected]cb84d642010-06-10 00:56:282550 case IDC_SHOW_BOOKMARK_BAR: ToggleBookmarkBar(); break;
[email protected]7664ab32011-02-01 23:35:252551 case IDC_PROFILING_ENABLED: Profiling::Toggle(); break;
[email protected]44b2c8852009-03-18 00:57:492552
[email protected]cb84d642010-06-10 00:56:282553 case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager(); break;
2554 case IDC_SHOW_APP_MENU: ShowAppMenu(); break;
[email protected]cb84d642010-06-10 00:56:282555 case IDC_SHOW_HISTORY: ShowHistoryTab(); break;
2556 case IDC_SHOW_DOWNLOADS: ShowDownloadsTab(); break;
2557 case IDC_MANAGE_EXTENSIONS: ShowExtensionsTab(); break;
2558 case IDC_SYNC_BOOKMARKS: OpenSyncMyBookmarksDialog(); break;
2559 case IDC_OPTIONS: OpenOptionsDialog(); break;
[email protected]445177652011-03-09 02:04:052560 case IDC_EDIT_SEARCH_ENGINES: OpenSearchEngineOptionsDialog(); break;
[email protected]cb84d642010-06-10 00:56:282561 case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break;
2562 case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break;
2563 case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break;
[email protected]b21d6912010-08-31 19:22:412564 case IDC_ABOUT: OpenAboutChromeDialog(); break;
2565 case IDC_UPGRADE_DIALOG: OpenUpdateChromeDialog(); break;
[email protected]c1bbaa82010-11-08 11:17:052566 case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab(); break;
[email protected]202802e42011-07-06 11:40:462567 case IDC_HELP_PAGE: ShowHelpTab(); break;
[email protected]16779842009-07-08 23:45:292568#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:052569 case IDC_FILE_MANAGER: OpenFileManager(); break;
[email protected]cb84d642010-06-10 00:56:282570 case IDC_SYSTEM_OPTIONS: OpenSystemOptionsDialog(); break;
2571 case IDC_INTERNET_OPTIONS: OpenInternetOptionsDialog(); break;
[email protected]024617a2010-08-20 05:08:052572 case IDC_LANGUAGE_OPTIONS: OpenLanguageOptionsDialog(); break;
[email protected]be715072009-07-07 15:43:202573#endif
[email protected]2e2cacc2011-07-12 21:54:262574 case IDC_SHOW_SYNC_SETUP: ShowSyncSetup(); break;
[email protected]d938aed92009-01-22 19:49:332575
[email protected]36b6dcb2008-11-12 01:19:572576 default:
[email protected]84214982008-12-10 18:49:102577 LOG(WARNING) << "Received Unimplemented Command: " << id;
[email protected]fbd77592008-11-12 20:50:272578 break;
[email protected]36b6dcb2008-11-12 01:19:572579 }
2580}
2581
[email protected]3ab6796d32010-12-21 23:56:072582bool Browser::ExecuteCommandIfEnabled(int id) {
2583 if (command_updater_.SupportsCommand(id) &&
2584 command_updater_.IsCommandEnabled(id)) {
2585 ExecuteCommand(id);
2586 return true;
2587 }
2588 return false;
2589}
2590
[email protected]06181422011-02-09 17:44:212591bool Browser::IsReservedCommandOrKey(int command_id,
2592 const NativeWebKeyboardEvent& event) {
[email protected]06181422011-02-09 17:44:212593#if defined(OS_CHROMEOS)
2594 // Chrome OS's top row of keys produces F1-10. Make sure that web pages
2595 // aren't able to block Chrome from performing the standard actions for F1-F4
2596 // (F5-7 are grabbed by other X clients and hence don't need this protection,
2597 // and F8-10 are handled separately in Chrome via a GDK event filter, but
2598 // let's future-proof this).
2599 ui::KeyboardCode key_code =
[email protected]6a1ae6cd2011-02-11 20:06:092600 static_cast<ui::KeyboardCode>(event.windowsKeyCode);
[email protected]06181422011-02-09 17:44:212601 if (key_code == ui::VKEY_F1 ||
2602 key_code == ui::VKEY_F2 ||
2603 key_code == ui::VKEY_F3 ||
2604 key_code == ui::VKEY_F4 ||
2605 key_code == ui::VKEY_F5 ||
2606 key_code == ui::VKEY_F6 ||
2607 key_code == ui::VKEY_F7 ||
2608 key_code == ui::VKEY_F8 ||
2609 key_code == ui::VKEY_F9 ||
2610 key_code == ui::VKEY_F10) {
[email protected]6a1ae6cd2011-02-11 20:06:092611 return true;
[email protected]06181422011-02-09 17:44:212612 }
2613#endif
2614
[email protected]6a1ae6cd2011-02-11 20:06:092615 return command_id == IDC_CLOSE_TAB ||
[email protected]867125a02009-12-10 06:01:482616 command_id == IDC_CLOSE_WINDOW ||
2617 command_id == IDC_NEW_INCOGNITO_WINDOW ||
2618 command_id == IDC_NEW_TAB ||
2619 command_id == IDC_NEW_WINDOW ||
2620 command_id == IDC_RESTORE_TAB ||
2621 command_id == IDC_SELECT_NEXT_TAB ||
2622 command_id == IDC_SELECT_PREVIOUS_TAB ||
[email protected]c1d0d812010-07-27 20:21:552623 command_id == IDC_TABPOSE ||
[email protected]f97d7f632010-06-01 21:08:332624 command_id == IDC_EXIT ||
2625 command_id == IDC_SEARCH;
[email protected]867125a02009-12-10 06:01:482626}
2627
2628void Browser::SetBlockCommandExecution(bool block) {
2629 block_command_execution_ = block;
2630 if (block) {
2631 last_blocked_command_id_ = -1;
2632 last_blocked_command_disposition_ = CURRENT_TAB;
2633 }
2634}
2635
2636int Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2637 if (disposition)
2638 *disposition = last_blocked_command_disposition_;
2639 return last_blocked_command_id_;
2640}
2641
[email protected]3c9e1872010-11-18 16:17:492642void Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
[email protected]19d9f3a2010-10-14 21:49:362643 PageTransition::Type transition,
2644 bool user_initiated) {
2645 tabstrip_model()->TabNavigating(contents, transition);
2646
[email protected]3c9e1872010-11-18 16:17:492647 bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
[email protected]19d9f3a2010-10-14 21:49:362648 if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2649 // Forcibly reset the location bar if the url is going to change in the
2650 // current tab, since otherwise it won't discard any ongoing user edits,
2651 // since it doesn't realize this is a user-initiated action.
2652 window()->GetLocationBar()->Revert();
2653 }
2654
2655 if (GetStatusBubble())
2656 GetStatusBubble()->Hide();
2657
2658 // Update the location bar. This is synchronous. We specifically don't
2659 // update the load state since the load hasn't started yet and updating it
2660 // will put it out of sync with the actual state like whether we're
2661 // displaying a favicon, which controls the throbber. If we updated it here,
2662 // the throbber will show the default favicon for a split second when
2663 // navigating away from the new tab page.
[email protected]3c9e1872010-11-18 16:17:492664 ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
[email protected]19d9f3a2010-10-14 21:49:362665
2666 if (contents_is_selected)
[email protected]3c9e1872010-11-18 16:17:492667 contents->tab_contents()->Focus();
[email protected]19d9f3a2010-10-14 21:49:362668}
2669
2670GURL Browser::GetHomePage() const {
2671 // --homepage overrides any preferences.
2672 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2673 if (command_line.HasSwitch(switches::kHomePage)) {
[email protected]a8e4b5a82010-10-27 00:05:472674 // TODO(evanm): clean up usage of DIR_CURRENT.
2675 // http://code.google.com/p/chromium/issues/detail?id=60630
2676 // For now, allow this code to call getcwd().
2677 base::ThreadRestrictions::ScopedAllowIO allow_io;
2678
[email protected]19d9f3a2010-10-14 21:49:362679 FilePath browser_directory;
2680 PathService::Get(base::DIR_CURRENT, &browser_directory);
2681 GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory,
2682 command_line.GetSwitchValuePath(switches::kHomePage)));
2683 if (home_page.is_valid())
2684 return home_page;
2685 }
2686
2687 if (profile_->GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
2688 return GURL(chrome::kChromeUINewTabURL);
2689 GURL home_page(URLFixerUpper::FixupURL(
2690 profile_->GetPrefs()->GetString(prefs::kHomePage),
2691 std::string()));
2692 if (!home_page.is_valid())
2693 return GURL(chrome::kChromeUINewTabURL);
2694 return home_page;
2695}
2696
[email protected]36b6dcb2008-11-12 01:19:572697///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402698// Browser, PageNavigator implementation:
[email protected]19d9f3a2010-10-14 21:49:362699
[email protected]00c37fc2011-08-02 00:22:502700// TODO(adriansc): Remove this method once refactoring changed all call sites.
[email protected]992e4542011-07-20 23:09:252701TabContents* Browser::OpenURL(const GURL& url,
2702 const GURL& referrer,
2703 WindowOpenDisposition disposition,
2704 PageTransition::Type transition) {
[email protected]00c37fc2011-08-02 00:22:502705 return OpenURLFromTab(NULL,
2706 OpenURLParams(url, referrer, disposition, transition));
2707}
2708
2709TabContents* Browser::OpenURL(const OpenURLParams& params) {
2710 return OpenURLFromTab(NULL, params);
[email protected]ecc523f62010-09-28 22:45:402711}
2712
2713///////////////////////////////////////////////////////////////////////////////
[email protected]485fba42009-03-24 23:27:292714// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2715
2716void Browser::ExecuteCommand(int id) {
2717 ExecuteCommandWithDisposition(id, CURRENT_TAB);
2718}
2719
2720///////////////////////////////////////////////////////////////////////////////
[email protected]ecc523f62010-09-28 22:45:402721// Browser, TabHandlerDelegate implementation:
2722
2723Profile* Browser::GetProfile() const {
2724 return profile();
2725}
2726
2727Browser* Browser::AsBrowser() {
2728 return this;
2729}
2730
2731///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572732// Browser, TabStripModelDelegate implementation:
2733
[email protected]3c9e1872010-11-18 16:17:492734TabContentsWrapper* Browser::AddBlankTab(bool foreground) {
[email protected]22735af62009-04-07 21:09:582735 return AddBlankTabAt(-1, foreground);
2736}
2737
[email protected]3c9e1872010-11-18 16:17:492738TabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
[email protected]3f8eb7f2009-10-02 23:58:052739 // Time new tab page creation time. We keep track of the timing data in
2740 // TabContents, but we want to include the time it takes to create the
2741 // TabContents object too.
2742 base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
[email protected]616381f02010-11-02 15:15:332743 browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
2744 PageTransition::TYPED);
[email protected]616381f02010-11-02 15:15:332745 params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2746 params.tabstrip_index = index;
2747 browser::Navigate(&params);
[email protected]3c9e1872010-11-18 16:17:492748 params.target_contents->tab_contents()->set_new_tab_start_time(
2749 new_tab_start_time);
[email protected]616381f02010-11-02 15:15:332750 return params.target_contents;
[email protected]15952e462008-11-14 00:29:052751}
2752
[email protected]3c9e1872010-11-18 16:17:492753Browser* Browser::CreateNewStripWithContents(
2754 TabContentsWrapper* detached_contents,
2755 const gfx::Rect& window_bounds,
2756 const DockInfo& dock_info,
2757 bool maximize) {
[email protected]018cf362010-05-05 22:43:222758 DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
[email protected]adf650f2008-12-09 16:10:062759
[email protected]5e495462008-11-20 23:07:412760 gfx::Rect new_window_bounds = window_bounds;
[email protected]5e495462008-11-20 23:07:412761 if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2762 dock_info.AdjustOtherWindowBounds();
2763
[email protected]36b6dcb2008-11-12 01:19:572764 // Create an empty new browser window the same size as the old one.
[email protected]b35b26b32011-05-05 20:35:142765 Browser* browser = new Browser(TYPE_TABBED, profile_);
[email protected]5e495462008-11-20 23:07:412766 browser->set_override_bounds(new_window_bounds);
[email protected]400eaf82011-08-22 15:47:392767 browser->set_show_state(
2768 maximize ? ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL);
[email protected]9800de5e2011-03-11 18:19:492769 browser->InitBrowserWindow();
[email protected]15952e462008-11-14 00:29:052770 browser->tabstrip_model()->AppendTabContents(detached_contents, true);
[email protected]159f7762008-12-19 14:58:272771 // Make sure the loading state is updated correctly, otherwise the throbber
2772 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492773 browser->LoadingStateChanged(detached_contents->tab_contents());
[email protected]3d1104f2009-03-26 15:30:282774 return browser;
[email protected]36b6dcb2008-11-12 01:19:572775}
2776
2777int Browser::GetDragActions() const {
[email protected]ecc523f62010-09-28 22:45:402778 return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
2779 TabStripModelDelegate::TAB_MOVE_ACTION : 0);
[email protected]36b6dcb2008-11-12 01:19:572780}
2781
[email protected]3c9e1872010-11-18 16:17:492782TabContentsWrapper* Browser::CreateTabContentsForURL(
[email protected]36b6dcb2008-11-12 01:19:572783 const GURL& url, const GURL& referrer, Profile* profile,
2784 PageTransition::Type transition, bool defer_load,
2785 SiteInstance* instance) const {
[email protected]3c9e1872010-11-18 16:17:492786 TabContentsWrapper* contents = TabContentsFactory(profile, instance,
[email protected]ecc523f62010-09-28 22:45:402787 MSG_ROUTING_NONE,
[email protected]3c9e1872010-11-18 16:17:492788 GetSelectedTabContents(), NULL);
[email protected]36b6dcb2008-11-12 01:19:572789 if (!defer_load) {
2790 // Load the initial URL before adding the new tab contents to the tab strip
2791 // so that the tab contents has navigation state.
[email protected]ce3fa3c2009-04-20 19:55:572792 contents->controller().LoadURL(url, referrer, transition);
[email protected]36b6dcb2008-11-12 01:19:572793 }
2794
2795 return contents;
2796}
2797
2798bool Browser::CanDuplicateContentsAt(int index) {
[email protected]ce3fa3c2009-04-20 19:55:572799 NavigationController& nc = GetTabContentsAt(index)->controller();
2800 return nc.tab_contents() && nc.GetLastCommittedEntry();
[email protected]36b6dcb2008-11-12 01:19:572801}
2802
2803void Browser::DuplicateContentsAt(int index) {
[email protected]3c9e1872010-11-18 16:17:492804 TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
[email protected]94ce7252010-12-20 21:46:332805 CHECK(contents);
[email protected]77d8d622010-12-15 10:30:122806 TabContentsWrapper* contents_dupe = contents->Clone();
[email protected]47b309f2010-12-28 17:35:562807
2808 bool pinned = false;
2809 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2810 // If this is a tabbed browser, just create a duplicate tab inside the same
2811 // window next to the tab being duplicated.
2812 int index = tab_handler_->GetTabStripModel()->
2813 GetIndexOfTabContents(contents);
2814 pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
[email protected]eaca0ad12011-04-18 15:53:412815 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:562816 TabStripModel::ADD_INHERIT_GROUP |
2817 (pinned ? TabStripModel::ADD_PINNED : 0);
2818 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
2819 contents_dupe,
2820 add_types);
2821 } else {
2822 Browser* browser = NULL;
[email protected]b35b26b32011-05-05 20:35:142823 if (is_app()) {
2824 CHECK(!is_type_popup());
2825 CHECK(!is_type_panel());
[email protected]5c209242011-06-06 20:36:172826 browser = Browser::CreateForApp(TYPE_POPUP, app_name_, gfx::Rect(),
[email protected]b35b26b32011-05-05 20:35:142827 profile_);
2828 } else if (is_type_popup()) {
[email protected]47b309f2010-12-28 17:35:562829 browser = Browser::CreateForType(TYPE_POPUP, profile_);
2830 }
2831
2832 // Preserve the size of the original window. The new window has already
2833 // been given an offset by the OS, so we shouldn't copy the old bounds.
2834 BrowserWindow* new_window = browser->window();
2835 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
2836 window()->GetRestoredBounds().size()));
2837
[email protected]4e595682011-02-09 17:07:022838 // We need to show the browser now. Otherwise ContainerWin assumes the
[email protected]47b309f2010-12-28 17:35:562839 // TabContents is invisible and won't size it.
2840 browser->window()->Show();
2841
2842 // The page transition below is only for the purpose of inserting the tab.
2843 browser->AddTab(contents_dupe, PageTransition::LINK);
2844 }
2845
[email protected]92371eb2011-04-28 11:50:152846 SessionService* session_service =
2847 SessionServiceFactory::GetForProfileIfExisting(profile_);
2848 if (session_service)
[email protected]81898992011-06-14 22:15:002849 session_service->TabRestored(contents_dupe, pinned);
[email protected]36b6dcb2008-11-12 01:19:572850}
2851
[email protected]36b6dcb2008-11-12 01:19:572852void Browser::CloseFrameAfterDragSession() {
[email protected]7be64502011-05-03 17:51:472853#if !defined(OS_MACOSX)
[email protected]36b6dcb2008-11-12 01:19:572854 // This is scheduled to run after we return to the message loop because
2855 // otherwise the frame will think the drag session is still active and ignore
2856 // the request.
[email protected]d6a3c772009-01-27 19:41:202857 // TODO(port): figure out what is required here in a cross-platform world
[email protected]0586b0e2010-02-12 21:38:372858 MessageLoop::current()->PostTask(
2859 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]d6a3c772009-01-27 19:41:202860#endif
initial.commit09911bf2008-07-26 23:55:292861}
2862
[email protected]3c9e1872010-11-18 16:17:492863void Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
[email protected]505323e22009-01-24 02:47:582864 // We don't create historical tabs for incognito windows or windows without
2865 // profiles.
[email protected]92371eb2011-04-28 11:50:152866 if (!profile() || profile()->IsOffTheRecord())
[email protected]505323e22009-01-24 02:47:582867 return;
[email protected]92371eb2011-04-28 11:50:152868
[email protected]0d4ef7f2011-05-12 22:38:572869 // We don't create historical tabs for print preview tabs.
2870 if (contents->tab_contents()->GetURL() == GURL(chrome::kChromeUIPrintURL))
2871 return;
2872
[email protected]92371eb2011-04-28 11:50:152873 TabRestoreService* service =
2874 TabRestoreServiceFactory::GetForProfile(profile());
[email protected]505323e22009-01-24 02:47:582875
[email protected]fb5ff422010-05-03 20:46:102876 // We only create historical tab entries for tabbed browser windows.
[email protected]92371eb2011-04-28 11:50:152877 if (service && CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2878 service->CreateHistoricalTab(&contents->controller(),
[email protected]fb7da4132011-03-15 15:51:002879 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
[email protected]505323e22009-01-24 02:47:582880 }
2881}
2882
[email protected]3c9e1872010-11-18 16:17:492883bool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
2884 return Browser::RunUnloadEventsHelper(contents->tab_contents());
[email protected]505323e22009-01-24 02:47:582885}
2886
[email protected]8e48e982009-12-25 11:22:462887bool Browser::CanReloadContents(TabContents* source) const {
[email protected]b35b26b32011-05-05 20:35:142888 return !is_devtools();
[email protected]8e48e982009-12-25 11:22:462889}
2890
[email protected]2db5a2042011-04-26 17:13:472891bool Browser::CanCloseContents(std::vector<int>* indices) {
2892 DCHECK(!indices->empty());
2893 TabCloseableStateWatcher* watcher =
2894 g_browser_process->tab_closeable_state_watcher();
2895 bool can_close_all = !watcher || watcher->CanCloseTabs(this, indices);
2896 if (indices->empty()) // Cannot close any tab.
[email protected]0b4d3382010-07-14 16:13:042897 return false;
[email protected]2db5a2042011-04-26 17:13:472898 // Now, handle cases where at least one tab can be closed.
2899 // If we are closing all the tabs for this browser, make sure to check for
[email protected]940ccb22009-04-30 17:11:102900 // in-progress downloads.
2901 // Note that the next call when it returns false will ask the user for
2902 // confirmation before closing the browser if the user decides so.
[email protected]2db5a2042011-04-26 17:13:472903 if (tab_handler_->GetTabStripModel()->count() ==
2904 static_cast<int>(indices->size()) &&
2905 !CanCloseWithInProgressDownloads()) {
2906 indices->clear();
2907 can_close_all = false;
2908 }
2909 return can_close_all;
[email protected]940ccb22009-04-30 17:11:102910}
[email protected]d6a3c772009-01-27 19:41:202911
[email protected]a206b442009-10-08 23:20:202912bool Browser::CanBookmarkAllTabs() const {
2913 BookmarkModel* model = profile()->GetBookmarkModel();
[email protected]a13f47d12011-04-14 11:41:582914 return (model && model->IsLoaded()) &&
2915 tab_count() > 1 &&
[email protected]97b46382011-05-02 13:23:042916 profile()->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
[email protected]a206b442009-10-08 23:20:202917}
2918
[email protected]b3ac5c82009-10-08 20:56:542919void Browser::BookmarkAllTabs() {
[email protected]ec12ffe2009-10-16 22:28:442920 BookmarkModel* model = profile()->GetBookmarkModel();
2921 DCHECK(model && model->IsLoaded());
2922
2923 BookmarkEditor::EditDetails details;
2924 details.type = BookmarkEditor::EditDetails::NEW_FOLDER;
2925 bookmark_utils::GetURLsForOpenTabs(this, &(details.urls));
2926 DCHECK(!details.urls.empty());
[email protected]b3ac5c82009-10-08 20:56:542927
[email protected]b3ac5c82009-10-08 20:56:542928 BookmarkEditor::Show(window()->GetNativeHandle(), profile_,
[email protected]ec12ffe2009-10-16 22:28:442929 model->GetParentForNewNodes(), details,
[email protected]97a056462010-04-28 16:46:352930 BookmarkEditor::SHOW_TREE);
[email protected]b3ac5c82009-10-08 20:56:542931}
2932
[email protected]0b4d3382010-07-14 16:13:042933bool Browser::CanCloseTab() const {
2934 TabCloseableStateWatcher* watcher =
2935 g_browser_process->tab_closeable_state_watcher();
2936 return !watcher || watcher->CanCloseTab(this);
2937}
2938
[email protected]b9c505b2010-04-30 15:05:102939void Browser::ToggleUseVerticalTabs() {
2940 use_vertical_tabs_.SetValue(!UseVerticalTabs());
[email protected]b3344872010-05-03 15:52:292941 UseVerticalTabsChanged();
[email protected]b9c505b2010-04-30 15:05:102942}
2943
[email protected]ac86c982011-05-11 13:26:052944void Browser::ToggleUseCompactNavigationBar() {
2945 use_compact_navigation_bar_.SetValue(!UseCompactNavigationBar());
2946 UseCompactNavigationBarChanged();
2947}
2948
[email protected]b283a7532010-08-12 21:24:592949bool Browser::LargeIconsPermitted() const {
[email protected]af801acd2010-08-20 20:27:442950 // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
2951 // for those windows, we already have a big icon in the top-left outside any
2952 // tab. Having big tab icons too looks kinda redonk.
[email protected]94ce7252010-12-20 21:46:332953 return true;
[email protected]b283a7532010-08-12 21:24:592954}
2955
[email protected]2d46c842008-11-14 19:24:312956///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:572957// Browser, TabStripModelObserver implementation:
2958
[email protected]3c9e1872010-11-18 16:17:492959void Browser::TabInsertedAt(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:572960 int index,
2961 bool foreground) {
[email protected]9219d262011-02-15 21:05:122962 SetAsDelegate(contents, this);
[email protected]81898992011-06-14 22:15:002963 contents->restore_tab_helper()->SetWindowID(session_id());
[email protected]e524ff92011-03-30 13:26:582964
[email protected]c37e3b62010-01-22 00:15:172965 SyncHistoryWithTabs(index);
[email protected]36b6dcb2008-11-12 01:19:572966
[email protected]159f7762008-12-19 14:58:272967 // Make sure the loading state is updated correctly, otherwise the throbber
2968 // won't start if the page is loading.
[email protected]3c9e1872010-11-18 16:17:492969 LoadingStateChanged(contents->tab_contents());
[email protected]159f7762008-12-19 14:58:272970
[email protected]36b6dcb2008-11-12 01:19:572971 // If the tab crashes in the beforeunload or unload handler, it won't be
2972 // able to ack. But we know we can close it.
[email protected]432115822011-07-10 15:52:272973 registrar_.Add(this, content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:052974 Source<TabContents>(contents->tab_contents()));
[email protected]93f230e02011-06-01 14:40:002975
[email protected]432115822011-07-10 15:52:272976 registrar_.Add(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]93f230e02011-06-01 14:40:002977 Source<TabContents>(contents->tab_contents()));
[email protected]36b6dcb2008-11-12 01:19:572978}
2979
[email protected]f2cc7382010-10-15 18:03:052980void Browser::TabClosingAt(TabStripModel* tab_strip_model,
[email protected]3c9e1872010-11-18 16:17:492981 TabContentsWrapper* contents,
[email protected]f2cc7382010-10-15 18:03:052982 int index) {
[email protected]bfd04a62009-02-01 18:16:562983 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:272984 content::NOTIFICATION_TAB_CLOSING,
[email protected]ce3fa3c2009-04-20 19:55:572985 Source<NavigationController>(&contents->controller()),
[email protected]bfd04a62009-02-01 18:16:562986 NotificationService::NoDetails());
[email protected]36b6dcb2008-11-12 01:19:572987
2988 // Sever the TabContents' connection back to us.
[email protected]9219d262011-02-15 21:05:122989 SetAsDelegate(contents, NULL);
[email protected]36b6dcb2008-11-12 01:19:572990}
2991
[email protected]3c9e1872010-11-18 16:17:492992void Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
[email protected]c37e3b62010-01-22 00:15:172993 TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
[email protected]36b6dcb2008-11-12 01:19:572994}
2995
[email protected]9ac8a242011-06-07 19:42:522996void Browser::TabDeactivated(TabContentsWrapper* contents) {
[email protected]6b723f82010-10-05 20:14:272997 if (instant())
2998 instant()->DestroyPreviewContents();
[email protected]03bb953d2010-09-14 21:38:302999
[email protected]85ff2c42009-05-29 21:22:033000 // Save what the user's currently typing, so it can be restored when we
3001 // switch back to this tab.
[email protected]3c9e1872010-11-18 16:17:493002 window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
[email protected]85ff2c42009-05-29 21:22:033003}
3004
[email protected]3aca95d42011-05-24 22:06:543005void Browser::ActiveTabChanged(TabContentsWrapper* old_contents,
3006 TabContentsWrapper* new_contents,
3007 int index,
3008 bool user_gesture) {
[email protected]a8f024392011-01-13 21:50:163009 // On some platforms we want to automatically reload tabs that are
3010 // killed when the user selects them.
3011 if (user_gesture && new_contents->tab_contents()->crashed_status() ==
3012 base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
3013 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
[email protected]f8a35772011-02-02 23:17:563014 if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
[email protected]a8f024392011-01-13 21:50:163015 Reload(CURRENT_TAB);
[email protected]f8a35772011-02-02 23:17:563016 return;
3017 }
[email protected]a8f024392011-01-13 21:50:163018 }
3019
[email protected]36b6dcb2008-11-12 01:19:573020 // If we have any update pending, do it now.
3021 if (!chrome_updater_factory_.empty() && old_contents)
3022 ProcessPendingUIUpdates();
3023
[email protected]36b6dcb2008-11-12 01:19:573024 // Propagate the profile to the location bar.
3025 UpdateToolbar(true);
3026
[email protected]943d8122010-06-11 02:13:453027 // Update reload/stop state.
[email protected]f5d978c2011-07-21 14:43:513028 UpdateReloadStopState(new_contents->tab_contents()->IsLoading(), true);
[email protected]36b6dcb2008-11-12 01:19:573029
[email protected]84214982008-12-10 18:49:103030 // Update commands to reflect current state.
3031 UpdateCommandsForTabState();
[email protected]36b6dcb2008-11-12 01:19:573032
3033 // Reset the status bubble.
[email protected]be3877f2009-01-14 15:51:103034 StatusBubble* status_bubble = GetStatusBubble();
3035 if (status_bubble) {
3036 status_bubble->Hide();
[email protected]36b6dcb2008-11-12 01:19:573037
[email protected]be3877f2009-01-14 15:51:103038 // Show the loading state (if any).
[email protected]0dd3a0ab2011-02-18 08:17:443039 status_bubble->SetStatus(GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]be3877f2009-01-14 15:51:103040 }
[email protected]36b6dcb2008-11-12 01:19:573041
[email protected]24db8a072009-10-29 20:35:373042 if (HasFindBarController()) {
[email protected]9c318862011-02-01 22:27:243043 find_bar_controller_->ChangeTabContents(new_contents);
[email protected]b77cb302009-10-29 04:09:173044 find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
[email protected]4801ecc2009-04-05 04:52:583045 }
3046
[email protected]36b6dcb2008-11-12 01:19:573047 // Update sessions. Don't force creation of sessions. If sessions doesn't
3048 // exist, the change will be picked up by sessions when created.
[email protected]92371eb2011-04-28 11:50:153049 SessionService* session_service =
3050 SessionServiceFactory::GetForProfileIfExisting(profile_);
3051 if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
3052 session_service->SetSelectedTabInWindow(
3053 session_id(), tab_handler_->GetTabStripModel()->active_index());
[email protected]36b6dcb2008-11-12 01:19:573054 }
[email protected]09b29342011-06-24 19:18:483055
3056 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH);
[email protected]36b6dcb2008-11-12 01:19:573057}
3058
[email protected]3c9e1872010-11-18 16:17:493059void Browser::TabMoved(TabContentsWrapper* contents,
[email protected]36b6dcb2008-11-12 01:19:573060 int from_index,
[email protected]1a242c32010-02-02 21:20:543061 int to_index) {
[email protected]36b6dcb2008-11-12 01:19:573062 DCHECK(from_index >= 0 && to_index >= 0);
3063 // Notify the history service.
3064 SyncHistoryWithTabs(std::min(from_index, to_index));
3065}
3066
[email protected]da25dd52011-01-11 19:06:303067void Browser::TabReplacedAt(TabStripModel* tab_strip_model,
3068 TabContentsWrapper* old_contents,
[email protected]3c9e1872010-11-18 16:17:493069 TabContentsWrapper* new_contents,
[email protected]8a34e6602010-10-02 17:29:433070 int index) {
[email protected]c37e3b62010-01-22 00:15:173071 TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
3072 TabInsertedAt(new_contents, index,
[email protected]1ea49d52011-04-12 17:44:443073 (index == tab_handler_->GetTabStripModel()->active_index()));
[email protected]c37e3b62010-01-22 00:15:173074
3075 int entry_count = new_contents->controller().entry_count();
3076 if (entry_count > 0) {
3077 // Send out notification so that observers are updated appropriately.
3078 new_contents->controller().NotifyEntryChanged(
3079 new_contents->controller().GetEntryAtIndex(entry_count - 1),
3080 entry_count - 1);
3081 }
[email protected]47e020a2010-10-15 14:43:373082
[email protected]92371eb2011-04-28 11:50:153083 SessionService* session_service =
3084 SessionServiceFactory::GetForProfile(profile());
[email protected]47e020a2010-10-15 14:43:373085 if (session_service) {
3086 // The new_contents may end up with a different navigation stack. Force
3087 // the session service to update itself.
3088 session_service->TabRestored(
[email protected]81898992011-06-14 22:15:003089 new_contents, tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]47e020a2010-10-15 14:43:373090 }
[email protected]2914600d2011-01-31 23:25:143091
3092 DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
3093 if (devtools_manager) // NULL in unit tests.
[email protected]dce502762011-07-20 08:53:493094 devtools_manager->TabReplaced(old_contents->tab_contents(),
3095 new_contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:173096}
3097
[email protected]3c9e1872010-11-18 16:17:493098void Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
[email protected]92371eb2011-04-28 11:50:153099 SessionService* session_service =
3100 SessionServiceFactory::GetForProfileIfExisting(profile());
[email protected]5c0e6482009-07-14 20:20:093101 if (session_service) {
3102 session_service->SetPinnedState(
3103 session_id(),
[email protected]81898992011-06-14 22:15:003104 GetTabContentsWrapperAt(index)->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:403105 tab_handler_->GetTabStripModel()->IsTabPinned(index));
[email protected]5c0e6482009-07-14 20:20:093106 }
3107}
3108
[email protected]36b6dcb2008-11-12 01:19:573109void Browser::TabStripEmpty() {
3110 // Close the frame after we return to the message loop (not immediately,
3111 // otherwise it will destroy this object before the stack has a chance to
3112 // cleanly unwind.)
3113 // Note: This will be called several times if TabStripEmpty is called several
3114 // times. This is because it does not close the window if tabs are
3115 // still present.
3116 // NOTE: If you change to be immediate (no invokeLater) then you'll need to
3117 // update BrowserList::CloseAllBrowsers.
[email protected]0586b0e2010-02-12 21:38:373118 MessageLoop::current()->PostTask(
3119 FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
[email protected]36b6dcb2008-11-12 01:19:573120}
3121
3122///////////////////////////////////////////////////////////////////////////////
3123// Browser, TabContentsDelegate implementation:
initial.commit09911bf2008-07-26 23:55:293124
[email protected]00c37fc2011-08-02 00:22:503125// TODO(adriansc): Remove this method once refactoring changed all call sites.
[email protected]992e4542011-07-20 23:09:253126TabContents* Browser::OpenURLFromTab(TabContents* source,
3127 const GURL& url,
3128 const GURL& referrer,
3129 WindowOpenDisposition disposition,
3130 PageTransition::Type transition) {
[email protected]00c37fc2011-08-02 00:22:503131 return OpenURLFromTab(source, OpenURLParams(url, referrer, disposition,
3132 transition));
3133}
3134
3135TabContents* Browser::OpenURLFromTab(TabContents* source,
3136 const OpenURLParams& params) {
3137 browser::NavigateParams nav_params(this, params.url, params.transition);
3138 nav_params.source_contents =
3139 tabstrip_model()->GetTabContentsAt(
3140 tabstrip_model()->GetWrapperIndex(source));
3141 nav_params.referrer = params.referrer;
3142 nav_params.disposition = params.disposition;
3143 nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
3144 nav_params.window_action = browser::NavigateParams::SHOW_WINDOW;
3145 nav_params.user_gesture = true;
3146 nav_params.override_encoding = params.override_encoding;
3147 browser::Navigate(&nav_params);
3148
3149 return nav_params.target_contents ?
3150 nav_params.target_contents->tab_contents() : NULL;
initial.commit09911bf2008-07-26 23:55:293151}
3152
3153void Browser::NavigationStateChanged(const TabContents* source,
3154 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:293155 // Only update the UI when something visible has changed.
[email protected]e83f1682008-09-07 23:57:403156 if (changed_flags)
initial.commit09911bf2008-07-26 23:55:293157 ScheduleUIUpdate(source, changed_flags);
3158
[email protected]84214982008-12-10 18:49:103159 // We don't schedule updates to commands since they will only change once per
3160 // navigation, so we don't have to worry about flickering.
[email protected]e83f1682008-09-07 23:57:403161 if (changed_flags & TabContents::INVALIDATE_URL)
[email protected]84214982008-12-10 18:49:103162 UpdateCommandsForTabState();
initial.commit09911bf2008-07-26 23:55:293163}
3164
initial.commit09911bf2008-07-26 23:55:293165void Browser::AddNewContents(TabContents* source,
3166 TabContents* new_contents,
3167 WindowOpenDisposition disposition,
3168 const gfx::Rect& initial_pos,
3169 bool user_gesture) {
[email protected]e7cfdbd2011-04-22 14:41:373170 // No code for this yet.
[email protected]616381f02010-11-02 15:15:333171 DCHECK(disposition != SAVE_TO_DISK);
3172 // Can't create a new contents for the current tab - invalid case.
3173 DCHECK(disposition != CURRENT_TAB);
initial.commit09911bf2008-07-26 23:55:293174
[email protected]e7cfdbd2011-04-22 14:41:373175 TabContentsWrapper* source_wrapper = NULL;
3176 BlockedContentTabHelper* source_blocked_content = NULL;
[email protected]ad1be1592011-04-27 14:14:453177 TabContentsWrapper* new_wrapper =
3178 TabContentsWrapper::GetCurrentWrapperForContents(new_contents);
3179 if (!new_wrapper)
3180 new_wrapper = new TabContentsWrapper(new_contents);
[email protected]e7cfdbd2011-04-22 14:41:373181 if (source) {
3182 source_wrapper = TabContentsWrapper::GetCurrentWrapperForContents(source);
3183 source_blocked_content = source_wrapper->blocked_content_tab_helper();
3184 }
3185
3186 if (source_wrapper) {
3187 // Handle blocking of all contents.
3188 if (source_blocked_content->all_contents_blocked()) {
3189 source_blocked_content->AddTabContents(new_wrapper,
3190 disposition,
3191 initial_pos,
3192 user_gesture);
3193 return;
3194 }
3195
3196 // Handle blocking of popups.
3197 if ((disposition == NEW_POPUP) && !user_gesture &&
3198 !CommandLine::ForCurrentProcess()->HasSwitch(
3199 switches::kDisablePopupBlocking)) {
3200 // Unrequested popups from normal pages are constrained unless they're in
3201 // the whitelist. The popup owner will handle checking this.
[email protected]393c0ed02011-04-22 14:55:363202 GetConstrainingContentsWrapper(source_wrapper)->
3203 blocked_content_tab_helper()->
3204 AddPopup(new_wrapper, initial_pos, user_gesture);
[email protected]e7cfdbd2011-04-22 14:41:373205 return;
3206 }
3207
[email protected]216813952011-05-19 22:21:263208 RenderViewHost* view = new_contents->render_view_host();
3209 view->Send(new ViewMsg_DisassociateFromPopupCount(view->routing_id()));
[email protected]e7cfdbd2011-04-22 14:41:373210 }
3211
[email protected]e7cfdbd2011-04-22 14:41:373212 browser::NavigateParams params(this, new_wrapper);
[email protected]3c9e1872010-11-18 16:17:493213 params.source_contents =
[email protected]e7cfdbd2011-04-22 14:41:373214 source ? tabstrip_model()->GetTabContentsAt(
3215 tabstrip_model()->GetWrapperIndex(source))
3216 : NULL;
[email protected]3c9e1872010-11-18 16:17:493217 params.disposition = disposition;
3218 params.window_bounds = initial_pos;
[email protected]588300d2011-04-28 21:06:353219 params.window_action = browser::NavigateParams::SHOW_WINDOW;
3220 params.user_gesture = user_gesture;
[email protected]3c9e1872010-11-18 16:17:493221 browser::Navigate(&params);
[email protected]e7cfdbd2011-04-22 14:41:373222
[email protected]a4f10c52011-07-25 09:42:013223 NotificationService::current()->Notify(
3224 content::NOTIFICATION_TAB_ADDED,
3225 Source<TabContentsDelegate>(this),
3226 Details<TabContents>(new_contents));
initial.commit09911bf2008-07-26 23:55:293227}
3228
initial.commit09911bf2008-07-26 23:55:293229void Browser::ActivateContents(TabContents* contents) {
[email protected]eaca0ad12011-04-18 15:53:413230 tab_handler_->GetTabStripModel()->ActivateTabAt(
[email protected]3c9e1872010-11-18 16:17:493231 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
[email protected]f3e99e32008-07-30 04:48:393232 window_->Activate();
initial.commit09911bf2008-07-26 23:55:293233}
3234
[email protected]ea42e7782010-08-23 23:58:123235void Browser::DeactivateContents(TabContents* contents) {
3236 window_->Deactivate();
3237}
3238
initial.commit09911bf2008-07-26 23:55:293239void Browser::LoadingStateChanged(TabContents* source) {
[email protected]ecc523f62010-09-28 22:45:403240 window_->UpdateLoadingAnimations(
3241 tab_handler_->GetTabStripModel()->TabsAreLoading());
[email protected]f3e99e32008-07-30 04:48:393242 window_->UpdateTitleBar();
initial.commit09911bf2008-07-26 23:55:293243
[email protected]3c9e1872010-11-18 16:17:493244 TabContents* selected_contents = GetSelectedTabContents();
3245 if (source == selected_contents) {
[email protected]f5d978c2011-07-21 14:43:513246 bool is_loading = source->IsLoading();
3247 UpdateReloadStopState(is_loading, false);
[email protected]43d259d2010-09-03 21:37:463248 if (GetStatusBubble()) {
[email protected]0dd3a0ab2011-02-18 08:17:443249 GetStatusBubble()->SetStatus(
3250 GetSelectedTabContentsWrapper()->GetStatusText());
[email protected]43d259d2010-09-03 21:37:463251 }
[email protected]eabfdae92009-12-11 06:13:513252
[email protected]f5d978c2011-07-21 14:43:513253 if (!is_loading && pending_web_app_action_ == UPDATE_SHORTCUT) {
[email protected]867dff82010-04-23 21:30:333254 // Schedule a shortcut update when web application info is available if
3255 // last committed entry is not NULL. Last committed entry could be NULL
3256 // when an interstitial page is injected (e.g. bad https certificate,
3257 // malware site etc). When this happens, we abort the shortcut update.
[email protected]eabfdae92009-12-11 06:13:513258 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3259 if (entry) {
[email protected]553602e12011-04-05 17:01:183260 TabContentsWrapper::GetCurrentWrapperForContents(source)->
3261 extension_tab_helper()->GetApplicationInfo(entry->page_id());
[email protected]eabfdae92009-12-11 06:13:513262 } else {
3263 pending_web_app_action_ = NONE;
[email protected]eabfdae92009-12-11 06:13:513264 }
3265 }
initial.commit09911bf2008-07-26 23:55:293266 }
3267}
3268
3269void Browser::CloseContents(TabContents* source) {
[email protected]04b4a6c2008-08-02 00:44:473270 if (is_attempting_to_close_browser_) {
3271 // If we're trying to close the browser, just clear the state related to
[email protected]adf650f2008-12-09 16:10:063272 // waiting for unload to fire. Don't actually try to close the tab as it
[email protected]04b4a6c2008-08-02 00:44:473273 // will go down the slow shutdown path instead of the fast path of killing
3274 // all the renderer processes.
[email protected]08f0d612011-01-13 23:58:213275 ClearUnloadState(source, true);
[email protected]04b4a6c2008-08-02 00:44:473276 return;
3277 }
3278
[email protected]3c9e1872010-11-18 16:17:493279 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
initial.commit09911bf2008-07-26 23:55:293280 if (index == TabStripModel::kNoTab) {
3281 NOTREACHED() << "CloseContents called for tab not in our strip";
3282 return;
3283 }
[email protected]ecc523f62010-09-28 22:45:403284 tab_handler_->GetTabStripModel()->CloseTabContentsAt(
[email protected]0cce15f2010-05-21 16:58:393285 index,
3286 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
initial.commit09911bf2008-07-26 23:55:293287}
3288
[email protected]15e8abe2008-08-20 22:40:403289void Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
[email protected]b35b26b32011-05-05 20:35:143290 if (!IsPopupOrPanel(source)) {
initial.commit09911bf2008-07-26 23:55:293291 NOTREACHED() << "moving invalid browser type";
3292 return;
3293 }
[email protected]e561e202010-03-24 17:57:123294 window_->SetBounds(pos);
initial.commit09911bf2008-07-26 23:55:293295}
3296
[email protected]b6c874582009-05-08 19:38:313297void Browser::DetachContents(TabContents* source) {
[email protected]3c9e1872010-11-18 16:17:493298 int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
[email protected]b6c874582009-05-08 19:38:313299 if (index >= 0)
[email protected]ecc523f62010-09-28 22:45:403300 tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
[email protected]b6c874582009-05-08 19:38:313301}
3302
[email protected]b35b26b32011-05-05 20:35:143303bool Browser::IsPopupOrPanel(const TabContents* source) const {
initial.commit09911bf2008-07-26 23:55:293304 // A non-tabbed BROWSER is an unconstrained popup.
[email protected]b35b26b32011-05-05 20:35:143305 return is_type_popup() || is_type_panel();
initial.commit09911bf2008-07-26 23:55:293306}
3307
[email protected]b8595e92009-11-14 01:18:003308void Browser::ContentsMouseEvent(
3309 TabContents* source, const gfx::Point& location, bool motion) {
[email protected]be3877f2009-01-14 15:51:103310 if (!GetStatusBubble())
3311 return;
3312
[email protected]36b6dcb2008-11-12 01:19:573313 if (source == GetSelectedTabContents()) {
[email protected]b8595e92009-11-14 01:18:003314 GetStatusBubble()->MouseMoved(location, !motion);
3315 if (!motion)
[email protected]65233052011-08-22 19:02:483316 GetStatusBubble()->SetURL(GURL(), std::string());
[email protected]36b6dcb2008-11-12 01:19:573317 }
3318}
3319
3320void Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
[email protected]be3877f2009-01-14 15:51:103321 if (!GetStatusBubble())
3322 return;
3323
[email protected]36b6dcb2008-11-12 01:19:573324 if (source == GetSelectedTabContents()) {
3325 PrefService* prefs = profile_->GetPrefs();
[email protected]65233052011-08-22 19:02:483326 GetStatusBubble()->SetURL(url, prefs->GetString(prefs::kAcceptLanguages));
[email protected]36b6dcb2008-11-12 01:19:573327 }
3328}
3329
[email protected]3a6a3b62009-05-27 21:36:203330void Browser::UpdateDownloadShelfVisibility(bool visible) {
[email protected]9b032bf2009-07-21 17:34:233331 if (GetStatusBubble())
3332 GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
[email protected]3a6a3b62009-05-27 21:36:203333}
3334
[email protected]aa02fff12010-07-21 19:55:253335bool Browser::UseVerticalTabs() const {
3336 return use_vertical_tabs_.GetValue();
3337}
3338
[email protected]ac86c982011-05-11 13:26:053339bool Browser::UseCompactNavigationBar() const {
3340 return use_compact_navigation_bar_.GetValue();
3341}
3342
[email protected]36b6dcb2008-11-12 01:19:573343void Browser::ContentsZoomChange(bool zoom_in) {
[email protected]b75b8292010-10-01 07:28:253344 ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
[email protected]36b6dcb2008-11-12 01:19:573345}
3346
[email protected]fa1cf0b82010-01-15 21:49:443347void Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
[email protected]3c9e1872010-11-18 16:17:493348 int index = tabstrip_model()->GetWrapperIndex(contents);
[email protected]fa1cf0b82010-01-15 21:49:443349 if (index == TabStripModel::kNoTab) {
3350 NOTREACHED();
3351 return;
3352 }
3353 tabstrip_model()->SetTabBlocked(index, blocked);
3354}
3355
[email protected]7e383692009-06-12 19:14:543356void Browser::TabContentsFocused(TabContents* tab_content) {
3357 window_->TabContentsFocused(tab_content);
3358}
3359
[email protected]130efb02009-09-18 18:54:353360bool Browser::TakeFocus(bool reverse) {
3361 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:273362 chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER,
[email protected]130efb02009-09-18 18:54:353363 Source<Browser>(this),
3364 NotificationService::NoDetails());
3365 return false;
3366}
3367
[email protected]36b6dcb2008-11-12 01:19:573368bool Browser::IsApplication() const {
[email protected]b35b26b32011-05-05 20:35:143369 return is_app();
[email protected]36b6dcb2008-11-12 01:19:573370}
3371
3372void Browser::ConvertContentsToApplication(TabContents* contents) {
[email protected]ce3fa3c2009-04-20 19:55:573373 const GURL& url = contents->controller().GetActiveEntry()->url();
[email protected]57ecc4b2010-08-11 03:02:513374 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
[email protected]36b6dcb2008-11-12 01:19:573375
[email protected]b6c874582009-05-08 19:38:313376 DetachContents(contents);
[email protected]94ce7252010-12-20 21:46:333377 Browser* app_browser = Browser::CreateForApp(
[email protected]5c209242011-06-06 20:36:173378 TYPE_POPUP, app_name, gfx::Rect(), profile_);
[email protected]ae2f2a772011-05-04 16:30:273379 TabContentsWrapper* wrapper =
3380 TabContentsWrapper::GetCurrentWrapperForContents(contents);
3381 if (!wrapper)
3382 wrapper = new TabContentsWrapper(contents);
[email protected]75aef122010-12-06 21:48:323383 app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3384
3385 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
3386 contents->render_view_host()->SyncRendererPrefs();
3387 app_browser->window()->Show();
[email protected]36b6dcb2008-11-12 01:19:573388}
3389
[email protected]36b6dcb2008-11-12 01:19:573390void Browser::BeforeUnloadFired(TabContents* tab,
3391 bool proceed,
3392 bool* proceed_to_fire_unload) {
3393 if (!is_attempting_to_close_browser_) {
3394 *proceed_to_fire_unload = proceed;
[email protected]0cce15f2010-05-21 16:58:393395 if (!proceed)
3396 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573397 return;
3398 }
3399
3400 if (!proceed) {
3401 CancelWindowClose();
3402 *proceed_to_fire_unload = false;
[email protected]0cce15f2010-05-21 16:58:393403 tab->set_closed_by_user_gesture(false);
[email protected]36b6dcb2008-11-12 01:19:573404 return;
3405 }
3406
[email protected]06b42f032008-12-03 18:43:053407 if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
[email protected]2d46c842008-11-14 19:24:313408 // Now that beforeunload has fired, put the tab on the queue to fire
3409 // unload.
[email protected]06b42f032008-12-03 18:43:053410 tabs_needing_unload_fired_.insert(tab);
[email protected]36b6dcb2008-11-12 01:19:573411 ProcessPendingTabs();
[email protected]adf650f2008-12-09 16:10:063412 // We want to handle firing the unload event ourselves since we want to
[email protected]36b6dcb2008-11-12 01:19:573413 // fire all the beforeunload events before attempting to fire the unload
3414 // events should the user cancel closing the browser.
3415 *proceed_to_fire_unload = false;
3416 return;
3417 }
3418
3419 *proceed_to_fire_unload = true;
3420}
3421
[email protected]a26dc362010-04-23 01:48:583422void Browser::SetFocusToLocationBar(bool select_all) {
[email protected]1a380622009-02-17 17:33:133423 // Two differences between this and FocusLocationBar():
3424 // (1) This doesn't get recorded in user metrics, since it's called
3425 // internally.
3426 // (2) This checks whether the location bar can be focused, and if not, clears
3427 // the focus. FocusLocationBar() is only reached when the location bar is
3428 // focusable, but this may be reached at other times, e.g. while in
3429 // fullscreen mode, where we need to leave focus in a consistent state.
[email protected]a26dc362010-04-23 01:48:583430 window_->SetFocusToLocationBar(select_all);
[email protected]4bcefee2009-01-29 15:57:573431}
3432
[email protected]7d5925a2009-03-03 02:59:123433void Browser::RenderWidgetShowing() {
3434 window_->DisableInactiveFrame();
3435}
[email protected]a239c3f2009-02-17 22:13:193436
[email protected]0a2aeb82009-05-15 21:52:483437int Browser::GetExtraRenderViewHeight() const {
3438 return window_->GetExtraRenderViewHeight();
3439}
3440
[email protected]a0e4b072011-08-17 01:47:073441namespace {
3442
3443bool DisplayOldDownloadsUI() {
3444 return !CommandLine::ForCurrentProcess()->HasSwitch(
3445 switches::kDownloadsNewUI);
3446}
3447
3448} // anonymous namespace
3449
[email protected]686493142011-07-15 21:47:223450void Browser::OnStartDownload(TabContents* source, DownloadItem* download) {
3451 TabContentsWrapper* wrapper =
3452 TabContentsWrapper::GetCurrentWrapperForContents(source);
3453 TabContentsWrapper* constrained = GetConstrainingContentsWrapper(wrapper);
3454 if (constrained != wrapper) {
3455 // Download in a constrained popup is shown in the tab that opened it.
3456 TabContents* constrained_tab = constrained->tab_contents();
3457 constrained_tab->delegate()->OnStartDownload(constrained_tab, download);
3458 return;
3459 }
3460
3461 if (!window())
3462 return;
3463
[email protected]a0e4b072011-08-17 01:47:073464 if (DisplayOldDownloadsUI()) {
[email protected]686493142011-07-15 21:47:223465#if defined(OS_CHROMEOS)
[email protected]a0e4b072011-08-17 01:47:073466 // Don't show content browser for extension/theme downloads from gallery.
[email protected]686493142011-07-15 21:47:223467 ExtensionService* service = profile_->GetExtensionService();
[email protected]8a282712011-08-23 19:28:003468 if (!ChromeDownloadManagerDelegate::IsExtensionDownload(download) ||
[email protected]a0e4b072011-08-17 01:47:073469 (service == NULL) ||
3470 !service->IsDownloadFromGallery(download->GetURL(),
3471 download->referrer_url())) {
3472 // Open the Active Downloads ui for chromeos.
3473 ActiveDownloadsUI::OpenPopup(profile_);
[email protected]686493142011-07-15 21:47:223474 }
[email protected]686493142011-07-15 21:47:223475#else
[email protected]a0e4b072011-08-17 01:47:073476 // GetDownloadShelf creates the download shelf if it was not yet created.
3477 DownloadShelf* shelf = window()->GetDownloadShelf();
3478 shelf->AddDownload(new DownloadItemModel(download));
3479 // Don't show the animation for "Save file" downloads.
3480 // For non-theme extensions, we don't show the download animation.
3481 // Show animation in same window as the download shelf. Download shelf
3482 // may not be in the same window that initiated the download, e.g.
3483 // Panels.
3484 // Don't show the animation if the selected tab is not visible (i.e. the
3485 // window is minimized, we're in a unit test, etc.).
3486 TabContents* shelf_tab = shelf->browser()->GetSelectedTabContents();
3487 if ((download->total_bytes() > 0) &&
[email protected]8a282712011-08-23 19:28:003488 (!ChromeDownloadManagerDelegate::IsExtensionDownload(download) ||
[email protected]a0e4b072011-08-17 01:47:073489 ExtensionService::IsDownloadFromMiniGallery(download->GetURL())) &&
3490 platform_util::IsVisible(shelf_tab->GetNativeView()) &&
3491 ui::Animation::ShouldRenderRichAnimation()) {
3492 DownloadStartedAnimation::Show(shelf_tab);
3493 }
[email protected]686493142011-07-15 21:47:223494#endif
[email protected]a0e4b072011-08-17 01:47:073495 }
[email protected]686493142011-07-15 21:47:223496
3497 // If the download occurs in a new tab, close it.
3498 if (source->controller().IsInitialNavigation() && tab_count() > 1)
3499 CloseContents(source);
3500}
3501
[email protected]3d7474ff2011-07-27 17:47:373502void Browser::ShowPageInfo(content::BrowserContext* browser_context,
[email protected]4d677202009-07-19 07:37:123503 const GURL& url,
3504 const NavigationEntry::SSLStatus& ssl,
3505 bool show_history) {
[email protected]3d7474ff2011-07-27 17:47:373506 Profile* profile = Profile::FromBrowserContext(browser_context);
[email protected]bb678332009-07-21 00:15:503507 window()->ShowPageInfo(profile, url, ssl, show_history);
[email protected]4d677202009-07-19 07:37:123508}
3509
[email protected]1788e772010-12-15 16:40:503510void Browser::ViewSourceForTab(TabContents* source, const GURL& page_url) {
3511 DCHECK(source);
3512 int index = tabstrip_model()->GetWrapperIndex(source);
[email protected]77d8d622010-12-15 10:30:123513 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3514 ViewSource(wrapper);
3515}
3516
[email protected]932b7a12011-03-09 12:50:273517void Browser::ViewSourceForFrame(TabContents* source,
3518 const GURL& frame_url,
3519 const std::string& frame_content_state) {
3520 DCHECK(source);
3521 int index = tabstrip_model()->GetWrapperIndex(source);
3522 TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3523 ViewSource(wrapper, frame_url, frame_content_state);
3524}
3525
[email protected]867125a02009-12-10 06:01:483526bool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3527 bool* is_keyboard_shortcut) {
3528 return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3529}
[email protected]97df4b332009-10-02 01:25:413530
[email protected]867125a02009-12-10 06:01:483531void Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3532 window()->HandleKeyboardEvent(event);
[email protected]97df4b332009-10-02 01:25:413533}
3534
[email protected]14f3408a2009-08-31 20:53:533535void Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
3536 window()->ShowRepostFormWarningDialog(tab_contents);
3537}
3538
[email protected]579e3192011-03-11 22:37:453539void Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
[email protected]445177652011-03-09 02:04:053540 ShowOptionsTab(
3541 chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
3542 ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
[email protected]63543142010-02-09 23:22:203543}
3544
[email protected]a503c97c2010-07-16 13:05:483545void Browser::ShowCollectedCookiesDialog(TabContents *tab_contents) {
3546 window()->ShowCollectedCookiesDialog(tab_contents);
3547}
3548
[email protected]ec0b6c42010-08-26 03:16:583549bool Browser::ShouldAddNavigationToHistory(
3550 const history::HistoryAddPageArgs& add_page_args,
3551 NavigationType::Type navigation_type) {
[email protected]2e29d922009-10-22 22:13:353552 // Don't update history if running as app.
3553 return !IsApplication();
3554}
3555
[email protected]9e823662010-10-13 23:36:003556void Browser::ContentRestrictionsChanged(TabContents* source) {
3557 UpdateCommandsForContentRestrictionState();
3558}
3559
[email protected]55452902011-06-01 21:57:473560void Browser::RendererUnresponsive(TabContents* source) {
3561 browser::ShowHungRendererDialog(source);
3562}
3563
3564void Browser::RendererResponsive(TabContents* source) {
3565 browser::HideHungRendererDialog(source);
3566}
3567
3568void Browser::WorkerCrashed(TabContents* source) {
3569 TabContentsWrapper* wrapper =
3570 TabContentsWrapper::GetCurrentWrapperForContents(source);
3571 wrapper->AddInfoBar(new SimpleAlertInfoBarDelegate(
3572 source, NULL, l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT),
3573 true));
[email protected]0dd3a0ab2011-02-18 08:17:443574}
3575
[email protected]09b29342011-06-24 19:18:483576void Browser::DidNavigateMainFramePostCommit(TabContents* tab) {
3577 if (tab == GetSelectedTabContents())
3578 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003579}
3580
[email protected]09b29342011-06-24 19:18:483581void Browser::DidNavigateToPendingEntry(TabContents* tab) {
3582 if (tab == GetSelectedTabContents())
3583 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
[email protected]93f230e02011-06-01 14:40:003584}
3585
[email protected]3ab9cb82011-06-03 18:02:073586content::JavaScriptDialogCreator* Browser::GetJavaScriptDialogCreator() {
3587 return GetJavaScriptDialogCreatorInstance();
3588}
3589
[email protected]3a29a6e2011-08-24 18:26:213590void Browser::RunFileChooser(TabContents* tab,
3591 const ViewHostMsg_RunFileChooser_Params& params) {
3592 Browser::RunFileChooserHelper(tab, params);
3593}
3594
3595void Browser::EnumerateDirectory(TabContents* tab, int request_id,
3596 const FilePath& path) {
3597 Browser::EnumerateDirectoryHelper(tab, request_id, path);
3598}
3599
[email protected]36b6dcb2008-11-12 01:19:573600///////////////////////////////////////////////////////////////////////////////
[email protected]a0366a52011-02-04 20:04:213601// Browser, TabContentsWrapperDelegate implementation:
3602
[email protected]553602e12011-04-05 17:01:183603void Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
3604 int32 page_id) {
3605 if (GetSelectedTabContentsWrapper() != source)
3606 return;
3607
3608 NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3609 if (!entry || (entry->page_id() != page_id))
3610 return;
3611
3612 switch (pending_web_app_action_) {
3613 case CREATE_SHORTCUT: {
3614 window()->ShowCreateWebAppShortcutsDialog(source);
3615 break;
3616 }
3617 case UPDATE_SHORTCUT: {
3618 web_app::UpdateShortcutForTabContents(source);
3619 break;
3620 }
3621 default:
3622 NOTREACHED();
3623 break;
3624 }
3625
3626 pending_web_app_action_ = NONE;
3627}
3628
3629void Browser::OnInstallApplication(TabContentsWrapper* source,
3630 const WebApplicationInfo& web_app) {
[email protected]14908b72011-04-20 06:54:363631 ExtensionService* extension_service = profile()->GetExtensionService();
3632 if (!extension_service)
[email protected]553602e12011-04-05 17:01:183633 return;
3634
[email protected]14908b72011-04-20 06:54:363635 scoped_refptr<CrxInstaller> installer(extension_service->MakeCrxInstaller(
3636 extension_service->show_extensions_prompts() ?
3637 new ExtensionInstallUI(profile()) : NULL));
[email protected]553602e12011-04-05 17:01:183638 installer->InstallWebApp(web_app);
3639}
3640
[email protected]c90c6ca2011-02-16 20:11:383641///////////////////////////////////////////////////////////////////////////////
3642// Browser, SearchEngineTabHelperDelegate implementation:
3643
[email protected]9219d262011-02-15 21:05:123644void Browser::ConfirmSetDefaultSearchProvider(
[email protected]b5a1d11c2011-02-17 03:09:423645 TabContents* tab_contents,
[email protected]9219d262011-02-15 21:05:123646 TemplateURL* template_url,
[email protected]8e5c89a2011-06-07 18:13:333647 TemplateURLService* template_url_service) {
[email protected]9219d262011-02-15 21:05:123648 window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
[email protected]8e5c89a2011-06-07 18:13:333649 template_url_service);
[email protected]9219d262011-02-15 21:05:123650}
3651
3652void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
3653 Profile* profile) {
3654 window()->ConfirmAddSearchProvider(template_url, profile);
3655}
3656
[email protected]a0366a52011-02-04 20:04:213657///////////////////////////////////////////////////////////////////////////////
[email protected]e7cfdbd2011-04-22 14:41:373658// Browser, BlockedContentTabHelperDelegate implementation:
3659
[email protected]393c0ed02011-04-22 14:55:363660TabContentsWrapper* Browser::GetConstrainingContentsWrapper(
[email protected]e7cfdbd2011-04-22 14:41:373661 TabContentsWrapper* source) {
3662 return source;
3663}
3664
3665///////////////////////////////////////////////////////////////////////////////
[email protected]35699d572011-05-11 19:46:143666// Browser, BookmarkTabHelperDelegate implementation:
[email protected]52cc59b2011-05-06 14:42:383667
3668void Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
3669 if (source == GetSelectedTabContentsWrapper())
3670 window_->SetStarredState(starred);
3671}
3672
3673///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573674// Browser, SelectFileDialog::Listener implementation:
3675
[email protected]561abe62009-04-06 18:08:343676void Browser::FileSelected(const FilePath& path, int index, void* params) {
[email protected]35896a32010-06-09 08:42:513677 profile_->set_last_selected_directory(path.DirName());
[email protected]72cbd322009-04-07 10:17:123678 GURL file_url = net::FilePathToFileURL(path);
[email protected]36b6dcb2008-11-12 01:19:573679 if (!file_url.is_empty())
3680 OpenURL(file_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
3681}
3682
3683///////////////////////////////////////////////////////////////////////////////
3684// Browser, NotificationObserver implementation:
3685
[email protected]432115822011-07-10 15:52:273686void Browser::Observe(int type,
initial.commit09911bf2008-07-26 23:55:293687 const NotificationSource& source,
3688 const NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:273689 switch (type) {
3690 case content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED:
[email protected]e83f1682008-09-07 23:57:403691 if (is_attempting_to_close_browser_) {
[email protected]08f0d612011-01-13 23:58:213692 // Pass in false so that we delay processing. We need to delay the
3693 // processing as it may close the tab, which is currently on the call
3694 // stack above us.
3695 ClearUnloadState(Source<TabContents>(source).ptr(), false);
[email protected]e83f1682008-09-07 23:57:403696 }
3697 break;
3698
[email protected]432115822011-07-10 15:52:273699 case content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED:
[email protected]e83f1682008-09-07 23:57:403700 // When the current tab's SSL state changes, we need to update the URL
[email protected]90e8d062008-09-08 02:26:323701 // bar to reflect the new state. Note that it's possible for the selected
3702 // tab contents to be NULL. This is because we listen for all sources
3703 // (NavigationControllers) for convenience, so the notification could
3704 // actually be for a different window while we're doing asynchronous
3705 // closing of this one.
3706 if (GetSelectedTabContents() &&
[email protected]ce3fa3c2009-04-20 19:55:573707 &GetSelectedTabContents()->controller() ==
[email protected]e83f1682008-09-07 23:57:403708 Source<NavigationController>(source).ptr())
[email protected]36b6dcb2008-11-12 01:19:573709 UpdateToolbar(false);
[email protected]e83f1682008-09-07 23:57:403710 break;
3711
[email protected]432115822011-07-10 15:52:273712 case chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED: {
[email protected]e6090e42010-03-23 22:44:083713 // Show the UI if the extension was disabled for escalated permissions.
[email protected]24e7a9d2009-11-04 11:11:343714 Profile* profile = Source<Profile>(source).ptr();
[email protected]bc535ee52010-08-31 18:40:323715 if (profile_->IsSameProfile(profile)) {
[email protected]eaa7dd182010-12-14 11:09:003716 ExtensionService* service = profile->GetExtensionService();
[email protected]bc535ee52010-08-31 18:40:323717 DCHECK(service);
[email protected]9adb9692010-10-29 23:14:023718 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]bc535ee52010-08-31 18:40:323719 if (service->extension_prefs()->DidExtensionEscalatePermissions(
3720 extension->id()))
3721 ShowExtensionDisabledUI(service, profile_, extension);
3722 }
[email protected]0c6da502009-08-14 22:32:393723 break;
3724 }
3725
[email protected]432115822011-07-10 15:52:273726 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]ce696a452011-05-31 17:47:363727 if (window()->GetLocationBar())
3728 window()->GetLocationBar()->UpdatePageActions();
[email protected]57f71b92009-09-11 19:31:383729
[email protected]894bb502009-05-21 22:39:573730 // Close any tabs from the unloaded extension.
[email protected]a9f39a312010-12-23 22:14:273731 const Extension* extension =
3732 Details<UnloadedExtensionInfo>(details)->extension;
[email protected]ecc523f62010-09-28 22:45:403733 TabStripModel* model = tab_handler_->GetTabStripModel();
3734 for (int i = model->count() - 1; i >= 0; --i) {
[email protected]3c9e1872010-11-18 16:17:493735 TabContents* tc = model->GetTabContentsAt(i)->tab_contents();
[email protected]894bb502009-05-21 22:39:573736 if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
3737 tc->GetURL().host() == extension->id()) {
3738 CloseTabContents(tc);
[email protected]894bb502009-05-21 22:39:573739 }
3740 }
[email protected]9fd542df2009-09-30 07:32:013741
[email protected]894bb502009-05-21 22:39:573742 break;
3743 }
3744
[email protected]432115822011-07-10 15:52:273745 case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
[email protected]ce696a452011-05-31 17:47:363746 if (window()->GetLocationBar())
3747 window()->GetLocationBar()->InvalidatePageActions();
[email protected]371ed7a2009-08-25 15:22:463748 break;
3749 }
3750
[email protected]432115822011-07-10 15:52:273751 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
3752 case chrome::NOTIFICATION_EXTENSION_LOADED:
[email protected]ce696a452011-05-31 17:47:363753 if (window()->GetLocationBar())
3754 window()->GetLocationBar()->UpdatePageActions();
[email protected]0dfe05c2011-02-23 23:03:363755 break;
[email protected]ad0c2e1b2010-01-30 00:00:103756
[email protected]432115822011-07-10 15:52:273757 case chrome::NOTIFICATION_BROWSER_THEME_CHANGED:
[email protected]e001d412009-06-26 20:53:253758 window()->UserChangedTheme();
3759 break;
3760
[email protected]432115822011-07-10 15:52:273761 case chrome::NOTIFICATION_EXTENSION_READY_FOR_INSTALL: {
[email protected]b35b26b32011-05-05 20:35:143762 // Handle EXTENSION_READY_FOR_INSTALL for last active tabbed browser.
3763 if (BrowserList::FindTabbedBrowser(profile(), true) != this)
[email protected]91e1bd82009-09-03 22:04:403764 break;
[email protected]ac025282009-12-16 19:16:383765
3766 // We only want to show the loading dialog for themes, but we don't want
3767 // to wait until unpack to find out an extension is a theme, so we test
3768 // the download_url GURL instead. This means that themes in the extensions
3769 // gallery won't get the loading dialog.
3770 GURL download_url = *(Details<GURL>(details).ptr());
[email protected]eaa7dd182010-12-14 11:09:003771 if (ExtensionService::IsDownloadFromMiniGallery(download_url))
[email protected]ac025282009-12-16 19:16:383772 window()->ShowThemeInstallBubble();
[email protected]91e1bd82009-09-03 22:04:403773 break;
3774 }
3775
[email protected]432115822011-07-10 15:52:273776 case chrome::NOTIFICATION_PREF_CHANGED: {
[email protected]2a7e7c152010-10-01 20:12:093777 const std::string& pref_name = *Details<std::string>(details).ptr();
3778 if (pref_name == prefs::kUseVerticalTabs) {
[email protected]b3344872010-05-03 15:52:293779 UseVerticalTabsChanged();
[email protected]ac86c982011-05-11 13:26:053780 } else if (pref_name == prefs::kUseCompactNavigationBar) {
3781 UseCompactNavigationBarChanged();
[email protected]2a7e7c152010-10-01 20:12:093782 } else if (pref_name == prefs::kPrintingEnabled) {
[email protected]b9163e02011-04-20 16:03:373783 UpdatePrintingState(GetContentRestrictionsForSelectedTab());
[email protected]3819f2ee2011-08-21 09:44:383784 } else if (pref_name == prefs::kInstantEnabled ||
3785 pref_name == prefs::kMetricsReportingEnabled ||
3786 pref_name == prefs::kSearchSuggestEnabled) {
[email protected]73de26a2010-10-17 03:23:253787 if (!InstantController::IsEnabled(profile())) {
3788 if (instant()) {
3789 instant()->DestroyPreviewContents();
[email protected]5aab5e22010-12-08 22:13:293790 instant_.reset();
3791 instant_unload_handler_.reset();
[email protected]73de26a2010-10-17 03:23:253792 }
3793 } else {
3794 CreateInstantIfNecessary();
3795 }
[email protected]4e94ab32011-08-05 05:28:273796 } else if (pref_name == prefs::kIncognitoModeAvailability) {
3797 IncognitoModePrefs::Availability available =
3798 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
3799 command_updater_.UpdateCommandEnabled(
3800 IDC_NEW_WINDOW,
3801 available != IncognitoModePrefs::FORCED);
[email protected]e1581e32011-06-09 15:18:023802 command_updater_.UpdateCommandEnabled(
3803 IDC_NEW_INCOGNITO_WINDOW,
[email protected]4e94ab32011-08-05 05:28:273804 available != IncognitoModePrefs::DISABLED);
[email protected]543432ee2010-10-22 16:32:133805 } else if (pref_name == prefs::kDevToolsDisabled) {
3806 UpdateCommandsForDevTools();
[email protected]97b46382011-05-02 13:23:043807 if (profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled))
[email protected]543432ee2010-10-22 16:32:133808 g_browser_process->devtools_manager()->CloseAllClientHosts();
[email protected]a13f47d12011-04-14 11:41:583809 } else if (pref_name == prefs::kEditBookmarksEnabled) {
3810 UpdateCommandsForBookmarkEditing();
[email protected]a007e732011-08-05 13:32:193811 } else if (pref_name == prefs::kEnableBookmarkBar) {
3812 UpdateCommandsForBookmarkBar();
[email protected]97b46382011-05-02 13:23:043813 } else if (pref_name == prefs::kAllowFileSelectionDialogs) {
3814 UpdateSaveAsState(GetContentRestrictionsForSelectedTab());
3815 UpdateOpenFileState();
[email protected]2a7e7c152010-10-01 20:12:093816 } else {
[email protected]b9c505b2010-04-30 15:05:103817 NOTREACHED();
[email protected]2a7e7c152010-10-01 20:12:093818 }
[email protected]b9c505b2010-04-30 15:05:103819 break;
3820 }
3821
[email protected]432115822011-07-10 15:52:273822 case chrome::NOTIFICATION_TAB_CONTENT_SETTINGS_CHANGED: {
[email protected]9a9a9e22011-05-13 22:20:353823 TabContents* tab_contents = Source<TabContents>(source).ptr();
3824 if (tab_contents == GetSelectedTabContents()) {
3825 LocationBar* location_bar = window()->GetLocationBar();
3826 if (location_bar)
3827 location_bar->UpdateContentSettingsIcons();
3828 }
3829 break;
3830 }
3831
[email protected]432115822011-07-10 15:52:273832 case content::NOTIFICATION_INTERSTITIAL_ATTACHED:
[email protected]09b29342011-06-24 19:18:483833 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
3834 break;
3835
[email protected]432115822011-07-10 15:52:273836 case chrome::NOTIFICATION_BOOKMARK_BAR_VISIBILITY_PREF_CHANGED:
[email protected]0b4e22322011-08-11 19:50:343837 if (profile_->IsSameProfile(Source<Profile>(source).ptr()))
3838 UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE);
[email protected]93f230e02011-06-01 14:40:003839 break;
3840
[email protected]e83f1682008-09-07 23:57:403841 default:
3842 NOTREACHED() << "Got a notification we didn't register for.";
initial.commit09911bf2008-07-26 23:55:293843 }
3844}
3845
[email protected]d3b98c82010-07-14 07:45:593846///////////////////////////////////////////////////////////////////////////////
3847// Browser, ProfileSyncServiceObserver implementation:
3848
3849void Browser::OnStateChanged() {
3850 DCHECK(profile_->GetProfileSyncService());
3851
3852#if !defined(OS_MACOSX)
[email protected]b35b26b32011-05-05 20:35:143853 const bool show_main_ui = is_type_tabbed() && !window_->IsFullscreen();
[email protected]d3b98c82010-07-14 07:45:593854#else
[email protected]b35b26b32011-05-05 20:35:143855 const bool show_main_ui = is_type_tabbed();
[email protected]d3b98c82010-07-14 07:45:593856#endif
3857
3858 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
[email protected]49385da692011-08-05 04:03:393859 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]d3b98c82010-07-14 07:45:593860}
[email protected]88d74942009-01-21 22:04:443861
[email protected]36b6dcb2008-11-12 01:19:573862///////////////////////////////////////////////////////////////////////////////
[email protected]6b723f82010-10-05 20:14:273863// Browser, InstantDelegate implementation:
[email protected]03bb953d2010-09-14 21:38:303864
[email protected]36d5e5592010-11-15 20:45:593865void Browser::PrepareForInstant() {
3866 window_->PrepareForInstant();
3867}
3868
[email protected]3c9e1872010-11-18 16:17:493869void Browser::ShowInstant(TabContentsWrapper* preview_contents) {
3870 DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
[email protected]e3690ed2011-03-25 20:25:143871 window_->ShowInstant(preview_contents);
[email protected]03bb953d2010-09-14 21:38:303872}
3873
[email protected]6b723f82010-10-05 20:14:273874void Browser::HideInstant() {
[email protected]1946c932010-12-15 00:07:383875 window_->HideInstant(instant_->is_active());
[email protected]03bb953d2010-09-14 21:38:303876}
3877
[email protected]3c9e1872010-11-18 16:17:493878void Browser::CommitInstant(TabContentsWrapper* preview_contents) {
3879 TabContentsWrapper* tab_contents = instant_->tab_contents();
3880 int index =
3881 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
3882 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]03bb953d2010-09-14 21:38:303883 // TabStripModel takes ownership of preview_contents.
[email protected]43032342011-03-21 14:10:313884 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
3885 index, preview_contents);
3886 // InstantUnloadHandler takes ownership of tab_contents.
3887 instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
[email protected]46fd1ea42011-02-16 15:59:333888
3889 GURL url = preview_contents->tab_contents()->GetURL();
[email protected]6e37fe32011-03-02 09:06:523890 DCHECK(profile_->GetExtensionService());
3891 if (profile_->GetExtensionService()->IsInstalledApp(url)) {
[email protected]46fd1ea42011-02-16 15:59:333892 UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
3893 extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
3894 extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
3895 }
[email protected]03bb953d2010-09-14 21:38:303896}
3897
[email protected]c98fd5d82011-05-04 15:20:093898void Browser::SwapTabContents(TabContentsWrapper* old_tab_contents,
3899 TabContentsWrapper* new_tab_contents) {
3900 int index =
3901 tab_handler_->GetTabStripModel()->GetIndexOfTabContents(old_tab_contents);
[email protected]71b5d242011-04-30 02:27:203902 DCHECK_NE(TabStripModel::kNoTab, index);
[email protected]c98fd5d82011-05-04 15:20:093903 tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(index,
3904 new_tab_contents);
[email protected]71b5d242011-04-30 02:27:203905}
3906
[email protected]33b8b8e2011-03-15 14:51:553907void Browser::SetSuggestedText(const string16& text,
3908 InstantCompleteBehavior behavior) {
[email protected]ce696a452011-05-31 17:47:363909 if (window()->GetLocationBar())
3910 window()->GetLocationBar()->SetSuggestedText(text, behavior);
[email protected]03bb953d2010-09-14 21:38:303911}
3912
[email protected]6b723f82010-10-05 20:14:273913gfx::Rect Browser::GetInstantBounds() {
3914 return window()->GetInstantBounds();
[email protected]46fe8e92010-09-22 03:32:473915}
3916
[email protected]03bb953d2010-09-14 21:38:303917///////////////////////////////////////////////////////////////////////////////
[email protected]9800de5e2011-03-11 18:19:493918// Browser, protected:
3919
3920BrowserWindow* Browser::CreateBrowserWindow() {
[email protected]b35b26b32011-05-05 20:35:143921 if (type_ == TYPE_PANEL &&
[email protected]011396a2011-04-13 23:35:283922 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels))
3923 return PanelManager::GetInstance()->CreatePanel(this);
3924
[email protected]9800de5e2011-03-11 18:19:493925 return BrowserWindow::CreateBrowserWindow(this);
3926}
3927
3928
3929///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:573930// Browser, Command and state updating (private):
3931
3932void Browser::InitCommandState() {
3933 // All browser commands whose state isn't set automagically some other way
3934 // (like Back & Forward with initial page load) must have their state
3935 // initialized here, otherwise they will be forever disabled.
3936
[email protected]84214982008-12-10 18:49:103937 // Navigation commands
[email protected]1fc025202009-01-20 23:03:143938 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
[email protected]1ccb3568d2010-02-19 10:51:163939 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
[email protected]84214982008-12-10 18:49:103940
3941 // Window management commands
[email protected]4e94ab32011-08-05 05:28:273942 IncognitoModePrefs::Availability incognito_avail =
3943 IncognitoModePrefs::GetAvailability(profile_->GetPrefs());
3944 command_updater_.UpdateCommandEnabled(
3945 IDC_NEW_WINDOW,
3946 incognito_avail != IncognitoModePrefs::FORCED);
[email protected]97b46382011-05-02 13:23:043947 command_updater_.UpdateCommandEnabled(
3948 IDC_NEW_INCOGNITO_WINDOW,
[email protected]4e94ab32011-08-05 05:28:273949 incognito_avail != IncognitoModePrefs::DISABLED);
3950
[email protected]1fc025202009-01-20 23:03:143951 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
3952 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
3953 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
3954 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
[email protected]281918912010-05-27 22:05:133955 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
[email protected]1fc025202009-01-20 23:03:143956 command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
[email protected]c8b59f92010-05-28 21:45:473957 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
[email protected]cdc05ec2011-05-18 15:15:593958 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true);
[email protected]84214982008-12-10 18:49:103959
3960 // Page-related commands
[email protected]89d6e6e2009-12-03 23:06:513961 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
[email protected]1fc025202009-01-20 23:03:143962 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
3963 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
3964 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
3965 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
3966 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
3967 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
3968 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
3969 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
3970 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
3971 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
3972 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
3973 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
3974 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
3975 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
3976 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
3977 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
3978 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
3979 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
3980 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
3981 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
3982 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
3983 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
3984 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
3985 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
3986 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
3987 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
3988 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
3989 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
3990 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
3991 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
3992 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
3993 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
3994 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
3995 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
3996 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
[email protected]e13271f2009-03-07 00:26:003997 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
[email protected]1fc025202009-01-20 23:03:143998 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
3999 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
[email protected]84214982008-12-10 18:49:104000
[email protected]63b02932009-06-05 09:40:514001 // Zoom
4002 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
4003 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
4004 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
4005 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
4006
[email protected]84214982008-12-10 18:49:104007 // Show various bits of UI
[email protected]97b46382011-05-02 13:23:044008 UpdateOpenFileState();
[email protected]1fc025202009-01-20 23:03:144009 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
[email protected]543432ee2010-10-22 16:32:134010 UpdateCommandsForDevTools();
[email protected]1fc025202009-01-20 23:03:144011 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
[email protected]1fc025202009-01-20 23:03:144012 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
[email protected]4a4180a52010-08-23 06:39:484013 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER,
4014 browser_defaults::bookmarks_enabled);
[email protected]1fc025202009-01-20 23:03:144015 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
4016 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
[email protected]4aee5652009-11-19 18:59:214017 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true);
[email protected]d6852fd2011-05-20 17:19:124018 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, true);
[email protected]9cd51a02009-10-23 22:30:294019
[email protected]96e34672010-02-09 21:40:294020#if defined(OS_CHROMEOS)
[email protected]ec2fd5a2011-04-30 06:16:054021 command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
[email protected]f97d7f632010-06-01 21:08:334022 command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
[email protected]d14af522010-12-02 03:54:504023 command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
[email protected]c8b59f92010-05-28 21:45:474024 command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
4025 command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
[email protected]96e34672010-02-09 21:40:294026#endif
[email protected]a038159b2011-08-18 02:55:364027 command_updater_.UpdateCommandEnabled(
4028 IDC_SHOW_SYNC_SETUP, profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]c8b59f92010-05-28 21:45:474029
[email protected]14908b72011-04-20 06:54:364030 ExtensionService* extension_service = profile()->GetExtensionService();
[email protected]9cd51a02009-10-23 22:30:294031 bool enable_extensions =
[email protected]14908b72011-04-20 06:54:364032 extension_service && extension_service->extensions_enabled();
[email protected]9cd51a02009-10-23 22:30:294033 command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
4034 enable_extensions);
4035
[email protected]64ff7942008-12-17 18:11:234036 // Initialize other commands based on the window type.
[email protected]b35b26b32011-05-05 20:35:144037 bool normal_window = is_type_tabbed();
[email protected]64ff7942008-12-17 18:11:234038
[email protected]11f4857282009-11-13 19:56:174039 // Navigation commands
4040 command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
[email protected]64ff7942008-12-17 18:11:234041
[email protected]11f4857282009-11-13 19:56:174042 // Window management commands
[email protected]d3766932011-08-04 22:18:234043 // TODO(rohitrao): Disable fullscreen on non-Lion?
[email protected]cf299bc2010-08-12 20:27:094044 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
[email protected]b35b26b32011-05-05 20:35:144045 !(is_type_panel() && is_app()));
[email protected]11f4857282009-11-13 19:56:174046 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
4047 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
4048 normal_window);
4049 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
4050 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
4051 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
4052 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
4053 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
4054 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
4055 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
4056 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
4057 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
4058 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
4059 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
[email protected]c1d0d812010-07-27 20:21:554060#if defined(OS_MACOSX)
4061 command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
[email protected]d3766932011-08-04 22:18:234062 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE,
4063 !(is_type_panel() && is_app()));
[email protected]c1d0d812010-07-27 20:21:554064#endif
[email protected]e662ade2009-06-08 18:20:144065
[email protected]fc33e9992010-04-08 19:40:134066 // Clipboard commands
[email protected]b35b26b32011-05-05 20:35:144067 command_updater_.UpdateCommandEnabled(IDC_COPY_URL, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134068
4069 // Find-in-page
[email protected]b35b26b32011-05-05 20:35:144070 command_updater_.UpdateCommandEnabled(IDC_FIND, !is_devtools());
4071 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, !is_devtools());
4072 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, !is_devtools());
[email protected]fc33e9992010-04-08 19:40:134073
[email protected]11f4857282009-11-13 19:56:174074 // Show various bits of UI
[email protected]fc33e9992010-04-08 19:40:134075 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
[email protected]9282cea2009-02-18 18:49:004076
[email protected]c1bbaa82010-11-08 11:17:054077 // The upgrade entry and the view incompatibility entry should always be
4078 // enabled. Whether they are visible is a separate matter determined on menu
4079 // show.
[email protected]b21d6912010-08-31 19:22:414080 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
[email protected]c1bbaa82010-11-08 11:17:054081 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
[email protected]b21d6912010-08-31 19:22:414082
[email protected]b569c112010-11-22 20:53:444083 // View Background Pages entry is always enabled, but is hidden if there are
4084 // no background pages.
4085 command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
4086
[email protected]9282cea2009-02-18 18:49:004087 // Initialize other commands whose state changes based on fullscreen mode.
4088 UpdateCommandsForFullscreenMode(false);
[email protected]9e823662010-10-13 23:36:004089
4090 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584091
4092 UpdateCommandsForBookmarkEditing();
[email protected]36b6dcb2008-11-12 01:19:574093}
4094
[email protected]227393e2011-06-29 21:28:394095void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
4096#if !defined(OS_MACOSX)
4097 const bool show_main_ui = is_type_tabbed() && !is_fullscreen;
4098#else
4099 const bool show_main_ui = is_type_tabbed();
4100#endif
4101
4102 bool main_not_fullscreen = show_main_ui && !is_fullscreen;
4103
4104 // Navigation commands
4105 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
4106
4107 // Window management commands
4108 command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
4109 type_ != TYPE_TABBED && !is_fullscreen);
4110
4111 // Focus various bits of UI
4112 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
4113 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
4114 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
4115 command_updater_.UpdateCommandEnabled(
4116 IDC_FOCUS_MENU_BAR, main_not_fullscreen);
4117 command_updater_.UpdateCommandEnabled(
4118 IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
4119 command_updater_.UpdateCommandEnabled(
4120 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
4121 command_updater_.UpdateCommandEnabled(
4122 IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
4123 command_updater_.UpdateCommandEnabled(
4124 IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
4125
4126 // Show various bits of UI
4127 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
4128 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
[email protected]227393e2011-06-29 21:28:394129 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
4130 command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
[email protected]49385da692011-08-05 04:03:394131 show_main_ui && profile_->GetOriginalProfile()->IsSyncAccessible());
[email protected]227393e2011-06-29 21:28:394132
4133 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
4134 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
4135 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
4136 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
4137 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
4138 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
4139 command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
4140#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
4141 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
4142#endif
[email protected]a007e732011-08-05 13:32:194143
4144 UpdateCommandsForBookmarkBar();
[email protected]227393e2011-06-29 21:28:394145}
4146
[email protected]84214982008-12-10 18:49:104147void Browser::UpdateCommandsForTabState() {
[email protected]c7c42332008-11-15 01:10:544148 TabContents* current_tab = GetSelectedTabContents();
[email protected]a0366a52011-02-04 20:04:214149 TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
4150 if (!current_tab || !current_tab_wrapper) // May be NULL during tab restore.
[email protected]d8375fd2008-11-25 22:45:394151 return;
[email protected]d8375fd2008-11-25 22:45:394152
[email protected]84214982008-12-10 18:49:104153 // Navigation commands
[email protected]ce3fa3c2009-04-20 19:55:574154 NavigationController& nc = current_tab->controller();
4155 command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
4156 command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
[email protected]fc33e9992010-04-08 19:40:134157 command_updater_.UpdateCommandEnabled(IDC_RELOAD,
4158 CanReloadContents(current_tab));
4159 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
4160 CanReloadContents(current_tab));
initial.commit09911bf2008-07-26 23:55:294161
[email protected]84214982008-12-10 18:49:104162 // Window management commands
[email protected]1fc025202009-01-20 23:03:144163 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
[email protected]b35b26b32011-05-05 20:35:144164 !is_app() && CanDuplicateContentsAt(active_index()));
[email protected]84214982008-12-10 18:49:104165
[email protected]57c6a652009-05-04 07:58:344166 // Page-related commands
[email protected]52cc59b2011-05-06 14:42:384167 window_->SetStarredState(
[email protected]35699d572011-05-11 19:46:144168 current_tab_wrapper->bookmark_tab_helper()->is_starred());
[email protected]57c6a652009-05-04 07:58:344169 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
[email protected]31682282010-01-15 18:05:164170 current_tab->controller().CanViewSource());
[email protected]151666e2010-10-21 17:05:254171 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
4172 current_tab->ShouldDisplayURL() && current_tab->GetURL().is_valid());
[email protected]af664c72011-05-17 14:33:404173 if (is_devtools())
4174 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
[email protected]151666e2010-10-21 17:05:254175
4176 // Changing the encoding is not possible on Chrome-internal webpages.
[email protected]50dc3deb2011-07-07 01:07:194177 bool is_chrome_internal = HasInternalURL(nc.GetActiveEntry());
[email protected]c0f82ec52010-07-27 14:22:144178 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
4179 !is_chrome_internal && SavePackage::IsSavableContents(
4180 current_tab->contents_mime_type()));
4181
[email protected]57c6a652009-05-04 07:58:344182 // Show various bits of UI
[email protected]c065fa072010-01-20 23:12:254183 // TODO(pinkerton): Disable app-mode in the model until we implement it
4184 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4185#if !defined(OS_MACOSX)
[email protected]57c6a652009-05-04 07:58:344186 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234187 web_app::IsValidUrl(current_tab->GetURL()));
[email protected]c065fa072010-01-20 23:12:254188#endif
[email protected]9e823662010-10-13 23:36:004189
4190 UpdateCommandsForContentRestrictionState();
[email protected]a13f47d12011-04-14 11:41:584191 UpdateCommandsForBookmarkEditing();
[email protected]9e823662010-10-13 23:36:004192}
4193
4194void Browser::UpdateCommandsForContentRestrictionState() {
[email protected]b9163e02011-04-20 16:03:374195 int restrictions = GetContentRestrictionsForSelectedTab();
[email protected]9e823662010-10-13 23:36:004196
4197 command_updater_.UpdateCommandEnabled(
4198 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
4199 command_updater_.UpdateCommandEnabled(
4200 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
4201 command_updater_.UpdateCommandEnabled(
4202 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
[email protected]97b46382011-05-02 13:23:044203 UpdateSaveAsState(restrictions);
[email protected]9e823662010-10-13 23:36:004204 UpdatePrintingState(restrictions);
4205}
4206
4207void Browser::UpdatePrintingState(int content_restrictions) {
4208 bool enabled = true;
4209 if (content_restrictions & CONTENT_RESTRICTION_PRINT) {
4210 enabled = false;
4211 } else if (g_browser_process->local_state()) {
[email protected]97b46382011-05-02 13:23:044212 enabled = g_browser_process->local_state()->
4213 GetBoolean(prefs::kPrintingEnabled);
[email protected]9e823662010-10-13 23:36:004214 }
4215 command_updater_.UpdateCommandEnabled(IDC_PRINT, enabled);
initial.commit09911bf2008-07-26 23:55:294216}
4217
[email protected]943d8122010-06-11 02:13:454218void Browser::UpdateReloadStopState(bool is_loading, bool force) {
4219 window_->UpdateReloadStopState(is_loading, force);
[email protected]1fc025202009-01-20 23:03:144220 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
[email protected]64ff7942008-12-17 18:11:234221}
4222
[email protected]543432ee2010-10-22 16:32:134223void Browser::UpdateCommandsForDevTools() {
[email protected]97b46382011-05-02 13:23:044224 bool dev_tools_enabled =
[email protected]5073f492011-05-03 09:36:424225 !profile_->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled);
[email protected]543432ee2010-10-22 16:32:134226 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
4227 dev_tools_enabled);
4228 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
4229 dev_tools_enabled);
4230 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
4231 dev_tools_enabled);
4232}
4233
[email protected]a13f47d12011-04-14 11:41:584234void Browser::UpdateCommandsForBookmarkEditing() {
[email protected]97b46382011-05-02 13:23:044235 bool enabled =
4236 profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled) &&
4237 browser_defaults::bookmarks_enabled;
[email protected]a13f47d12011-04-14 11:41:584238
4239 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
[email protected]b35b26b32011-05-05 20:35:144240 enabled && is_type_tabbed());
[email protected]a13f47d12011-04-14 11:41:584241 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
4242 enabled && CanBookmarkAllTabs());
4243}
4244
[email protected]a007e732011-08-05 13:32:194245void Browser::UpdateCommandsForBookmarkBar() {
4246#if !defined(OS_MACOSX)
4247 const bool show_main_ui = is_type_tabbed() &&
4248 (!window_ || !window_->IsFullscreen());
4249#else
4250 const bool show_main_ui = is_type_tabbed();
4251#endif
4252 command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
4253 browser_defaults::bookmarks_enabled &&
4254 !profile_->GetPrefs()->IsManagedPreference(prefs::kEnableBookmarkBar) &&
4255 show_main_ui);
4256}
4257
[email protected]97b46382011-05-02 13:23:044258void Browser::UpdateSaveAsState(int content_restrictions) {
4259 bool enabled = !(content_restrictions & CONTENT_RESTRICTION_SAVE);
4260 PrefService* state = g_browser_process->local_state();
4261 if (state)
4262 enabled = enabled && state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4263
4264 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, enabled);
4265}
4266
4267void Browser::UpdateOpenFileState() {
4268 bool enabled = true;
4269 PrefService* local_state = g_browser_process->local_state();
4270 if (local_state)
4271 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
4272
4273 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
4274}
4275
[email protected]36b6dcb2008-11-12 01:19:574276///////////////////////////////////////////////////////////////////////////////
4277// Browser, UI update coalescing and handling (private):
4278
4279void Browser::UpdateToolbar(bool should_restore_state) {
[email protected]3c9e1872010-11-18 16:17:494280 window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
initial.commit09911bf2008-07-26 23:55:294281}
4282
[email protected]36b6dcb2008-11-12 01:19:574283void Browser::ScheduleUIUpdate(const TabContents* source,
4284 unsigned changed_flags) {
[email protected]a5231662009-09-26 00:56:004285 if (!source)
4286 return;
4287
[email protected]2b4355c2009-04-04 17:55:464288 // Do some synchronous updates.
[email protected]36b6dcb2008-11-12 01:19:574289 if (changed_flags & TabContents::INVALIDATE_URL &&
4290 source == GetSelectedTabContents()) {
4291 // Only update the URL for the current tab. Note that we do not update
4292 // the navigation commands since those would have already been updated
4293 // synchronously by NavigationStateChanged.
4294 UpdateToolbar(false);
[email protected]8030f012009-09-25 18:09:374295 changed_flags &= ~TabContents::INVALIDATE_URL;
[email protected]36b6dcb2008-11-12 01:19:574296 }
[email protected]a5231662009-09-26 00:56:004297 if (changed_flags & TabContents::INVALIDATE_LOAD) {
[email protected]6ebdc9b2010-09-27 16:55:574298 // Update the loading state synchronously. This is so the throbber will
4299 // immediately start/stop, which gives a more snappy feel. We want to do
[email protected]a5231662009-09-26 00:56:004300 // this for any tab so they start & stop quickly.
[email protected]ecc523f62010-09-28 22:45:404301 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4302 tab_handler_->GetTabStripModel()->GetIndexOfController(
4303 &source->controller()),
[email protected]6ebdc9b2010-09-27 16:55:574304 TabStripModelObserver::LOADING_ONLY);
4305 // The status bubble needs to be updated during INVALIDATE_LOAD too, but
4306 // we do that asynchronously by not stripping INVALIDATE_LOAD from
4307 // changed_flags.
[email protected]8030f012009-09-25 18:09:374308 }
4309
[email protected]f5d978c2011-07-21 14:43:514310 if (changed_flags & TabContents::INVALIDATE_TITLE && !source->IsLoading()) {
[email protected]f1cd5e82009-10-23 17:19:034311 // To correctly calculate whether the title changed while not loading
4312 // we need to process the update synchronously. This state only matters for
4313 // the TabStripModel, so we notify the TabStripModel now and notify others
4314 // asynchronously.
[email protected]ecc523f62010-09-28 22:45:404315 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
4316 tab_handler_->GetTabStripModel()->GetIndexOfController(
4317 &source->controller()),
[email protected]f1cd5e82009-10-23 17:19:034318 TabStripModelObserver::TITLE_NOT_LOADING);
4319 }
4320
[email protected]2b4355c2009-04-04 17:55:464321 // If the only updates were synchronously handled above, we're done.
[email protected]8030f012009-09-25 18:09:374322 if (changed_flags == 0)
[email protected]2b4355c2009-04-04 17:55:464323 return;
[email protected]36b6dcb2008-11-12 01:19:574324
4325 // Save the dirty bits.
[email protected]85354982009-09-25 19:58:404326 scheduled_updates_[source] |= changed_flags;
[email protected]36b6dcb2008-11-12 01:19:574327
4328 if (chrome_updater_factory_.empty()) {
4329 // No task currently scheduled, start another.
[email protected]0586b0e2010-02-12 21:38:374330 MessageLoop::current()->PostDelayedTask(
4331 FROM_HERE,
[email protected]36b6dcb2008-11-12 01:19:574332 chrome_updater_factory_.NewRunnableMethod(
4333 &Browser::ProcessPendingUIUpdates),
[email protected]6ebdc9b2010-09-27 16:55:574334 kUIUpdateCoalescingTimeMS);
[email protected]36b6dcb2008-11-12 01:19:574335 }
4336}
4337
4338void Browser::ProcessPendingUIUpdates() {
4339#ifndef NDEBUG
4340 // Validate that all tabs we have pending updates for exist. This is scary
4341 // because the pending list must be kept in sync with any detached or
[email protected]a5231662009-09-26 00:56:004342 // deleted tabs.
[email protected]85354982009-09-25 19:58:404343 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4344 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574345 bool found = false;
4346 for (int tab = 0; tab < tab_count(); tab++) {
[email protected]a5231662009-09-26 00:56:004347 if (GetTabContentsAt(tab) == i->first) {
[email protected]36b6dcb2008-11-12 01:19:574348 found = true;
4349 break;
4350 }
4351 }
4352 DCHECK(found);
4353 }
4354#endif
4355
4356 chrome_updater_factory_.RevokeAll();
4357
[email protected]85354982009-09-25 19:58:404358 for (UpdateMap::const_iterator i = scheduled_updates_.begin();
4359 i != scheduled_updates_.end(); ++i) {
[email protected]36b6dcb2008-11-12 01:19:574360 // Do not dereference |contents|, it may be out-of-date!
[email protected]85354982009-09-25 19:58:404361 const TabContents* contents = i->first;
4362 unsigned flags = i->second;
[email protected]36b6dcb2008-11-12 01:19:574363
[email protected]a5231662009-09-26 00:56:004364 if (contents == GetSelectedTabContents()) {
4365 // Updates that only matter when the tab is selected go here.
[email protected]f7f3a5f2009-05-01 22:02:344366
[email protected]9800de5e2011-03-11 18:19:494367 if (flags & TabContents::INVALIDATE_PAGE_ACTIONS) {
4368 LocationBar* location_bar = window()->GetLocationBar();
4369 if (location_bar)
4370 location_bar->UpdatePageActions();
4371 }
[email protected]6ebdc9b2010-09-27 16:55:574372 // Updating the URL happens synchronously in ScheduleUIUpdate.
[email protected]0dd3a0ab2011-02-18 08:17:444373 if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) {
4374 GetStatusBubble()->SetStatus(
4375 GetSelectedTabContentsWrapper()->GetStatusText());
4376 }
[email protected]a5231662009-09-26 00:56:004377
[email protected]f1cd5e82009-10-23 17:19:034378 if (flags & (TabContents::INVALIDATE_TAB |
4379 TabContents::INVALIDATE_TITLE)) {
[email protected]c065fa072010-01-20 23:12:254380// TODO(pinkerton): Disable app-mode in the model until we implement it
4381// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
4382#if !defined(OS_MACOSX)
[email protected]a5231662009-09-26 00:56:004383 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
[email protected]12ea22a2009-11-19 07:17:234384 web_app::IsValidUrl(contents->GetURL()));
[email protected]c065fa072010-01-20 23:12:254385#endif
[email protected]a5231662009-09-26 00:56:004386 window_->UpdateTitleBar();
4387 }
[email protected]4d34e2e2009-05-26 22:55:284388 }
[email protected]36b6dcb2008-11-12 01:19:574389
[email protected]a5231662009-09-26 00:56:004390 // Updates that don't depend upon the selected state go here.
[email protected]f1cd5e82009-10-23 17:19:034391 if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
[email protected]ecc523f62010-09-28 22:45:404392 tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
[email protected]3c9e1872010-11-18 16:17:494393 tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
[email protected]f1cd5e82009-10-23 17:19:034394 TabStripModelObserver::ALL);
[email protected]36b6dcb2008-11-12 01:19:574395 }
4396
4397 // We don't need to process INVALIDATE_STATE, since that's not visible.
4398 }
4399
4400 scheduled_updates_.clear();
4401}
4402
4403void Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
4404 if (!contents)
4405 return;
4406
[email protected]85354982009-09-25 19:58:404407 UpdateMap::iterator i = scheduled_updates_.find(contents);
4408 if (i != scheduled_updates_.end())
4409 scheduled_updates_.erase(i);
initial.commit09911bf2008-07-26 23:55:294410}
4411
[email protected]d938aed92009-01-22 19:49:334412
[email protected]36b6dcb2008-11-12 01:19:574413///////////////////////////////////////////////////////////////////////////////
4414// Browser, Getters for UI (private):
initial.commit09911bf2008-07-26 23:55:294415
[email protected]36b6dcb2008-11-12 01:19:574416StatusBubble* Browser::GetStatusBubble() {
[email protected]34930432009-11-09 00:12:094417#if !defined(OS_MACOSX)
4418 // In kiosk mode, we want to always hide the status bubble.
4419 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4420 return NULL;
4421#endif
[email protected]9b032bf2009-07-21 17:34:234422 return window_ ? window_->GetStatusBubble() : NULL;
initial.commit09911bf2008-07-26 23:55:294423}
4424
[email protected]36b6dcb2008-11-12 01:19:574425///////////////////////////////////////////////////////////////////////////////
4426// Browser, Session restore functions (private):
initial.commit09911bf2008-07-26 23:55:294427
4428void Browser::SyncHistoryWithTabs(int index) {
[email protected]92371eb2011-04-28 11:50:154429 SessionService* session_service =
4430 SessionServiceFactory::GetForProfileIfExisting(profile());
initial.commit09911bf2008-07-26 23:55:294431 if (session_service) {
4432 for (int i = index; i < tab_count(); ++i) {
[email protected]81898992011-06-14 22:15:004433 TabContentsWrapper* tab = GetTabContentsWrapperAt(i);
4434 if (tab) {
initial.commit09911bf2008-07-26 23:55:294435 session_service->SetTabIndexInWindow(
[email protected]81898992011-06-14 22:15:004436 session_id(), tab->restore_tab_helper()->session_id(), i);
[email protected]ecc523f62010-09-28 22:45:404437 session_service->SetPinnedState(
4438 session_id(),
[email protected]81898992011-06-14 22:15:004439 tab->restore_tab_helper()->session_id(),
[email protected]ecc523f62010-09-28 22:45:404440 tab_handler_->GetTabStripModel()->IsTabPinned(i));
initial.commit09911bf2008-07-26 23:55:294441 }
4442 }
4443 }
4444}
4445
[email protected]36b6dcb2008-11-12 01:19:574446///////////////////////////////////////////////////////////////////////////////
4447// Browser, OnBeforeUnload handling (private):
initial.commit09911bf2008-07-26 23:55:294448
[email protected]04b4a6c2008-08-02 00:44:474449void Browser::ProcessPendingTabs() {
[email protected]08f0d612011-01-13 23:58:214450 if (!is_attempting_to_close_browser_) {
4451 // Because we might invoke this after a delay it's possible for the value of
4452 // is_attempting_to_close_browser_ to have changed since we scheduled the
4453 // task.
4454 return;
4455 }
initial.commit09911bf2008-07-26 23:55:294456
[email protected]04b4a6c2008-08-02 00:44:474457 if (HasCompletedUnloadProcessing()) {
4458 // We've finished all the unload events and can proceed to close the
4459 // browser.
4460 OnWindowClosing();
initial.commit09911bf2008-07-26 23:55:294461 return;
4462 }
4463
[email protected]04b4a6c2008-08-02 00:44:474464 // Process beforeunload tabs first. When that queue is empty, process
4465 // unload tabs.
[email protected]04b4a6c2008-08-02 00:44:474466 if (!tabs_needing_before_unload_fired_.empty()) {
[email protected]06b42f032008-12-03 18:43:054467 TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244468 // Null check render_view_host here as this gets called on a PostTask and
4469 // the tab's render_view_host may have been nulled out.
4470 if (tab->render_view_host()) {
[email protected]ae23c272009-07-27 20:15:404471 tab->render_view_host()->FirePageBeforeUnload(false);
[email protected]22484622009-06-10 21:17:244472 } else {
[email protected]08f0d612011-01-13 23:58:214473 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244474 }
[email protected]04b4a6c2008-08-02 00:44:474475 } else if (!tabs_needing_unload_fired_.empty()) {
initial.commit09911bf2008-07-26 23:55:294476 // We've finished firing all beforeunload events and can proceed with unload
4477 // events.
4478 // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4479 // somewhere around here so that we have accurate measurements of shutdown
4480 // time.
[email protected]04b4a6c2008-08-02 00:44:474481 // TODO(ojan): We can probably fire all the unload events in parallel and
4482 // get a perf benefit from that in the cases where the tab hangs in it's
4483 // unload handler or takes a long time to page in.
[email protected]06b42f032008-12-03 18:43:054484 TabContents* tab = *(tabs_needing_unload_fired_.begin());
[email protected]22484622009-06-10 21:17:244485 // Null check render_view_host here as this gets called on a PostTask and
4486 // the tab's render_view_host may have been nulled out.
4487 if (tab->render_view_host()) {
[email protected]992db4c2011-05-12 15:37:154488 tab->render_view_host()->ClosePage();
[email protected]22484622009-06-10 21:17:244489 } else {
[email protected]08f0d612011-01-13 23:58:214490 ClearUnloadState(tab, true);
[email protected]22484622009-06-10 21:17:244491 }
initial.commit09911bf2008-07-26 23:55:294492 } else {
[email protected]04b4a6c2008-08-02 00:44:474493 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:294494 }
4495}
4496
[email protected]d043c2cc2009-03-25 18:30:454497bool Browser::HasCompletedUnloadProcessing() const {
[email protected]04b4a6c2008-08-02 00:44:474498 return is_attempting_to_close_browser_ &&
4499 tabs_needing_before_unload_fired_.empty() &&
4500 tabs_needing_unload_fired_.empty();
4501}
4502
4503void Browser::CancelWindowClose() {
[email protected]0b4d3382010-07-14 16:13:044504 // Closing of window can be canceled from:
4505 // - canceling beforeunload
4506 // - disallowing closing from IsClosingPermitted.
[email protected]04b4a6c2008-08-02 00:44:474507 DCHECK(is_attempting_to_close_browser_);
[email protected]8f673f3a2008-08-05 22:34:284508 tabs_needing_before_unload_fired_.clear();
4509 tabs_needing_unload_fired_.clear();
[email protected]04b4a6c2008-08-02 00:44:474510 is_attempting_to_close_browser_ = false;
[email protected]0b4d3382010-07-14 16:13:044511
4512 // Inform TabCloseableStateWatcher that closing of window has been canceled.
4513 TabCloseableStateWatcher* watcher =
4514 g_browser_process->tab_closeable_state_watcher();
4515 if (watcher)
4516 watcher->OnWindowCloseCanceled(this);
[email protected]04b4a6c2008-08-02 00:44:474517}
4518
[email protected]06b42f032008-12-03 18:43:054519bool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
[email protected]04b4a6c2008-08-02 00:44:474520 DCHECK(is_attempting_to_close_browser_);
4521
[email protected]06b42f032008-12-03 18:43:054522 UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4523 if (iter != set->end()) {
4524 set->erase(iter);
4525 return true;
[email protected]04b4a6c2008-08-02 00:44:474526 }
4527 return false;
4528}
initial.commit09911bf2008-07-26 23:55:294529
[email protected]08f0d612011-01-13 23:58:214530void Browser::ClearUnloadState(TabContents* tab, bool process_now) {
[email protected]0b4d3382010-07-14 16:13:044531 // Closing of browser could be canceled (via IsClosingPermitted) between the
4532 // time when request was initiated and when this method is called, so check
4533 // for is_attempting_to_close_browser_ flag before proceeding.
4534 if (is_attempting_to_close_browser_) {
4535 RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4536 RemoveFromSet(&tabs_needing_unload_fired_, tab);
[email protected]08f0d612011-01-13 23:58:214537 if (process_now) {
4538 ProcessPendingTabs();
4539 } else {
4540 MessageLoop::current()->PostTask(
4541 FROM_HERE,
4542 method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
4543 }
[email protected]0b4d3382010-07-14 16:13:044544 }
initial.commit09911bf2008-07-26 23:55:294545}
4546
[email protected]36b6dcb2008-11-12 01:19:574547///////////////////////////////////////////////////////////////////////////////
[email protected]69444cc2009-04-09 20:40:064548// Browser, In-progress download termination handling (private):
4549
[email protected]460a2942010-12-15 19:43:154550void Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present,
4551 bool* incognito_downloads_are_present) {
4552 *normal_downloads_are_present = false;
4553 *incognito_downloads_are_present = false;
4554
4555 // If there are no download in-progress, our job is done.
4556 DownloadManager* download_manager = NULL;
[email protected]803e4c82011-06-21 21:04:284557 // But first we need to check for the existence of the download manager, as
[email protected]460a2942010-12-15 19:43:154558 // GetDownloadManager() will unnecessarily try to create one if it does not
4559 // exist.
4560 if (profile()->HasCreatedDownloadManager())
4561 download_manager = profile()->GetDownloadManager();
4562 if (profile()->IsOffTheRecord()) {
4563 // Browser is incognito and so download_manager if present is for incognito
4564 // downloads.
4565 *incognito_downloads_are_present =
4566 (download_manager && download_manager->in_progress_count() != 0);
4567 // Check original profile.
4568 if (profile()->GetOriginalProfile()->HasCreatedDownloadManager())
4569 download_manager = profile()->GetOriginalProfile()->GetDownloadManager();
4570 }
4571
4572 *normal_downloads_are_present =
4573 (download_manager && download_manager->in_progress_count() != 0);
4574}
4575
[email protected]69444cc2009-04-09 20:40:064576bool Browser::CanCloseWithInProgressDownloads() {
4577 if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
[email protected]7a22201c2009-10-16 16:50:374578 if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
4579 // We need to hear from the user before we can close.
4580 return false;
4581 }
4582 // RESPONSE_RECEIVED case, the user decided to go along with the closing.
[email protected]69444cc2009-04-09 20:40:064583 return true;
4584 }
[email protected]446295a2010-04-19 23:43:004585 // Indicated that normal (non-incognito) downloads are pending.
4586 bool normal_downloads_are_present = false;
4587 bool incognito_downloads_are_present = false;
[email protected]460a2942010-12-15 19:43:154588 CheckDownloadsInProgress(&normal_downloads_are_present,
[email protected]803e4c82011-06-21 21:04:284589 &incognito_downloads_are_present);
[email protected]446295a2010-04-19 23:43:004590 if (!normal_downloads_are_present && !incognito_downloads_are_present)
4591 return true;
4592
4593 if (is_attempting_to_close_browser_)
4594 return true;
4595
4596 if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
4597 (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
[email protected]69444cc2009-04-09 20:40:064598 return true;
4599
4600 // Let's figure out if we are the last window for our profile.
4601 // Note that we cannot just use BrowserList::GetBrowserCount as browser
4602 // windows closing is delayed and the returned count might include windows
4603 // that are being closed.
[email protected]446295a2010-04-19 23:43:004604 // The browser allowed to be closed only if:
4605 // 1. It is a regular browser and there are no regular downloads present or
4606 // this is not the last regular browser window.
4607 // 2. It is an incognito browser and there are no incognito downloads present
4608 // or this is not the last incognito browser window.
[email protected]69444cc2009-04-09 20:40:064609 int count = 0;
4610 for (BrowserList::const_iterator iter = BrowserList::begin();
4611 iter != BrowserList::end(); ++iter) {
4612 // Don't count this browser window or any other in the process of closing.
[email protected]b35b26b32011-05-05 20:35:144613 // Only consider tabbed browser windows, not popups.
[email protected]460a2942010-12-15 19:43:154614 Browser* const browser = *iter;
4615 if (browser == this
4616 || browser->is_attempting_to_close_browser_
[email protected]b35b26b32011-05-05 20:35:144617 || !browser->is_type_tabbed())
[email protected]69444cc2009-04-09 20:40:064618 continue;
4619
[email protected]446295a2010-04-19 23:43:004620 // Verify that this is not the last non-incognito or incognito browser,
4621 // depending on the pending downloads.
4622 if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154623 browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004624 continue;
4625 if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
[email protected]460a2942010-12-15 19:43:154626 !browser->profile()->IsOffTheRecord())
[email protected]446295a2010-04-19 23:43:004627 continue;
4628
[email protected]69444cc2009-04-09 20:40:064629 // We test the original profile, because an incognito browser window keeps
4630 // the original profile alive (and its DownloadManager).
4631 // We also need to test explicitly the profile directly so that 2 incognito
4632 // profiles count as a match.
4633 if ((*iter)->profile() == profile() ||
4634 (*iter)->profile()->GetOriginalProfile() == profile())
4635 count++;
4636 }
4637 if (count > 0)
4638 return true;
4639
4640 cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4641 window_->ConfirmBrowserCloseWithPendingDownloads();
4642
4643 // Return false so the browser does not close. We'll close if the user
4644 // confirms in the dialog.
4645 return false;
4646}
4647
4648///////////////////////////////////////////////////////////////////////////////
[email protected]36b6dcb2008-11-12 01:19:574649// Browser, Assorted utility functions (private):
initial.commit09911bf2008-07-26 23:55:294650
[email protected]1a6b30a2009-08-19 03:52:114651// static
[email protected]de4e7632010-09-01 06:24:044652Browser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
[email protected]b35b26b32011-05-05 20:35:144653 return BrowserList::FindTabbedBrowser(profile, match_incognito);
[email protected]de4e7632010-09-01 06:24:044654}
4655
4656// static
[email protected]1a6b30a2009-08-19 03:52:114657Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
[email protected]de4e7632010-09-01 06:24:044658 Browser* browser = GetTabbedBrowser(profile, false);
[email protected]15952e462008-11-14 00:29:054659 if (!browser)
[email protected]1a6b30a2009-08-19 03:52:114660 browser = Browser::Create(profile);
initial.commit09911bf2008-07-26 23:55:294661 return browser;
4662}
4663
[email protected]9219d262011-02-15 21:05:124664void Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
[email protected]e7cfdbd2011-04-22 14:41:374665 // TabContents...
[email protected]9219d262011-02-15 21:05:124666 tab->tab_contents()->set_delegate(delegate);
4667 tab->set_delegate(delegate);
[email protected]e7cfdbd2011-04-22 14:41:374668
4669 // ...and all the helpers.
4670 tab->blocked_content_tab_helper()->set_delegate(delegate);
[email protected]35699d572011-05-11 19:46:144671 tab->bookmark_tab_helper()->set_delegate(delegate);
[email protected]9219d262011-02-15 21:05:124672 tab->search_engine_tab_helper()->set_delegate(delegate);
4673}
4674
[email protected]4f3dc372009-02-24 00:10:294675void Browser::FindInPage(bool find_next, bool forward_direction) {
[email protected]4801ecc2009-04-05 04:52:584676 ShowFindBar();
[email protected]4f3dc372009-02-24 00:10:294677 if (find_next) {
[email protected]6a4f5af22009-09-23 22:43:004678 string16 find_text;
4679#if defined(OS_MACOSX)
4680 // We always want to search for the contents of the find pasteboard on OS X.
4681 find_text = GetFindPboardText();
4682#endif
[email protected]9c318862011-02-01 22:27:244683 GetSelectedTabContentsWrapper()->
[email protected]c90c6ca2011-02-16 20:11:384684 find_tab_helper()->StartFinding(find_text,
4685 forward_direction,
4686 false); // Not case sensitive.
[email protected]4f3dc372009-02-24 00:10:294687 }
[email protected]fbd77592008-11-12 20:50:274688}
[email protected]cb17f7f2009-02-06 18:14:484689
[email protected]36b6dcb2008-11-12 01:19:574690void Browser::CloseFrame() {
4691 window_->Close();
initial.commit09911bf2008-07-26 23:55:294692}
4693
[email protected]3c9e1872010-11-18 16:17:494694void Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
[email protected]c37e3b62010-01-22 00:15:174695 DetachType type) {
4696 if (type == DETACH_TYPE_DETACH) {
[email protected]56580852010-11-17 16:09:154697 // Save the current location bar state, but only if the tab being detached
4698 // is the selected tab. Because saving state can conditionally revert the
4699 // location bar, saving the current tab's location bar state to a
4700 // non-selected tab can corrupt both tabs.
[email protected]9800de5e2011-03-11 18:19:494701 if (contents == GetSelectedTabContentsWrapper()) {
4702 LocationBar* location_bar = window()->GetLocationBar();
4703 if (location_bar)
4704 location_bar->SaveStateToContents(contents->tab_contents());
4705 }
[email protected]c37e3b62010-01-22 00:15:174706
[email protected]ecc523f62010-09-28 22:45:404707 if (!tab_handler_->GetTabStripModel()->closing_all())
[email protected]c37e3b62010-01-22 00:15:174708 SyncHistoryWithTabs(0);
4709 }
4710
[email protected]9219d262011-02-15 21:05:124711 SetAsDelegate(contents, NULL);
[email protected]3c9e1872010-11-18 16:17:494712 RemoveScheduledUpdatesFor(contents->tab_contents());
[email protected]c37e3b62010-01-22 00:15:174713
[email protected]ecc523f62010-09-28 22:45:404714 if (find_bar_controller_.get() &&
[email protected]1ea49d52011-04-12 17:44:444715 index == tab_handler_->GetTabStripModel()->active_index()) {
[email protected]c37e3b62010-01-22 00:15:174716 find_bar_controller_->ChangeTabContents(NULL);
[email protected]ecc523f62010-09-28 22:45:404717 }
[email protected]c37e3b62010-01-22 00:15:174718
[email protected]08f0d612011-01-13 23:58:214719 if (is_attempting_to_close_browser_) {
4720 // If this is the last tab with unload handlers, then ProcessPendingTabs
4721 // would call back into the TabStripModel (which is invoking this method on
4722 // us). Avoid that by passing in false so that the call to
4723 // ProcessPendingTabs is delayed.
4724 ClearUnloadState(contents->tab_contents(), false);
4725 }
4726
[email protected]432115822011-07-10 15:52:274727 registrar_.Remove(this, content::NOTIFICATION_INTERSTITIAL_ATTACHED,
[email protected]93f230e02011-06-01 14:40:004728 Source<TabContents>(contents->tab_contents()));
[email protected]432115822011-07-10 15:52:274729 registrar_.Remove(this, content::NOTIFICATION_TAB_CONTENTS_DISCONNECTED,
[email protected]8d258e192011-05-05 21:21:054730 Source<TabContents>(contents->tab_contents()));
[email protected]c37e3b62010-01-22 00:15:174731}
4732
initial.commit09911bf2008-07-26 23:55:294733// static
[email protected]f87919d72011-02-02 18:46:164734void Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
initial.commit09911bf2008-07-26 23:55:294735 // We need to register the window position pref.
[email protected]57ecc4b2010-08-11 03:02:514736 std::string window_pref(prefs::kBrowserWindowPlacement);
4737 window_pref.append("_");
initial.commit09911bf2008-07-26 23:55:294738 window_pref.append(app_name);
[email protected]b35b26b32011-05-05 20:35:144739 PrefService* prefs = profile->GetPrefs();
[email protected]d36f941b2011-05-09 06:19:164740 if (!prefs->FindPreference(window_pref.c_str())) {
4741 prefs->RegisterDictionaryPref(window_pref.c_str(),
4742 PrefService::UNSYNCABLE_PREF);
4743 }
initial.commit09911bf2008-07-26 23:55:294744}
[email protected]5c238752009-06-13 10:29:074745
[email protected]281918912010-05-27 22:05:134746void Browser::TabRestoreServiceChanged(TabRestoreService* service) {
4747 command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
4748 !service->entries().empty());
4749}
4750
4751void Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
4752 if (!tab_restore_service_)
4753 return;
4754
4755 DCHECK_EQ(tab_restore_service_, service);
4756 tab_restore_service_->RemoveObserver(this);
4757 tab_restore_service_ = NULL;
4758}
[email protected]97b6c4f2010-09-27 19:31:264759
[email protected]3c9e1872010-11-18 16:17:494760// Centralized method for creating a TabContents, configuring and installing
4761// all its supporting objects and observers.
4762TabContentsWrapper* Browser::TabContentsFactory(
4763 Profile* profile,
4764 SiteInstance* site_instance,
4765 int routing_id,
4766 const TabContents* base_tab_contents,
4767 SessionStorageNamespace* session_storage_namespace) {
4768 TabContents* new_contents = new TabContents(profile, site_instance,
4769 routing_id, base_tab_contents,
4770 session_storage_namespace);
4771 TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
4772 return wrapper;
4773}
4774
[email protected]6b723f82010-10-05 20:14:274775bool Browser::OpenInstant(WindowOpenDisposition disposition) {
[email protected]35242602011-01-06 16:38:534776 if (!instant() || !instant()->is_active() || !instant()->IsCurrent() ||
4777 disposition == NEW_BACKGROUND_TAB) {
4778 // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
4779 // attempt to use the instant preview.
[email protected]97b6c4f2010-09-27 19:31:264780 return false;
[email protected]35242602011-01-06 16:38:534781 }
[email protected]97b6c4f2010-09-27 19:31:264782
4783 if (disposition == CURRENT_TAB) {
[email protected]6b723f82010-10-05 20:14:274784 instant()->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER);
[email protected]97b6c4f2010-09-27 19:31:264785 return true;
4786 }
[email protected]35242602011-01-06 16:38:534787 if (disposition == NEW_FOREGROUND_TAB) {
[email protected]3c9e1872010-11-18 16:17:494788 TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
[email protected]6b723f82010-10-05 20:14:274789 INSTANT_COMMIT_PRESSED_ENTER);
[email protected]a0df03c122011-01-05 00:22:554790 // HideInstant is invoked after release so that InstantController is not
4791 // active when HideInstant asks it for its state.
4792 HideInstant();
[email protected]97b6c4f2010-09-27 19:31:264793 preview_contents->controller().PruneAllButActive();
[email protected]ecc523f62010-09-28 22:45:404794 tab_handler_->GetTabStripModel()->AddTabContents(
[email protected]97b6c4f2010-09-27 19:31:264795 preview_contents,
4796 -1,
[email protected]6b723f82010-10-05 20:14:274797 instant()->last_transition_type(),
[email protected]eaca0ad12011-04-18 15:53:414798 TabStripModel::ADD_ACTIVE);
[email protected]e7cfdbd2011-04-22 14:41:374799 instant()->CompleteRelease(preview_contents);
[email protected]97b6c4f2010-09-27 19:31:264800 return true;
4801 }
4802 // The omnibox currently doesn't use other dispositions, so we don't attempt
4803 // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
4804 // support for the new disposition.
4805 NOTREACHED();
4806 return false;
4807}
[email protected]2031cf9d2010-10-12 05:05:374808
4809void Browser::CreateInstantIfNecessary() {
[email protected]b35b26b32011-05-05 20:35:144810 if (is_type_tabbed() && InstantController::IsEnabled(profile()) &&
[email protected]2031cf9d2010-10-12 05:05:374811 !profile()->IsOffTheRecord()) {
[email protected]fdf773c52010-11-01 20:58:194812 instant_.reset(new InstantController(profile_, this));
[email protected]5aab5e22010-12-08 22:13:294813 instant_unload_handler_.reset(new InstantUnloadHandler(this));
[email protected]2031cf9d2010-10-12 05:05:374814 }
4815}
[email protected]77d8d622010-12-15 10:30:124816
4817void Browser::ViewSource(TabContentsWrapper* contents) {
[email protected]932b7a12011-03-09 12:50:274818 DCHECK(contents);
4819
4820 NavigationEntry* active_entry = contents->controller().GetActiveEntry();
4821 if (!active_entry)
4822 return;
4823
4824 ViewSource(contents, active_entry->url(), active_entry->content_state());
4825}
4826
4827void Browser::ViewSource(TabContentsWrapper* contents,
4828 const GURL& url,
4829 const std::string& content_state) {
[email protected]afd1e522011-04-27 23:29:594830 UserMetrics::RecordAction(UserMetricsAction("ViewSource"));
[email protected]77d8d622010-12-15 10:30:124831 DCHECK(contents);
4832
4833 TabContentsWrapper* view_source_contents = contents->Clone();
4834 view_source_contents->controller().PruneAllButActive();
4835 NavigationEntry* active_entry =
4836 view_source_contents->controller().GetActiveEntry();
[email protected]1788e772010-12-15 16:40:504837 if (!active_entry)
4838 return;
4839
[email protected]932b7a12011-03-09 12:50:274840 GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
4841 url.spec());
4842 active_entry->set_virtual_url(view_source_url);
[email protected]1436beff2010-12-16 19:47:044843
[email protected]932b7a12011-03-09 12:50:274844 // Do not restore scroller position.
4845 active_entry->set_content_state(
4846 webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
4847
[email protected]cd3d50d2010-12-18 21:03:294848 // Do not restore title, derive it from the url.
[email protected]6b2f7a82011-04-25 19:30:514849 active_entry->set_title(string16());
[email protected]77d8d622010-12-15 10:30:124850
[email protected]47b309f2010-12-28 17:35:564851 // Now show view-source entry.
[email protected]77d8d622010-12-15 10:30:124852 if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
4853 // If this is a tabbed browser, just create a duplicate tab inside the same
4854 // window next to the tab being duplicated.
4855 int index = tab_handler_->GetTabStripModel()->
4856 GetIndexOfTabContents(contents);
[email protected]eaca0ad12011-04-18 15:53:414857 int add_types = TabStripModel::ADD_ACTIVE |
[email protected]47b309f2010-12-28 17:35:564858 TabStripModel::ADD_INHERIT_GROUP;
[email protected]77d8d622010-12-15 10:30:124859 tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
[email protected]47b309f2010-12-28 17:35:564860 view_source_contents,
[email protected]77d8d622010-12-15 10:30:124861 add_types);
4862 } else {
[email protected]b35b26b32011-05-05 20:35:144863 Browser* browser = Browser::CreateForType(TYPE_TABBED, profile_);
[email protected]77d8d622010-12-15 10:30:124864
4865 // Preserve the size of the original window. The new window has already
4866 // been given an offset by the OS, so we shouldn't copy the old bounds.
4867 BrowserWindow* new_window = browser->window();
4868 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
4869 window()->GetRestoredBounds().size()));
4870
4871 // We need to show the browser now. Otherwise ContainerWin assumes the
4872 // TabContents is invisible and won't size it.
4873 browser->window()->Show();
4874
4875 // The page transition below is only for the purpose of inserting the tab.
[email protected]47b309f2010-12-28 17:35:564876 browser->AddTab(view_source_contents, PageTransition::LINK);
[email protected]77d8d622010-12-15 10:30:124877 }
4878
[email protected]92371eb2011-04-28 11:50:154879 SessionService* session_service =
4880 SessionServiceFactory::GetForProfileIfExisting(profile_);
4881 if (session_service)
[email protected]81898992011-06-14 22:15:004882 session_service->TabRestored(view_source_contents, false);
[email protected]77d8d622010-12-15 10:30:124883}
[email protected]b9163e02011-04-20 16:03:374884
4885int Browser::GetContentRestrictionsForSelectedTab() {
4886 int content_restrictions = 0;
4887 TabContents* current_tab = GetSelectedTabContents();
4888 if (current_tab) {
4889 content_restrictions = current_tab->content_restrictions();
4890 NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
4891 // See comment in UpdateCommandsForTabState about why we call url().
4892 if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL()))
4893 content_restrictions |= CONTENT_RESTRICTION_SAVE;
4894 }
4895 return content_restrictions;
4896}
[email protected]09b29342011-06-24 19:18:484897
4898void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
4899 BookmarkBar::State state;
[email protected]227393e2011-06-29 21:28:394900 // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
4901 if ((profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
4902 profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)) &&
4903 (!window_ || !window_->IsFullscreen())) {
[email protected]09b29342011-06-24 19:18:484904 state = BookmarkBar::SHOW;
4905 } else {
4906 TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
4907 if (tab && tab->bookmark_tab_helper()->ShouldShowBookmarkBar())
4908 state = BookmarkBar::DETACHED;
4909 else
4910 state = BookmarkBar::HIDDEN;
4911 }
4912 if (state == bookmark_bar_state_)
4913 return;
4914
4915 bookmark_bar_state_ = state;
4916
4917 if (!window_)
4918 return; // This is called from the constructor when window_ is NULL.
4919
4920 if (reason == BOOKMARK_BAR_STATE_CHANGE_TAB_SWITCH) {
4921 // Don't notify BrowserWindow on a tab switch as at the time this is invoked
4922 // BrowserWindow hasn't yet switched tabs. The BrowserWindow implementations
4923 // end up querying state once they process the tab switch.
4924 return;
4925 }
4926
4927 BookmarkBar::AnimateChangeType animate_type =
4928 (reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE) ?
4929 BookmarkBar::ANIMATE_STATE_CHANGE :
4930 BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
4931 window_->BookmarkBarStateChanged(animate_type);
4932}
[email protected]2e2cacc2011-07-12 21:54:264933
4934void Browser::ShowSyncSetup() {
[email protected]e0dc2cb2011-08-04 03:22:574935 ProfileSyncService* service =
4936 profile()->GetOriginalProfile()->GetProfileSyncService();
[email protected]2e2cacc2011-07-12 21:54:264937 if (service->HasSyncSetupCompleted())
4938 ShowOptionsTab(chrome::kSyncSetupSubPage);
4939 else
[email protected]e0dc2cb2011-08-04 03:22:574940 service->ShowLoginDialog();
[email protected]2e2cacc2011-07-12 21:54:264941}