172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <shellapi.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <windows.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // OS_WIN
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base_paths.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
18731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h"
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autofill/autofill_manager.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/background_contents_service.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_shutdown.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_url_handler.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/character_encoding.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_manager.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_toggle_action.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_window.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item_model.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_manager.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_shelf.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_started_animation.h"
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/save_package.h"
43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/extensions/crx_installer.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_browser_event_router.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/extensions/extension_host.h"
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/extensions/extension_prefs.h"
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_tab_helper.h"
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/extensions/extension_tabs_module.h"
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/first_run/first_run.h"
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/google/google_url_tracker.h"
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/google/google_util.h"
54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/instant/instant_controller.h"
55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/instant/instant_unload_handler.h"
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/metrics/user_metrics.h"
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/browser_url_util.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_fixer_upper.h"
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/notifications/notification_ui_manager.h"
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/platform_util.h"
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/printing/print_preview_tab_controller.h"
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sessions/session_service.h"
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sessions/session_types.h"
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/sessions/tab_restore_service.h"
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h"
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sync_ui_util.h"
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_closeable_state_watcher.h"
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/tab_contents/background_contents.h"
72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/tabs/tab_finder.h"
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model.h"
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/download/download_tab_helper.h"
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar.h"
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar_controller.h"
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/find_bar/find_tab_helper.h"
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/omnibox/location_bar.h"
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/options/options_window.h"
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/panels/panel.h"
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/panels/panel_manager.h"
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/status_bubble.h"
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tabs/dock_info.h"
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tabs/tab_menu_model.h"
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/web_applications/web_app_ui.h"
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/webui/active_downloads_ui.h"
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/bug_report_ui.h"
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/options/content_settings_handler.h"
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/window_sizer.h"
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/upgrade_detector.h"
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/web_applications/web_app.h"
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/common/content_restriction.h"
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/common/extensions/extension_constants.h"
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/profiling.h"
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/web_apps.h"
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/host_zoom_map.h"
108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/site_instance.h"
110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/interstitial_page.h"
111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h"
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/page_transition_types.h"
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h"
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_monster.h"
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/registry_controlled_domain.h"
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/static_cookie_policy.h"
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
1253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "ui/base/animation/animation.h"
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/point.h"
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/webkit_glue.h"
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/window_open_disposition.h"
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
1323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "app/win/shell.h"
1334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/shell_integration.h"
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ssl/ssl_error_info.h"
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/task_manager/task_manager.h"
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/view_ids.h"
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // OS_WIN
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/cocoa/find_pasteboard.h"
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/chromeos/boot_times_loader.h"
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/file_manager_util.h"
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch///////////////////////////////////////////////////////////////////////////////
1534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochnamespace {
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The URL to be loaded to display Help.
1574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kHelpContentUrl[] =
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_CHROMEOS)
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  #if defined(OFFICIAL_BUILD)
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html";
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  #else
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      "https://www.google.com/support/chromeos/";
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  #endif
164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#else
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "https://www.google.com/support/chrome/";
166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// The URL to be opened when the Help link on the Autofill dialog is clicked.
1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kAutofillHelpUrl[] =
1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#if defined(OS_CHROMEOS)
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "https://www.google.com/support/chromeos/bin/answer.py?answer=142893";
1724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#else
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "https://www.google.com/support/chrome/bin/answer.py?answer=142893";
1744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif
1754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The URL to be loaded to display the "Report a broken page" form.
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kBrokenPageUrl[] =
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "https://www.google.com/support/chrome/bin/request.py?contact_type="
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "broken_website&format=inproduct&p.page_title=$1&p.page_url=$2";
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// The URL for the privacy dashboard.
1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kPrivacyDashboardUrl[] = "https://www.google.com/dashboard";
183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// How long we wait before updating the browser chrome while loading a page.
1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst int kUIUpdateCoalescingTimeMS = 200;
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kHashMark[] = "#";
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_CHROMEOS)
190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// If a popup window is bigger than this fraction of the screen on chrome os,
191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// turn it into a tab
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst float kPopupMaxWidthFactor = 0.5;
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst float kPopupMaxHeightFactor = 0.6;
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickextern bool g_log_bug53991;
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Constructors, Creation, Showing:
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser::Browser(Type type, Profile* profile)
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : type_(type),
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_(profile),
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window_(NULL),
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ALLOW_THIS_IN_INITIALIZER_LIST(
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          tab_handler_(TabHandler::CreateTabHandler(this))),
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      command_updater_(this),
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      toolbar_model_(this),
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      chrome_updater_factory_(this),
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_attempting_to_close_browser_(false),
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cancel_download_confirmation_state_(NOT_PROMPTED),
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      maximized_state_(MAXIMIZED_STATE_DEFAULT),
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      method_factory_(this),
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      block_command_execution_(false),
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      last_blocked_command_id_(-1),
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      last_blocked_command_disposition_(CURRENT_TAB),
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      pending_web_app_action_(NONE),
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ALLOW_THIS_IN_INITIALIZER_LIST(
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          tab_restore_service_delegate_(
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              new BrowserTabRestoreServiceDelegate(this))) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::SSL_VISIBLE_STATE_CHANGED,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  registrar_.Add(this, NotificationType::EXTENSION_UNINSTALLED,
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                 NotificationService::AllSources());
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED,
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Need to know when to alert the user of theme install delay.
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_READY_FOR_INSTALL,
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // NOTE: These prefs all need to be explicitly destroyed in the destructor
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // or you'll get a nasty surprise when you run the incognito tests.
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  PrefService* local_state = g_browser_process->local_state();
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (local_state)
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    printing_enabled_.Init(prefs::kPrintingEnabled, local_state, this);
247513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  dev_tools_disabled_.Init(prefs::kDevToolsDisabled,
248513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                           profile_->GetPrefs(), this);
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  incognito_mode_allowed_.Init(prefs::kIncognitoEnabled,
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               profile_->GetPrefs(), this);
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  edit_bookmarks_enabled_.Init(prefs::kEditBookmarksEnabled,
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               profile_->GetPrefs(), this);
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitCommandState();
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserList::AddBrowser(this);
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             profile_->GetPrefs(), NULL);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  instant_enabled_.Init(prefs::kInstantEnabled, profile_->GetPrefs(), this);
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!TabMenuModel::AreVerticalTabsEnabled()) {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // might show vertical tabs but not show an option to turn them off.
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    use_vertical_tabs_.SetValue(false);
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateTabStripModelInsertionPolicy();
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_restore_service_ = profile->GetTabRestoreService();
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_restore_service_) {
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_restore_service_->AddObserver(this);
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabRestoreServiceChanged(tab_restore_service_);
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_->GetProfileSyncService())
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->GetProfileSyncService()->AddObserver(this);
2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreateInstantIfNecessary();
278dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
279dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Make sure TabFinder has been created. This does nothing if TabFinder is
280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // not enabled.
281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  TabFinder::GetInstance();
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser::~Browser() {
285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  VLOG_IF(1, g_log_bug53991) << "~Browser: " << profile_->IsOffTheRecord()
286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                             << "; stillActive="
287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                             << BrowserList::IsOffTheRecordSessionActive();
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_->GetProfileSyncService())
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->GetProfileSyncService()->RemoveObserver(this);
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserList::RemoveBrowser(this);
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_LINUX)
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!BrowserList::HasBrowserWithProfile(profile_)) {
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We're the last browser window with this profile. We need to nuke the
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TabRestoreService, which will start the shutdown of the
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // NavigationControllers and allow for proper shutdown. If we don't do this
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // chrome won't shutdown cleanly, and may end up crashing when some
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // thread tries to use the IO thread (or another thread) that is no longer
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // valid.
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This isn't a valid assumption for Mac OS, as it stays running after
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the last browser has closed. The Mac equivalent is in its app
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // controller.
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->ResetTabRestoreService();
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SessionService* session_service = profile_->GetSessionService();
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (session_service)
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    session_service->WindowClosed(session_id_);
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabRestoreService* tab_restore_service = profile()->GetTabRestoreService();
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_restore_service)
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_restore_service->BrowserClosed(tab_restore_service_delegate());
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  encoding_auto_detect_.Destroy();
31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  printing_enabled_.Destroy();
31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  dev_tools_disabled_.Destroy();
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  incognito_mode_allowed_.Destroy();
32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  instant_enabled_.Destroy();
32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  use_vertical_tabs_.Destroy();
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  edit_bookmarks_enabled_.Destroy();
32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_->IsOffTheRecord() &&
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !BrowserList::IsOffTheRecordSessionActive()) {
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // An incognito profile is no longer needed, this indirectly
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // frees its cache and cookies.
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->GetOriginalProfile()->DestroyOffTheRecordProfile();
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // There may be pending file dialogs, we need to tell them that we've gone
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // away so they don't try and call back to us.
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (select_file_dialog_.get())
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_file_dialog_->ListenerDestroyed();
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabRestoreServiceDestroyed(tab_restore_service_);
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser* Browser::Create(Profile* profile) {
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = new Browser(TYPE_NORMAL, profile);
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
348731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickBrowser* Browser::CreateForPopup(Type type,
349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 Profile* profile,
350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 TabContents* new_contents,
351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 const gfx::Rect& initial_bounds) {
352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(type & TYPE_POPUP);
353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Browser* browser = new Browser(type, profile);
354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  browser->set_override_bounds(initial_bounds);
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
356201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
357201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  browser->tabstrip_model()->AppendTabContents(wrapper, true);
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return browser;
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBrowser* Browser::CreateForType(Type type, Profile* profile) {
3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Browser* browser = new Browser(type, profile);
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBrowser* Browser::CreateForApp(const std::string& app_name,
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                               const gfx::Size& window_size,
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Profile* profile,
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               bool is_panel) {
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser::Type type = TYPE_APP;
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (is_panel) {
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      type = TYPE_APP_PANEL;
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // TYPE_APP_PANEL is the logical choice.  However, the panel UI
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // is not fully implemented.  See crbug/55943.
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      type = TYPE_APP_POPUP;
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = new Browser(type, profile);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->app_name_ = app_name;
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!window_size.IsEmpty()) {
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    gfx::Rect initial_pos(window_size);
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    browser->set_override_bounds(initial_pos);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser* Browser::CreateForDevTools(Profile* profile) {
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = new Browser(TYPE_DEVTOOLS, profile);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->app_name_ = DevToolsWindow::kDevToolsApp;
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::InitBrowserWindow() {
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!window_);
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window_ = CreateBrowserWindow();
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
412513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  {
413513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // TODO: This might hit the disk
414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    //   http://code.google.com/p/chromium/issues/detail?id=61638
415513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::ThreadRestrictions::ScopedAllowIO allow_io;
416513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
417513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Set the app user model id for this application to that of the application
418513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // name.  See http://crbug.com/7028.
4193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    app::win::SetAppIdForWindow(
420513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        type_ & TYPE_APP ?
421513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
422513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        ShellIntegration::GetChromiumAppId(profile_->GetPath()),
423513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        window()->GetNativeHandle());
424513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BROWSER_WINDOW_READY,
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<Browser>(this),
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::NoDetails());
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show the First Run information bubble if we've been told to.
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* local_state = g_browser_process->local_state();
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!local_state)
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (local_state->
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      bubble_type = FirstRun::OEM_BUBBLE;
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (local_state->
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      bubble_type = FirstRun::MINIMAL_BUBBLE;
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Reset the preference so we don't show the bubble for subsequent windows.
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window_->GetLocationBar()->ShowFirstRunBubble(bubble_type);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (local_state->FindPreference(
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs::kAutofillPersonalDataManagerFirstRun) &&
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      local_state->GetBoolean(prefs::kAutofillPersonalDataManagerFirstRun)) {
455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Notify PDM that this is a first run.
456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN)
457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ImportAutofillDataWin(profile_->GetPersonalDataManager());
458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif  // defined(OS_WIN)
459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Reset the preference so we don't call it again for subsequent windows.
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    local_state->ClearPref(prefs::kAutofillPersonalDataManagerFirstRun);
461731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Getters & Setters
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst std::vector<std::wstring>& Browser::user_data_dir_profiles() const {
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return g_browser_process->user_data_dir_profiles();
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::set_user_data_dir_profiles(
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<std::wstring>& profiles) {
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_browser_process->user_data_dir_profiles() = profiles;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFindBarController* Browser::GetFindBarController() {
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!find_bar_controller_.get()) {
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FindBar* find_bar = BrowserWindow::CreateFindBar(this);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_bar_controller_.reset(new FindBarController(find_bar));
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_bar->SetFindBarController(find_bar_controller_.get());
48172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper());
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return find_bar_controller_.get();
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::HasFindBarController() const {
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return find_bar_controller_.get() != NULL;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Creation Helpers:
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenEmptyWindow(Profile* profile) {
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->AddBlankTab(true);
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenWindowWithRestoredTabs(Profile* profile) {
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabRestoreService* service = profile->GetTabRestoreService();
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service)
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service->RestoreMostRecentEntry(NULL);
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
510731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  Browser* browser = GetOrCreateTabbedBrowser(
511731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      profile->GetOffTheRecordProfile());
512731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  browser->AddSelectedTabWithURL(url, PageTransition::LINK);
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTabContents* Browser::OpenApplication(
5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    Profile* profile,
519513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension,
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    extension_misc::LaunchContainer container,
521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabContents* existing_tab) {
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* tab = NULL;
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs();
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->SetActiveBit(extension->id(), true);
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
526731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100);
527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (container) {
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case extension_misc::LAUNCH_WINDOW:
5303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case extension_misc::LAUNCH_PANEL:
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab = Browser::OpenApplicationWindow(profile, extension, container,
532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           GURL(), NULL);
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
5343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case extension_misc::LAUNCH_TAB: {
535731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      tab = Browser::OpenApplicationTab(profile, extension, existing_tab);
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return tab;
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContents* Browser::OpenApplicationWindow(
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Profile* profile,
548513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension,
5493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    extension_misc::LaunchContainer container,
550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const GURL& url_input,
551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    Browser** app_browser) {
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url;
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!url_input.is_empty()) {
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension)
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK(extension->web_extent().ContainsURL(url_input));
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url = url_input;
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
558dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK(extension);  // Empty url and no extension.  Nothing to open.
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url = extension->GetFullLaunchURL();
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string app_name;
56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (extension)
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    app_name =
56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        web_app::GenerateApplicationNameFromExtensionId(extension->id());
56672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  else
56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    app_name = web_app::GenerateApplicationNameFromURL(url);
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RegisterAppPrefs(app_name, profile);
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool as_panel = extension && (container == extension_misc::LAUNCH_PANEL);
57221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
57321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  gfx::Size window_size;
57421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (extension)
57521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    window_size.SetSize(extension->launch_width(),
57621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                        extension->launch_height());
57721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
57821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Browser* browser = Browser::CreateForApp(app_name, window_size, profile,
579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           as_panel);
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (app_browser)
582201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    *app_browser = browser;
583201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
584201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper =
585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* contents = wrapper->tab_contents();
587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
588731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  contents->render_view_host()->SyncRendererPrefs();
589731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  browser->window()->Show();
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //                focus explicitly.
593731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  contents->view()->SetInitialFocus();
594201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return contents;
595201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
596201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
597201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContents* Browser::OpenAppShortcutWindow(Profile* profile,
598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                            const GURL& url,
599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                            bool update_shortcut) {
600201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  Browser* app_browser;
601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* tab = OpenApplicationWindow(
602201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      profile,
603201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      NULL,  // this is a URL app.  No extension.
604201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      extension_misc::LAUNCH_WINDOW,
605201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      url,
606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      &app_browser);
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
608201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!tab)
609201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return NULL;
610201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
611201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (update_shortcut) {
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Set UPDATE_SHORTCUT as the pending web app action. This action is picked
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // up in LoadingStateChanged to schedule a GetApplicationInfo. And when
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the web app info is available, TabContents notifies Browser via
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // OnDidGetApplicationInfo, which calls
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // pending web app action.
618201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    app_browser->pending_web_app_action_ = UPDATE_SHORTCUT;
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
620201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return tab;
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContents* Browser::OpenApplicationTab(Profile* profile,
625513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                         const Extension* extension,
626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         TabContents* existing_tab) {
62772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* browser =
62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      BrowserList::FindBrowserWithType(profile, Browser::TYPE_NORMAL, false);
629731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TabContents* contents = NULL;
63072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!browser)
631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return contents;
6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Check the prefs for overridden mode.
63421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* extensions_service = profile->GetExtensionService();
6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(extensions_service);
6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExtensionPrefs::LaunchType launch_type =
638201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      extensions_service->extension_prefs()->GetLaunchType(
63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          extension->id(), ExtensionPrefs::LAUNCH_DEFAULT);
640731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100);
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int add_type = TabStripModel::ADD_ACTIVE;
6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (launch_type == ExtensionPrefs::LAUNCH_PINNED)
6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    add_type |= TabStripModel::ADD_PINNED;
6443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
64572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // For extensions lacking launch urls, determine a reasonable fallback.
64672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL extension_url = extension->GetFullLaunchURL();
64772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!extension_url.is_valid()) {
64872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    extension_url = extension->options_url();
64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!extension_url.is_valid())
65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      extension_url = GURL(chrome::kChromeUIExtensionsURL);
65172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
65272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(erikkay): START_PAGE doesn't seem like the right transition in all
6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // cases.
65572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser::NavigateParams params(browser, extension_url,
656513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                 PageTransition::START_PAGE);
657513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.tabstrip_add_types = add_type;
658731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
659731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Launch the application in the existing TabContents, if it was supplied.
660731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (existing_tab) {
661731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    TabStripModel* model = browser->tabstrip_model();
662201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int tab_index = model->GetWrapperIndex(existing_tab);
663731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
664731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    existing_tab->OpenURL(extension->GetFullLaunchURL(), existing_tab->GetURL(),
665731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                          CURRENT_TAB, PageTransition::LINK);
666513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) {
667731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      model->SetTabPinned(tab_index, true);
668201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      tab_index = model->GetWrapperIndex(existing_tab);
669513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    }
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE)
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      model->ActivateTabAt(tab_index, true);
672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    contents = existing_tab;
674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
675513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    params.disposition = NEW_FOREGROUND_TAB;
676513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    browser::Navigate(&params);
677201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    contents = params.target_contents->tab_contents();
678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
68072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // TODO(skerner):  If we are already in full screen mode, and the user
68172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // set the app to open as a regular or pinned tab, what should happen?
68272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Today we open the tab, but stay in full screen mode.  Should we leave
68372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // full screen mode in this case?
68472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN &&
68572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      !browser->window()->IsFullscreen())
68672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    browser->ToggleFullscreenMode();
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
688731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return contents;
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenBookmarkManagerWindow(Profile* profile) {
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->ShowBookmarkManagerTab();
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenHistoryWindow(Profile* profile) {
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->ShowHistoryTab();
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenDownloadsWindow(Profile* profile) {
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->ShowDownloadsTab();
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenHelpWindow(Profile* profile) {
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->OpenHelpTab();
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// static
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenOptionsWindow(Profile* profile) {
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser->OpenOptionsDialog();
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
72672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
72772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
72872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::OpenClearBrowingDataDialogWindow(Profile* profile) {
72972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* browser = Browser::Create(profile);
73072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser->OpenClearBrowsingDataDialog();
73172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser->window()->Show();
73272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
73372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
73472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
73572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::OpenImportSettingsDialogWindow(Profile* profile) {
73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* browser = Browser::Create(profile);
73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser->OpenImportSettingsDialog();
73872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser->window()->Show();
73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OpenInstantConfirmDialogWindow(Profile* profile) {
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Browser* browser = Browser::Create(profile);
744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->OpenInstantConfirmDialog();
745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->window()->Show();
746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenExtensionsWindow(Profile* profile) {
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile);
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->ShowExtensionsTab();
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, State Storage and Retrieval for UI:
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string Browser::GetWindowPlacementKey() const {
7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string name(prefs::kBrowserWindowPlacement);
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!app_name_.empty()) {
7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    name.append("_");
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    name.append(app_name_);
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return name;
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::ShouldSaveWindowPlacement() const {
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only save the window placement of popups if they are restored.
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (type() & TYPE_POPUP) == 0 || browser_defaults::kRestorePopups;
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SaveWindowPlacement(const gfx::Rect& bounds, bool maximized) {
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save to the session storage service, used when reloading a past session.
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we don't want to be the ones who cause lazy initialization of
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the session service. This function gets called during initial window
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // showing, and we don't want to bring in the session service this early.
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile()->HasSessionService()) {
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionService* session_service = profile()->GetSessionService();
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (session_service)
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      session_service->SetWindowBounds(session_id_, bounds, maximized);
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect Browser::GetSavedWindowBounds() const {
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool record_mode = parsed_command_line.HasSwitch(switches::kRecordMode);
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool playback_mode = parsed_command_line.HasSwitch(switches::kPlaybackMode);
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (record_mode || playback_mode) {
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // In playback/record mode we always fix the size of the browser and
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // move it to (0,0).  The reason for this is two reasons:  First we want
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // resize/moves in the playback to still work, and Second we want
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // playbacks to work (as much as possible) on machines w/ different
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // screen sizes.
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return gfx::Rect(0, 0, 800, 600);
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect restored_bounds = override_bounds_;
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool maximized;
80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      &restored_bounds, &maximized);
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return restored_bounds;
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(beng): obtain maximized state some other way so we don't need to go
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//             through all this hassle.
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::GetSavedMaximizedState() const {
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStartMaximized))
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (maximized_state_ == MAXIMIZED_STATE_MAXIMIZED)
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (maximized_state_ == MAXIMIZED_STATE_UNMAXIMIZED)
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // An explicit maximized state was not set. Query the window sizer.
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect restored_bounds;
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool maximized = false;
82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WindowSizer::GetBrowserWindowBounds(app_name_, restored_bounds, this,
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      &restored_bounds, &maximized);
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return maximized;
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSkBitmap Browser::GetCurrentPageIcon() const {
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* contents = GetSelectedTabContents();
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |contents| can be NULL since GetCurrentPageIcon() is called by the window
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // during the window's creation (before tabs have been added).
829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return contents ? contents->GetFavicon() : SkBitmap();
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 Browser::GetWindowTitleForCurrentTab() const {
833201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* contents = GetSelectedTabContents();
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 title;
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |contents| can be NULL because GetWindowTitleForCurrentTab is called by the
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window during the window's creation (before tabs have been added).
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (contents) {
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    title = contents->GetTitle();
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FormatTitleForDisplay(&title);
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (title.empty())
843dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    title = TabContentsWrapper::GetDefaultTitle();
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On Mac or ChromeOS, we don't want to suffix the page title with
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the application name.
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return title;
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN) || defined(OS_LINUX)
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't append the app name to window titles on app frames and app popups
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type_ & TYPE_APP)
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return l10n_util::GetStringFUTF16(string_id, title);
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FormatTitleForDisplay(string16* title) {
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t current_index = 0;
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t match_index;
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  while ((match_index = title->find(L'\n', current_index)) != string16::npos) {
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    title->replace(match_index, 1, string16());
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    current_index = match_index;
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, OnBeforeUnload handling:
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Browser::TabsNeedBeforeUnloadFired() {
87221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (tabs_needing_before_unload_fired_.empty()) {
87321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    for (int i = 0; i < tab_count(); ++i) {
87421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      TabContents* contents = GetTabContentsAt(i);
87521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (contents->NeedToFireBeforeUnload())
87621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        tabs_needing_before_unload_fired_.insert(contents);
87721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
87821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
87921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return !tabs_needing_before_unload_fired_.empty();
88021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
88121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::ShouldCloseWindow() {
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanCloseWithInProgressDownloads())
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (HasCompletedUnloadProcessing())
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return IsClosingPermitted();
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_attempting_to_close_browser_ = true;
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!TabsNeedBeforeUnloadFired())
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return IsClosingPermitted();
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProcessPendingTabs();
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OnWindowClosing() {
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!ShouldCloseWindow())
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool exiting = false;
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Application should shutdown on last window close if the user is explicitly
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // trying to quit, or if there is nothing keeping the browser alive (such as
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // AppController on the Mac, or BackgroundContentsService for background
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pages).
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool should_quit_if_last_browser =
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_shutdown::IsTryingToQuit() || !BrowserList::WillKeepAlive();
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (should_quit_if_last_browser && BrowserList::size() == 1) {
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE);
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    exiting = true;
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't use HasSessionService here, we want to force creation of the
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // session service so that user can restore what was open.
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SessionService* session_service = profile()->GetSessionService();
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (session_service)
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    session_service->WindowClosing(session_id());
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabRestoreService* tab_restore_service = profile()->GetTabRestoreService();
923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_restore_service && type() == TYPE_NORMAL && tab_count())
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_restore_service->BrowserClosing(tab_restore_service_delegate());
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(sky): convert session/tab restore to use notification.
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BROWSER_CLOSING,
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<Browser>(this),
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<bool>(&exiting));
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseAllTabs();
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In-progress download termination handling:
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::InProgressDownloadResponse(bool cancel_downloads) {
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (cancel_downloads) {
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cancel_download_confirmation_state_ = RESPONSE_RECEIVED;
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CloseWindow();
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets the confirmation state to NOT_PROMPTED so that if the user tries to
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // close again we'll show the warning again.
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cancel_download_confirmation_state_ = NOT_PROMPTED;
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show the download page so the user can figure-out what downloads are still
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in-progress.
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowDownloadsTab();
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
9553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Browser, TabStripModel pass-thrus:
9563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint Browser::tab_count() const {
9583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return tab_handler_->GetTabStripModel()->count();
9593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint Browser::active_index() const {
962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return tab_handler_->GetTabStripModel()->active_index();
9633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint Browser::GetIndexOfController(
9663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const NavigationController* controller) const {
9673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return tab_handler_->GetTabStripModel()->GetIndexOfController(controller);
9683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
970201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::GetSelectedTabContentsWrapper() const {
971201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return tabstrip_model()->GetSelectedTabContents();
972201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
973201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::GetTabContentsWrapperAt(int index) const {
974201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return tabstrip_model()->GetTabContentsAt(index);
9753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTabContents* Browser::GetSelectedTabContents() const {
978201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = GetSelectedTabContentsWrapper();
979201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (wrapper)
980201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return wrapper->tab_contents();
981201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return NULL;
982201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
983201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
984201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContents* Browser::GetTabContentsAt(int index) const {
985201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
986201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (wrapper)
987201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return wrapper->tab_contents();
988201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return NULL;
9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::ActivateTabAt(int index, bool user_gesture) {
992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_handler_->GetTabStripModel()->ActivateTabAt(index, user_gesture);
993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Browser::IsTabPinned(int index) const {
996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return tabstrip_model()->IsTabPinned(index);
9973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::CloseAllTabs() {
10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->CloseAllTabs();
10013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
10023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
10033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick////////////////////////////////////////////////////////////////////////////////
1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Tab adding/showing functions:
1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Browser::IsTabStripEditable() const {
100721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return window()->IsTabStripEditable();
100821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
100921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint Browser::GetIndexForInsertionDuringRestore(int relative_index) {
10113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return (tab_handler_->GetTabStripModel()->insertion_policy() ==
10123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TabStripModel::INSERT_AFTER) ? tab_count() : relative_index;
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::AddSelectedTabWithURL(const GURL& url,
1016731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                            PageTransition::Type transition) {
1017513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::NavigateParams params(this, url, transition);
1018513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.disposition = NEW_FOREGROUND_TAB;
1019513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::Navigate(&params);
1020513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return params.target_contents;
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1023201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContents* Browser::AddTab(TabContentsWrapper* tab_contents,
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             PageTransition::Type type) {
10253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->AddTabContents(
1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents, -1, type, TabStripModel::ADD_ACTIVE);
1027201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return tab_contents->tab_contents();
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::AddTabContents(TabContents* new_contents,
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             WindowOpenDisposition disposition,
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const gfx::Rect& initial_pos,
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool user_gesture) {
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddNewContents(NULL, new_contents, disposition, initial_pos, user_gesture);
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseTabContents(TabContents* contents) {
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CloseContents(contents);
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::BrowserShowHtmlDialog(HtmlDialogUIDelegate* delegate,
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    gfx::NativeWindow parent_window) {
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowHtmlDialog(delegate, parent_window);
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::BrowserRenderWidgetShowing() {
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetShowing();
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::BookmarkBarSizeChanged(bool is_animating) {
1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window_->ToolbarSizeChanged(is_animating);
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContents* Browser::AddRestoredTab(
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<TabNavigation>& navigations,
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int tab_index,
1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int selected_navigation,
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& extension_app_id,
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool select,
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool pin,
10613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bool from_last_session,
10623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SessionStorageNamespace* session_storage_namespace) {
1063201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
1064201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      MSG_ROUTING_NONE,
1065201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetSelectedTabContents(),
10663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      session_storage_namespace);
1067201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* new_tab = wrapper->tab_contents();
1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  new_tab->controller().RestoreFromState(navigations, selected_navigation,
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         from_last_session);
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int add_types = select ? TabStripModel::ADD_ACTIVE :
1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      TabStripModel::ADD_NONE;
1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (pin) {
1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_index = std::min(tab_index, tabstrip_model()->IndexOfFirstNonMiniTab());
1076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    add_types |= TabStripModel::ADD_PINNED;
1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_handler_->GetTabStripModel()->InsertTabContentsAt(tab_index, wrapper,
1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                        add_types);
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (select) {
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window_->Activate();
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We set the size of the view here, before WebKit does its initial
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // layout.  If we don't, the initial layout of background tabs will be
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // performed with a view width of 0, which may cause script outputs and
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // anchor link location calculations to be incorrect even after a new
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // layout with proper view dimensions. TabStripModel::AddTabContents()
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // contains similar logic.
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_tab->view()->SizeContents(window_->GetRestoredBounds().size());
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_tab->HideContents();
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_->HasSessionService()) {
1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionService* session_service = profile_->GetSessionService();
1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (session_service)
1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      session_service->TabRestored(&new_tab->controller(), pin);
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new_tab;
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ReplaceRestoredTab(
1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<TabNavigation>& navigations,
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int selected_navigation,
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool from_last_session,
11043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& extension_app_id,
11053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SessionStorageNamespace* session_storage_namespace) {
1106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = TabContentsFactory(profile(), NULL,
11073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      MSG_ROUTING_NONE,
1108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetSelectedTabContents(),
11093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      session_storage_namespace);
1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  wrapper->extension_tab_helper()->SetExtensionAppById(extension_app_id);
1111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* replacement = wrapper->tab_contents();
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  replacement->controller().RestoreFromState(navigations, selected_navigation,
1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             from_last_session);
1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->ReplaceNavigationControllerAt(
1116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_handler_->GetTabStripModel()->active_index(),
1117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      wrapper);
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanRestoreTab() {
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return command_updater_.IsCommandEnabled(IDC_RESTORE_TAB);
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::NavigateToIndexWithDisposition(int index,
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             WindowOpenDisposition disp) {
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController& controller =
1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetOrCloneTabForDisposition(disp)->controller();
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (index < 0 || index >= controller.entry_count())
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  controller.GoToIndex(index);
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbrowser::NavigateParams Browser::GetSingletonTabNavigateParams(
1135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const GURL& url) {
1136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::NavigateParams params(this, url, PageTransition::AUTO_BOOKMARK);
1137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.disposition = SINGLETON_TAB;
1138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  params.window_action = browser::NavigateParams::SHOW_WINDOW;
1139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return params;
1140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
1141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Browser::ShowSingletonTab(const GURL& url) {
1143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::Navigate(&params);
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool show_main_ui = (type() == TYPE_NORMAL) && !is_fullscreen;
1150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool show_main_ui = (type() == TYPE_NORMAL);
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool main_not_fullscreen_or_popup =
1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_main_ui && !is_fullscreen && (type() & TYPE_POPUP) == 0;
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigation commands
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Window management commands
1161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
1162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (type() & TYPE_POPUP) && !is_fullscreen);
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Focus various bits of UI
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDC_FOCUS_MENU_BAR, main_not_fullscreen_or_popup);
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(
1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDC_FOCUS_NEXT_PANE, main_not_fullscreen_or_popup);
1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(
1173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen_or_popup);
1174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(
1175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDC_FOCUS_BOOKMARKS, main_not_fullscreen_or_popup);
1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(
1177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen_or_popup);
1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show various bits of UI
1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
1181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
11823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
11833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      browser_defaults::bookmarks_enabled && show_main_ui);
1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_main_ui && profile_->IsSyncAccessible());
11873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
1189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
119472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
119572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
119672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Assorted browser commands:
1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::ShouldOpenNewTabForWindowDisposition(
1203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    WindowOpenDisposition disposition) {
1204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (disposition == NEW_FOREGROUND_TAB ||
1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          disposition == NEW_BACKGROUND_TAB);
1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContents* Browser::GetOrCloneTabForDisposition(
1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       WindowOpenDisposition disposition) {
1210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ShouldOpenNewTabForWindowDisposition(disposition)) {
1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    current_tab = current_tab->Clone();
12133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tab_handler_->GetTabStripModel()->AddTabContents(
1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        current_tab, -1, PageTransition::LINK,
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        disposition == NEW_FOREGROUND_TAB ? TabStripModel::ADD_ACTIVE :
1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            TabStripModel::ADD_NONE);
1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return current_tab->tab_contents();
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateTabStripModelInsertionPolicy() {
12223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->SetInsertionPolicy(UseVerticalTabs() ?
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::INSERT_BEFORE : TabStripModel::INSERT_AFTER);
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UseVerticalTabsChanged() {
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateTabStripModelInsertionPolicy();
1228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->ToggleTabStripMode();
1229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
1232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        bool check_fullscreen) const {
1233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On Mac, fullscreen mode has most normal things (in a slide-down panel). On
1234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // other platforms, we hide some controls when in fullscreen mode.
1235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool hide_ui_for_fullscreen = false;
1236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
1237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  hide_ui_for_fullscreen = check_fullscreen && window_ &&
1238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window_->IsFullscreen();
1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  unsigned int features = FEATURE_INFOBAR | FEATURE_SIDEBAR;
1242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_CHROMEOS)
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Chrome OS opens a FileBrowse pop up instead of using download shelf.
1245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // So FEATURE_DOWNLOADSHELF is only added for non-chromeos platforms.
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  features |= FEATURE_DOWNLOADSHELF;
1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif  // !defined(OS_CHROMEOS)
1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type() == TYPE_NORMAL) {
1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    features |= FEATURE_BOOKMARKBAR;
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!hide_ui_for_fullscreen) {
125421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (type() != TYPE_NORMAL)
1255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      features |= FEATURE_TITLEBAR;
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (type() == TYPE_NORMAL)
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      features |= FEATURE_TABSTRIP;
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (type() == TYPE_NORMAL)
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      features |= FEATURE_TOOLBAR;
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if ((type() & Browser::TYPE_APP) == 0)
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      features |= FEATURE_LOCATIONBAR;
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !!(features & feature);
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::IsClosingPermitted() {
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabCloseableStateWatcher* watcher =
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_browser_process->tab_closeable_state_watcher();
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool can_close = !watcher || watcher->CanCloseBrowser(this);
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!can_close && is_attempting_to_close_browser_)
1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelWindowClose();
1275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return can_close;
1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::GoBack(WindowOpenDisposition disposition) {
1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Back"), profile_);
1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_tab->controller().CanGoBack()) {
1283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* new_tab = GetOrCloneTabForDisposition(disposition);
1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If we are on an interstitial page and clone the tab, it won't be copied
1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // to the new tab, so we don't need to go back.
1286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (current_tab->tab_contents()->showing_interstitial_page() &&
1287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        (new_tab != current_tab->tab_contents()))
1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_tab->controller().GoBack();
1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::GoForward(WindowOpenDisposition disposition) {
1294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Forward"), profile_);
1295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (GetSelectedTabContentsWrapper()->controller().CanGoForward())
1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetOrCloneTabForDisposition(disposition)->controller().GoForward();
1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Reload(WindowOpenDisposition disposition) {
1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Reload"), profile_);
1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReloadInternal(disposition, false);
1302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ReloadIgnoringCache(WindowOpenDisposition disposition) {
1305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ReloadIgnoringCache"), profile_);
1306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReloadInternal(disposition, true);
1307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ReloadInternal(WindowOpenDisposition disposition,
1310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool ignore_cache) {
1311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we are showing an interstitial, treat this as an OpenURL.
1312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* current_tab = GetSelectedTabContents();
1313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (current_tab && current_tab->showing_interstitial_page()) {
1314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NavigationEntry* entry = current_tab->controller().GetActiveEntry();
1315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(entry);  // Should exist if interstitial is showing.
1316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OpenURL(entry->url(), GURL(), disposition, PageTransition::RELOAD);
1317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // As this is caused by a user action, give the focus to the page.
1321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* tab = GetOrCloneTabForDisposition(disposition);
1322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!tab->FocusLocationBarByDefault())
1323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    tab->Focus();
1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (ignore_cache)
1325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    tab->controller().ReloadIgnoringCache(true);
1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
1327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    tab->controller().Reload(true);
1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Home(WindowOpenDisposition disposition) {
1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Home"), profile_);
1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  OpenURL(GetHomePage(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenCurrentURL() {
1336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("LoadURL"), profile_);
1337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LocationBar* location_bar = window_->GetLocationBar();
1338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!location_bar)
1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WindowOpenDisposition open_disposition =
1342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      location_bar->GetWindowOpenDisposition();
1343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (OpenInstant(open_disposition))
13443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
1345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(WideToUTF8(location_bar->GetInputString()));
1347dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1348dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (open_disposition == CURRENT_TAB && TabFinder::IsEnabled()) {
1349dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    Browser* existing_browser = NULL;
1350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* existing_tab = TabFinder::GetInstance()->FindTab(
1351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        this, url, &existing_browser);
1352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (existing_tab) {
1353dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      existing_browser->ActivateContents(existing_tab);
1354dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return;
1355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
1356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::NavigateParams params(this, url, location_bar->GetPageTransition());
1359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.disposition = open_disposition;
1360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
1361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // inherit the opener. In some cases the tabstrip will determine the group
1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be inherited, in which case the group is inherited instead of the
1363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // opener.
1364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.tabstrip_add_types =
1365513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
1366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::Navigate(&params);
1367dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
1368dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(profile_->GetExtensionService());
1369dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (profile_->GetExtensionService()->IsInstalledApp(url)) {
1370dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
1371dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                              extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
1372dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                              extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
1373dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Stop() {
1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Stop"), profile_);
1378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  GetSelectedTabContentsWrapper()->tab_contents()->Stop();
1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::NewWindow() {
1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (browser_defaults::kAlwaysOpenIncognitoWindow &&
138372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CommandLine::ForCurrentProcess()->HasSwitch(switches::kIncognito) &&
138472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      incognito_mode_allowed_.GetValue()) {
1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NewIncognitoWindow();
1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("NewWindow"), profile_);
1389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SessionService* session_service =
1390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetOriginalProfile()->GetSessionService();
1391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!session_service ||
1392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !session_service->RestoreIfNecessary(std::vector<GURL>())) {
1393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser::OpenEmptyWindow(profile_->GetOriginalProfile());
1394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::NewIncognitoWindow() {
139872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!incognito_mode_allowed_.GetValue()) {
139972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    NewWindow();
140072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
140172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
140272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
1403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("NewIncognitoWindow"), profile_);
1404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser::OpenEmptyWindow(profile_->GetOffTheRecordProfile());
1405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseWindow() {
1408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("CloseWindow"), profile_);
1409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->Close();
1410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::NewTab() {
1413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("NewTab"), profile_);
1414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type() == TYPE_NORMAL) {
1416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddBlankTab(true);
141772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetSelectedTabContentsWrapper()->view()->RestoreFocus();
1418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
1419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Browser* b = GetOrCreateTabbedBrowser(profile_);
1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    b->AddBlankTab(true);
1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    b->window()->Show();
1422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The call to AddBlankTab above did not set the focus to the tab as its
1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // window was not active, so we have to do it explicitly.
1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // See http://crbug.com/6380.
1425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    b->GetSelectedTabContentsWrapper()->view()->RestoreFocus();
1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseTab() {
1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("CloseTab_Accelerator"),
1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
1432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (CanCloseTab())
1433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_handler_->GetTabStripModel()->CloseSelectedTabs();
1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SelectNextTab() {
1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("SelectNextTab"), profile_);
14383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->SelectNextTab();
1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SelectPreviousTab() {
1442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("SelectPrevTab"), profile_);
14433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->SelectPreviousTab();
14443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
14453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
14463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::OpenTabpose() {
14473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX)
1448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!CommandLine::ForCurrentProcess()->HasSwitch(
1449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        switches::kEnableExposeForTabs)) {
1450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
1451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
14533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"), profile_);
14543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  window()->OpenTabpose();
14553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
14563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NOTREACHED();
14573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
1458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::MoveTabNext() {
1461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"), profile_);
14623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->MoveTabNext();
1463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::MoveTabPrevious() {
1466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("MoveTabPrevious"), profile_);
14673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->MoveTabPrevious();
1468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SelectNumberedTab(int index) {
1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (index < tab_count()) {
1472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UserMetrics::RecordAction(UserMetricsAction("SelectNumberedTab"),
1473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              profile_);
1474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_handler_->GetTabStripModel()->ActivateTabAt(index, true);
1475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SelectLastTab() {
1479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("SelectLastTab"), profile_);
14803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->SelectLastTab();
1481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::DuplicateTab() {
1484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Duplicate"), profile_);
1485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DuplicateContentsAt(active_index());
1486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::RestoreTab() {
1489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("RestoreTab"), profile_);
1490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabRestoreService* service = profile_->GetTabRestoreService();
1491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service)
1492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->RestoreMostRecentEntry(tab_restore_service_delegate());
1495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::WriteCurrentURLToClipboard() {
1498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(ericu): There isn't currently a metric for this.  Should there be?
1499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't appear to track the action when it comes from the
1500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // RenderContextViewMenu.
1501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* contents = GetSelectedTabContents();
1503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!contents->ShouldDisplayURL())
1504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chrome_browser_net::WriteURLToClipboard(
1507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents->GetURL(),
15083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
1509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_browser_process->clipboard());
1510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ConvertPopupToTabbedBrowser() {
1513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowAsTab"), profile_);
1514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int tab_strip_index = tab_handler_->GetTabStripModel()->active_index();
1515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents =
15163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      tab_handler_->GetTabStripModel()->DetachTabContentsAt(tab_strip_index);
1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = Browser::Create(profile_);
1518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->tabstrip_model()->AppendTabContents(contents, true);
1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->window()->Show();
1520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ToggleFullscreenMode() {
1523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
1524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // In kiosk mode, we always want to be fullscreen. When the browser first
1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // starts we're not yet fullscreen, so let the initial toggle go through.
1526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode) &&
1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window_->IsFullscreen())
1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"), profile_);
1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->SetFullscreen(!window_->IsFullscreen());
1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // On Linux, setting fullscreen mode is an async call to the X server, which
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // may or may not support fullscreen mode.
1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_LINUX)
1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCommandsForFullscreenMode(window_->IsFullscreen());
1537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Search() {
1542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the NTP is showing, close it.
1543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (StartsWithASCII(GetSelectedTabContents()->GetURL().spec(),
1544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       chrome::kChromeUINewTabURL, true)) {
1545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CloseTab();
1546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
15483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Exit fullscreen to show omnibox.
1550513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (window_->IsFullscreen()) {
15513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ToggleFullscreenMode();
1552513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // ToggleFullscreenMode is asynchronous, so we don't have omnibox
1553513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // visible at this point. Wait for next event cycle which toggles
1554513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // the visibility of omnibox before creating new tab.
1555513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    MessageLoop::current()->PostTask(
1556513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        FROM_HERE, method_factory_.NewRunnableMethod(&Browser::Search));
1557513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return;
1558513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
15593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Otherwise just open it.
1561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NewTab();
1562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
156321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
156421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid Browser::ShowKeyboardOverlay() {
156521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  window_->ShowKeyboardOverlay(window_->GetNativeHandle());
156621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
1567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Exit() {
1570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Exit"), profile_);
15713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_CHROMEOS)
1572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  chromeos::BootTimesLoader::Get()->AddLogoutTimeMarker("LogoutStarted", false);
1573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Write /tmp/uptime-logout-started as well.
1574201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const char kLogoutStarted[] = "logout-started";
1575201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  chromeos::BootTimesLoader::Get()->RecordCurrentStats(kLogoutStarted);
157672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
157772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Login screen should show up in owner's locale.
157872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  PrefService* state = g_browser_process->local_state();
157972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (state) {
158072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    std::string owner_locale = state->GetString(prefs::kOwnerLocale);
158172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!owner_locale.empty() &&
158272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        state->GetString(prefs::kApplicationLocale) != owner_locale &&
158372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        !state->IsManagedPreference(prefs::kApplicationLocale)) {
158472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state->SetString(prefs::kApplicationLocale, owner_locale);
158572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      state->ScheduleSavePersistentPrefs();
158672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
158772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
15883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
158921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BrowserList::Exit();
1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::BookmarkCurrentPage() {
1593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Star"), profile_);
1594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkModel* model = profile()->GetBookmarkModel();
1596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!model || !model->IsLoaded())
1597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // Ignore requests until bookmarks are loaded.
1598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url;
16003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  string16 title;
160121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  TabContents* tab = GetSelectedTabContents();
160221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bookmark_utils::GetURLAndTitleToBookmark(tab, &url, &title);
1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool was_bookmarked = model->IsBookmarked(url);
160421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!was_bookmarked && profile_->IsOffTheRecord()) {
1605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If we're incognito the favicon may not have been saved. Save it now
160621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // so that bookmarks have an icon for the page.
160721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    tab->SaveFavicon();
160821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  model->SetURLStarred(url, title, true);
1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the model actually added a bookmark before showing the star. A
1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // bookmark isn't created if the url is invalid.
1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (window_->IsActive() && model->IsBookmarked(url)) {
1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Only show the bubble if the window is active, otherwise we may get into
1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // weird situations were the bubble is deleted as soon as it is shown.
1615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window_->ShowBookmarkBubble(url, was_bookmarked);
1616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SavePage() {
1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("SavePage"), profile_);
1621513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  TabContents* current_tab = GetSelectedTabContents();
1622513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  if (current_tab && current_tab->contents_mime_type() == "application/pdf")
1623513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    UserMetrics::RecordAction(UserMetricsAction("PDF.SavePage"), profile_);
1624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetSelectedTabContentsWrapper()->download_tab_helper()->OnSavePage();
1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid Browser::ViewSelectedSource() {
162821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ViewSource(GetSelectedTabContentsWrapper());
1629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowFindBar() {
1632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetFindBarController()->Show();
1633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::SupportsWindowFeature(WindowFeature feature) const {
1636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return SupportsWindowFeatureImpl(feature, true);
1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanSupportWindowFeature(WindowFeature feature) const {
1640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return SupportsWindowFeatureImpl(feature, false);
1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::EmailPageLocation() {
1644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("EmailPageLocation"), profile_);
1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetSelectedTabContents()->EmailPageLocation();
1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Print() {
1649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("PrintPreview"), profile_);
1650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (CommandLine::ForCurrentProcess()->HasSwitch(
1651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      switches::kEnablePrintPreview)) {
1652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printing::PrintPreviewTabController::PrintPreview(
1653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        GetSelectedTabContents());
1654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
1655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GetSelectedTabContentsWrapper()->print_view_manager()->PrintNow();
1656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ToggleEncodingAutoDetect() {
1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("AutoDetectChange"), profile_);
1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  encoding_auto_detect_.SetValue(!encoding_auto_detect_.GetValue());
1662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If "auto detect" is turned on, then any current override encoding
1663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is cleared. This also implicitly performs a reload.
1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // OTOH, if "auto detect" is turned off, we don't change the currently
1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // active encoding.
1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (encoding_auto_detect_.GetValue()) {
1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* contents = GetSelectedTabContents();
1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (contents)
1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      contents->ResetOverrideEncoding();
1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OverrideEncoding(int encoding_id) {
1674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("OverrideEncoding"), profile_);
1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string selected_encoding =
1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CharacterEncoding::GetCanonicalEncodingNameByCommandId(encoding_id);
1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* contents = GetSelectedTabContents();
1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!selected_encoding.empty() && contents)
1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     contents->SetOverrideEncoding(selected_encoding);
1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Update the list of recently selected encodings.
1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string new_selected_encoding_list;
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (CharacterEncoding::UpdateRecentlySelectedEncoding(
1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        profile_->GetPrefs()->GetString(prefs::kRecentlySelectedEncoding),
1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        encoding_id,
1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        &new_selected_encoding_list)) {
1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_->GetPrefs()->SetString(prefs::kRecentlySelectedEncoding,
1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    new_selected_encoding_list);
1688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Cut() {
1692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Cut"), profile_);
1693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->Cut();
1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Copy() {
1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Copy"), profile_);
1698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->Copy();
1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Paste() {
1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Paste"), profile_);
1703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->Paste();
1704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Find() {
1707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Find"), profile_);
1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FindInPage(false, false);
1709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FindNext() {
1712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FindNext"), profile_);
1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FindInPage(true, true);
1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FindPrevious() {
1717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FindPrevious"), profile_);
1718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FindInPage(true, false);
1719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Zoom(PageZoom::Function zoom_function) {
1722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const UserMetricsAction kActions[] = {
1723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      UserMetricsAction("ZoomMinus"),
1724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      UserMetricsAction("ZoomNormal"),
1725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      UserMetricsAction("ZoomPlus")
1726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      };
1727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(kActions[zoom_function - PageZoom::ZOOM_OUT],
1729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
1730201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* tab_contents = GetSelectedTabContentsWrapper();
1731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_contents->render_view_host()->Zoom(zoom_function);
1732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusToolbar() {
1735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusToolbar"), profile_);
1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->FocusToolbar();
1737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusAppMenu() {
1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusAppMenu"), profile_);
1741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->FocusAppMenu();
1742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusLocationBar() {
1745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusLocation"), profile_);
1746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->SetFocusToLocationBar(true);
1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusBookmarksToolbar() {
1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusBookmarksToolbar"),
1751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
1752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->FocusBookmarksToolbar();
1753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusChromeOSStatus() {
1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusChromeOSStatus"), profile_);
1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->FocusChromeOSStatus();
1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusNextPane() {
1761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusNextPane"), profile_);
1762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->RotatePaneFocus(true);
1763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusPreviousPane() {
1766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusPreviousPane"), profile_);
1767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->RotatePaneFocus(false);
1768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FocusSearch() {
1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(beng): replace this with FocusLocationBar
1772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("FocusSearch"), profile_);
1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->GetLocationBar()->FocusSearch();
1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenFile() {
1777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("OpenFile"), profile_);
1778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS) && !defined(FILE_MANAGER_EXTENSION)
1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FileBrowseUI::OpenPopup(profile_,
1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          "",
1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          FileBrowseUI::kPopupWidth,
1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          FileBrowseUI::kPopupHeight);
1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!select_file_dialog_.get())
1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_file_dialog_ = SelectFileDialog::Create(this);
1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath directory = profile_->last_selected_directory();
1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(beng): figure out how to juggle this.
1790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeWindow parent_window = window_->GetNativeHandle();
1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  string16(), directory,
1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  NULL, 0, FILE_PATH_LITERAL(""),
1794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  GetSelectedTabContents(),
1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  parent_window, NULL);
1796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenCreateShortcutsDialog() {
1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("CreateShortcut"), profile_);
1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_LINUX)
1802201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* current_tab = GetSelectedTabContentsWrapper();
1803201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(current_tab &&
1804201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      web_app::IsValidUrl(current_tab->tab_contents()->GetURL())) <<
1805201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          "Menu item should be disabled.";
1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = current_tab->controller().GetLastCommittedEntry();
1808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry)
1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // RVH's GetApplicationInfo should not be called before it returns.
1812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(pending_web_app_action_ == NONE);
1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_web_app_action_ = CREATE_SHORTCUT;
1814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Start fetching web app info for CreateApplicationShortcut dialog and show
1816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the dialog when the data is available in OnDidGetApplicationInfo.
1817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  current_tab->extension_tab_helper()->GetApplicationInfo(entry->page_id());
1818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
1819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NOTIMPLEMENTED();
1820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
1821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ToggleDevToolsWindow(DevToolsToggleAction action) {
1824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string uma_string;
1825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (action) {
1826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
1827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      uma_string = "DevTools_ToggleConsole";
1828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case DEVTOOLS_TOGGLE_ACTION_NONE:
1830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case DEVTOOLS_TOGGLE_ACTION_INSPECT:
1831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
1832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      uma_string = "DevTools_ToggleWindow";
1833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
1834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction(uma_string.c_str()), profile_);
1836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsManager::GetInstance()->ToggleDevToolsWindow(
1837201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetSelectedTabContentsWrapper()->render_view_host(), action);
1838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::OpenTaskManager(bool highlight_background_resources) {
1841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("TaskManager"), profile_);
184272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (highlight_background_resources)
184372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    window_->ShowBackgroundPages();
184472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  else
184572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    window_->ShowTaskManager();
1846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenBugReportDialog() {
1849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ReportBug"), profile_);
185072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser::ShowHtmlBugReportView(this);
1851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ToggleBookmarkBar() {
1854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowBookmarksBar"), profile_);
1855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ToggleBookmarkBar();
1856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenBookmarkManager() {
1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"), profile_);
1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowBookmarkManagerTab();
1861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowAppMenu() {
186472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We record the user metric for this event in WrenchMenu::RunMenu.
1865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ShowAppMenu();
1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowBookmarkManagerTab() {
1869731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UserMetrics::RecordAction(UserMetricsAction("ShowBookmarks"), profile_);
1870dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIBookmarksURL));
1871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowHistoryTab() {
1874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowHistory"), profile_);
1875dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIHistoryURL));
1876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowDownloadsTab() {
1879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowDownloads"), profile_);
1880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (window()) {
1881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadShelf* shelf = window()->GetDownloadShelf();
1882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (shelf->IsShowing())
1883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      shelf->Close();
1884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1885dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIDownloadsURL));
1886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowExtensionsTab() {
1889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ShowExtensions"), profile_);
1890dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIExtensionsURL));
1891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1893513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid Browser::ShowAboutConflictsTab() {
1894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  UserMetrics::RecordAction(UserMetricsAction("AboutConflicts"), profile_);
1895dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIConflictsURL));
1896513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
1897513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
1898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowBrokenPageTab(TabContents* contents) {
1899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ReportBug"), profile_);
1900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 page_title = contents->GetTitle();
1901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = contents->controller().GetActiveEntry();
1902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry)
1903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
1904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string page_url = entry->url().spec();
1905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> subst;
1906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  subst.push_back(UTF16ToASCII(page_title));
1907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  subst.push_back(page_url);
1908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string report_page_url =
1909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ReplaceStringPlaceholders(kBrokenPageUrl, subst, NULL);
1910dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(report_page_url));
1911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::ShowOptionsTab(const std::string& sub_page) {
19143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(chrome::kChromeUISettingsURL + sub_page);
1915dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1916dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  params.path_behavior = browser::NavigateParams::IGNORE_AND_NAVIGATE;
1917dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  browser::Navigate(&params);
1918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenClearBrowsingDataDialog() {
1921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("ClearBrowsingData_ShowDlg"),
1922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
1923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kClearBrowserDataSubPage);
1924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenOptionsDialog() {
19273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UserMetrics::RecordAction(UserMetricsAction("ShowOptions"), profile_);
1928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GURL url(chrome::kChromeUISettingsURL);
1929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser::NavigateParams params(GetSingletonTabNavigateParams(url));
1930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  params.path_behavior = browser::NavigateParams::IGNORE_AND_STAY_PUT;
1931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser::Navigate(&params);
1932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenPasswordManager() {
1935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Options_ShowPasswordManager"),
1936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            profile_);
1937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kPasswordManagerSubPage);
1938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenImportSettingsDialog() {
1941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("Import_ShowDlg"), profile_);
1942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kImportDataSubPage);
1943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OpenInstantConfirmDialog() {
1946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kInstantConfirmPage);
1947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenSyncMyBookmarksDialog() {
1950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  sync_ui_util::OpenSyncMyBookmarksDialog(
195172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      profile_, this, ProfileSyncService::START_FROM_WRENCH);
1952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenAboutChromeDialog() {
1955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("AboutChrome"), profile_);
19563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_CHROMEOS)
1957dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ShowSingletonTab(GURL(chrome::kChromeUIAboutURL));
19583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
1959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ShowAboutChromeDialog();
19603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
1961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenUpdateChromeDialog() {
1964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("UpdateChrome"), profile_);
1965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ShowUpdateChromeDialog();
1966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenHelpTab() {
19694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  GURL help_url(kHelpContentUrl);
19704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  GURL localized_help_url = google_util::AppendGoogleLocaleParam(help_url);
19714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AddSelectedTabWithURL(localized_help_url, PageTransition::AUTO_BOOKMARK);
1972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenThemeGalleryTabAndActivate() {
1975513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  AddSelectedTabWithURL(GURL(l10n_util::GetStringUTF8(IDS_THEMES_GALLERY_URL)),
1976513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                        PageTransition::LINK);
1977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenPrivacyDashboardTabAndActivate() {
1980513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  OpenURL(GURL(kPrivacyDashboardUrl), GURL(),
1981513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          NEW_FOREGROUND_TAB, PageTransition::LINK);
1982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->Activate();
1983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OpenAutofillHelpTabAndActivate() {
19864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  GURL help_url = google_util::AppendGoogleLocaleParam(GURL(kAutofillHelpUrl));
19874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  AddSelectedTabWithURL(help_url, PageTransition::LINK);
1988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::OpenSearchEngineOptionsDialog() {
1991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("EditSearchEngines"), profile_);
1992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kSearchEnginesSubPage);
19933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
19943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
1996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OpenFileManager() {
1997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UserMetrics::RecordAction(UserMetricsAction("OpenFileManager"));
1998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowSingletonTab(FileManagerUtil::GetFileBrowserUrl());
1999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenSystemOptionsDialog() {
2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("OpenSystemOptionsDialog"),
2003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
2004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kSystemOptionsSubPage);
2005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenInternetOptionsDialog() {
2008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserMetrics::RecordAction(UserMetricsAction("OpenInternetOptionsDialog"),
2009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            profile_);
2010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kInternetOptionsSubPage);
20113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
20123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
20133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::OpenLanguageOptionsDialog() {
20143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UserMetrics::RecordAction(UserMetricsAction("OpenLanguageOptionsDialog"),
20153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            profile_);
2016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(chrome::kLanguageOptionsSubPage);
2017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2018731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2019731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::OpenSystemTabAndActivate() {
2020731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  OpenURL(GURL(chrome::kChromeUISystemInfoURL), GURL(),
2021731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          NEW_FOREGROUND_TAB, PageTransition::LINK);
2022731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  window_->Activate();
2023731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2024731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2025731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::OpenMobilePlanTabAndActivate() {
2026731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  OpenURL(GURL(chrome::kChromeUIMobileSetupURL), GURL(),
2027731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          NEW_FOREGROUND_TAB, PageTransition::LINK);
2028731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  window_->Activate();
2029731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2032731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::OpenPluginsTabAndActivate() {
2033731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  OpenURL(GURL(chrome::kAboutPluginsURL), GURL(),
2034731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          NEW_FOREGROUND_TAB, PageTransition::LINK);
2035731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  window_->Activate();
2036731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2037731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
2039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
2041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SetNewHomePagePrefs(PrefService* prefs) {
2042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PrefService::Preference* home_page_pref =
2043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs->FindPreference(prefs::kHomePage);
2044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (home_page_pref &&
2045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !home_page_pref->IsManaged() &&
2046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !prefs->HasPrefPath(prefs::kHomePage)) {
2047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    prefs->SetString(prefs::kHomePage,
2048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GoogleURLTracker::kDefaultGoogleHomepage);
2049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PrefService::Preference* home_page_is_new_tab_page_pref =
2051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs->FindPreference(prefs::kHomePageIsNewTabPage);
2052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (home_page_is_new_tab_page_pref &&
2053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !home_page_is_new_tab_page_pref->IsManaged() &&
2054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !prefs->HasPrefPath(prefs::kHomePageIsNewTabPage))
2055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
2056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
2059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::RegisterPrefs(PrefService* prefs) {
2060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterIntegerPref(prefs::kOptionsWindowLastTabIndex, 0);
20613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->RegisterIntegerPref(prefs::kExtensionSidebarWidth, -1);
206272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterIntegerPref(prefs::kMultipleProfilePrefMigration, 0);
2063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true);
206421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Educated guess: Chrome has a bundled Flash version supporting
206521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // clearing LSO data, Chromium hasn't.
206621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#if defined(GOOGLE_CHROME_BUILD)
206721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, true);
206821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#else
206921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  prefs->RegisterBooleanPref(prefs::kClearPluginLSODataEnabled, false);
207021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif
2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
2074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::RegisterUserPrefs(PrefService* prefs) {
2075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterStringPref(prefs::kHomePage,
2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            chrome::kChromeUINewTabURL);
2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, true);
2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kShowHomeButton, false);
2079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
2080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This really belongs in platform code, but there's no good place to
2081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // initialize it between the time when the AppController is created
2082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (where there's no profile) and the time the controller gets another
2083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // crack at the start of the main event loop. By that time, BrowserInit
2084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // has already created the browser window, and it's too late: we need the
2085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // pref to be already initialized. Doing it here also saves us from having
2086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to hard-code pref registration in the several unit tests that use
2087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this preference.
2088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kConfirmToQuitEnabled, false);
2089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar, true);
2090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kDeleteBrowsingHistory, true);
2092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kDeleteDownloadHistory, true);
2093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kDeleteCache, true);
2094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kDeleteCookies, true);
2095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kDeletePasswords, false);
2096731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  prefs->RegisterBooleanPref(prefs::kDeleteFormData, false);
2097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterIntegerPref(prefs::kDeleteTimePeriod, 0);
2098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kCheckDefaultBrowser, true);
2099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kShowOmniboxSearchHint, true);
2100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop, true);
2101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu, true);
2102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar, true);
2103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kUseVerticalTabs, false);
2104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kEnableTranslate, true);
2105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kEnableBookmarkBar, true);
21063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->RegisterBooleanPref(prefs::kRemotingHasSetupCompleted, false);
21073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  prefs->RegisterStringPref(prefs::kCloudPrintEmail, std::string());
210872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterBooleanPref(prefs::kCloudPrintProxyEnabled, true);
2109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  prefs->RegisterBooleanPref(prefs::kDevToolsDisabled, false);
211072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterBooleanPref(prefs::kIncognitoEnabled, true);
211172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterIntegerPref(prefs::kDevToolsSplitLocation, -1);
211272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterDictionaryPref(prefs::kBrowserWindowPlacement);
211372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  prefs->RegisterDictionaryPref(prefs::kPreferencesWindowPlacement);
2114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We need to register the type of these preferences in order to query
2115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // them even though they're typically only controlled via policy or command
2116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // line switches.
2117ac1e49eb6695f711d72215fcdf9388548942a00dBen Murdoch  prefs->RegisterBooleanPref(prefs::kDisable3DAPIs, false);
2118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kPluginsAllowOutdated, false);
2119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true);
2120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  prefs->RegisterBooleanPref(prefs::kEnableReferrers, true);
21213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
21223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static
21243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Browser::RunUnloadEventsHelper(TabContents* contents) {
21253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If the TabContents is not connected yet, then there's no unload
21263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // handler we can fire even if the TabContents has an unload listener.
21273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // One case where we hit this is in a tab that has an infinite loop
21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // before load.
2129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (contents->NeedToFireBeforeUnload()) {
21303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // If the page has unload listeners, then we tell the renderer to fire
21313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // them. Once they have fired, we'll get a message back saying whether
21323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // to proceed closing the page or not, which sends us back to this method
2133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // with the NeedToFireBeforeUnload bit cleared.
21343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    contents->render_view_host()->FirePageBeforeUnload(false);
21353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
21363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
21373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return false;
2138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
2141c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser* Browser::GetBrowserForController(
2142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NavigationController* controller, int* index_result) {
2143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BrowserList::const_iterator it;
2144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (it = BrowserList::begin(); it != BrowserList::end(); ++it) {
21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    int index = (*it)->tab_handler_->GetTabStripModel()->GetIndexOfController(
21463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        controller);
2147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (index != TabStripModel::kNoTab) {
2148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (index_result)
2149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        *index_result = index;
2150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return *it;
2151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
2152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
2155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ExecuteCommandWithDisposition(
2158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int id, WindowOpenDisposition disposition) {
2159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No commands are enabled if there is not yet any selected tab.
2160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(pkasting): It seems like we should not need this, because either
2161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // most/all commands should not have been enabled yet anyway or the ones that
2162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // are enabled should be global, or safe themselves against having no selected
2163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // tab.  However, Ben says he tried removing this before and got lots of
2164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // crashes, e.g. from Windows sending WM_COMMANDs at random times during
2165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window construction.  This probably could use closer examination someday.
2166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!GetSelectedTabContentsWrapper())
2167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command "
2170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                << id;
2171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If command execution is blocked then just record the command and return.
2173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (block_command_execution_) {
2174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We actually only allow no more than one blocked command, otherwise some
2175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // commands maybe lost.
2176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(last_blocked_command_id_, -1);
2177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    last_blocked_command_id_ = id;
2178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    last_blocked_command_disposition_ = disposition;
2179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The order of commands in this switch statement must match the function
2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // declaration order in browser.h!
2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (id) {
2185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Navigation commands
2186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_BACK:                  GoBack(disposition);              break;
2187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FORWARD:               GoForward(disposition);           break;
2188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_RELOAD:                Reload(disposition);              break;
2189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_RELOAD_IGNORING_CACHE: ReloadIgnoringCache(disposition); break;
2190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_HOME:                  Home(disposition);                break;
2191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_OPEN_CURRENT_URL:      OpenCurrentURL();                 break;
2192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_STOP:                  Stop();                           break;
2193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     // Window management commands
2195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_NEW_WINDOW:            NewWindow();                      break;
2196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_NEW_INCOGNITO_WINDOW:  NewIncognitoWindow();             break;
2197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CLOSE_WINDOW:          CloseWindow();                    break;
2198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_NEW_TAB:               NewTab();                         break;
2199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CLOSE_TAB:             CloseTab();                       break;
2200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_NEXT_TAB:       SelectNextTab();                  break;
2201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_PREVIOUS_TAB:   SelectPreviousTab();              break;
22023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case IDC_TABPOSE:               OpenTabpose();                    break;
2203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_MOVE_TAB_NEXT:         MoveTabNext();                    break;
2204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_MOVE_TAB_PREVIOUS:     MoveTabPrevious();                break;
2205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_0:
2206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_1:
2207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_2:
2208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_3:
2209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_4:
2210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_5:
2211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_6:
2212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_TAB_7:          SelectNumberedTab(id - IDC_SELECT_TAB_0);
2213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                                      break;
2214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SELECT_LAST_TAB:       SelectLastTab();                  break;
2215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_DUPLICATE_TAB:         DuplicateTab();                   break;
2216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_RESTORE_TAB:           RestoreTab();                     break;
2217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_COPY_URL:              WriteCurrentURLToClipboard();     break;
2218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_AS_TAB:           ConvertPopupToTabbedBrowser();    break;
2219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FULLSCREEN:            ToggleFullscreenMode();           break;
2220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_EXIT:                  Exit();                           break;
2221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_TOGGLE_VERTICAL_TABS:  ToggleUseVerticalTabs();          break;
2222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
2223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SEARCH:                Search();                         break;
222421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay();            break;
2225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Page-related commands
2228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SAVE_PAGE:             SavePage();                       break;
2229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_BOOKMARK_PAGE:         BookmarkCurrentPage();            break;
2230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_BOOKMARK_ALL_TABS:     BookmarkAllTabs();                break;
223121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case IDC_VIEW_SOURCE:           ViewSelectedSource();             break;
2232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_EMAIL_PAGE_LOCATION:   EmailPageLocation();              break;
2233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_PRINT:                 Print();                          break;
2234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_AUTO_DETECT:  ToggleEncodingAutoDetect();       break;
2235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_UTF8:
2236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_UTF16LE:
2237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88591:
2238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1252:
2239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_GBK:
2240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_GB18030:
2241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_BIG5HKSCS:
2242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_BIG5:
2243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_KOREAN:
2244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_SHIFTJIS:
2245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO2022JP:
2246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_EUCJP:
2247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_THAI:
2248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO885915:
2249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_MACINTOSH:
2250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88592:
2251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1250:
2252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88595:
2253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1251:
2254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_KOI8R:
2255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_KOI8U:
2256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88597:
2257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1253:
2258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88594:
2259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO885913:
2260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1257:
2261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88593:
2262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO885910:
2263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO885914:
2264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO885916:
2265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1254:
2266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88596:
2267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1256:
2268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88598:
2269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_ISO88598I:
2270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1255:
2271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ENCODING_WINDOWS1258:  OverrideEncoding(id);             break;
2272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Clipboard commands
2274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CUT:                   Cut();                            break;
2275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_COPY:                  Copy();                           break;
2276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_PASTE:                 Paste();                          break;
2277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Find-in-page
2279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FIND:                  Find();                           break;
2280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FIND_NEXT:             FindNext();                       break;
2281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FIND_PREVIOUS:         FindPrevious();                   break;
2282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Zoom
2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ZOOM_PLUS:             Zoom(PageZoom::ZOOM_IN);          break;
2285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ZOOM_NORMAL:           Zoom(PageZoom::RESET);            break;
2286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_ZOOM_MINUS:            Zoom(PageZoom::ZOOM_OUT);         break;
2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Focus various bits of UI
2289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_TOOLBAR:         FocusToolbar();                   break;
2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_LOCATION:        FocusLocationBar();               break;
2291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_SEARCH:          FocusSearch();                    break;
2292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_MENU_BAR:        FocusAppMenu();                   break;
2293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_BOOKMARKS:       FocusBookmarksToolbar();          break;
2294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_CHROMEOS_STATUS: FocusChromeOSStatus();            break;
2295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_NEXT_PANE:       FocusNextPane();                  break;
2296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_FOCUS_PREVIOUS_PANE:   FocusPreviousPane();              break;
2297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Show various bits of UI
2299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_OPEN_FILE:             OpenFile();                       break;
2300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CREATE_SHORTCUTS:      OpenCreateShortcutsDialog();      break;
2301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_DEV_TOOLS:             ToggleDevToolsWindow(
2302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        DEVTOOLS_TOGGLE_ACTION_NONE);
2303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    break;
2304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_DEV_TOOLS_CONSOLE:     ToggleDevToolsWindow(
2305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
2306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    break;
2307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_DEV_TOOLS_INSPECT:     ToggleDevToolsWindow(
2308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        DEVTOOLS_TOGGLE_ACTION_INSPECT);
2309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    break;
231072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case IDC_TASK_MANAGER:          OpenTaskManager(false);           break;
231172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case IDC_VIEW_BACKGROUND_PAGES: OpenTaskManager(true);            break;
2312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    case IDC_FEEDBACK:              OpenBugReportDialog();            break;
2313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_BOOKMARK_BAR:     ToggleBookmarkBar();              break;
231572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case IDC_PROFILING_ENABLED:     Profiling::Toggle();              break;
2316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_BOOKMARK_MANAGER: OpenBookmarkManager();            break;
2318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_APP_MENU:         ShowAppMenu();                    break;
2319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_HISTORY:          ShowHistoryTab();                 break;
2320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SHOW_DOWNLOADS:        ShowDownloadsTab();               break;
2321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_MANAGE_EXTENSIONS:     ShowExtensionsTab();              break;
2322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SYNC_BOOKMARKS:        OpenSyncMyBookmarksDialog();      break;
2323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_OPTIONS:               OpenOptionsDialog();              break;
2324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case IDC_EDIT_SEARCH_ENGINES:   OpenSearchEngineOptionsDialog();  break;
2325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_VIEW_PASSWORDS:        OpenPasswordManager();            break;
2326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_CLEAR_BROWSING_DATA:   OpenClearBrowsingDataDialog();    break;
2327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_IMPORT_SETTINGS:       OpenImportSettingsDialog();       break;
23283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case IDC_ABOUT:                 OpenAboutChromeDialog();          break;
23293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case IDC_UPGRADE_DIALOG:        OpenUpdateChromeDialog();         break;
2330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    case IDC_VIEW_INCOMPATIBILITIES: ShowAboutConflictsTab();         break;
2331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_HELP_PAGE:             OpenHelpTab();                    break;
2332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
2333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case IDC_FILE_MANAGER:          OpenFileManager();                break;
2334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_SYSTEM_OPTIONS:        OpenSystemOptionsDialog();        break;
2335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case IDC_INTERNET_OPTIONS:      OpenInternetOptionsDialog();      break;
23363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case IDC_LANGUAGE_OPTIONS:      OpenLanguageOptionsDialog();      break;
2337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
2340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      LOG(WARNING) << "Received Unimplemented Command: " << id;
2341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
2342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Browser::ExecuteCommandIfEnabled(int id) {
234621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (command_updater_.SupportsCommand(id) &&
234721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      command_updater_.IsCommandEnabled(id)) {
234821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ExecuteCommand(id);
234921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return true;
235021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
235121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return false;
235221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
235321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
235472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool Browser::IsReservedCommandOrKey(int command_id,
235572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                     const NativeWebKeyboardEvent& event) {
235672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_CHROMEOS)
235772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Chrome OS's top row of keys produces F1-10.  Make sure that web pages
235872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // aren't able to block Chrome from performing the standard actions for F1-F4
235972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // (F5-7 are grabbed by other X clients and hence don't need this protection,
236072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // and F8-10 are handled separately in Chrome via a GDK event filter, but
236172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // let's future-proof this).
236272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::KeyboardCode key_code =
236372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      static_cast<ui::KeyboardCode>(event.windowsKeyCode);
236472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (key_code == ui::VKEY_F1 ||
236572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F2 ||
236672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F3 ||
236772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F4 ||
236872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F5 ||
236972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F6 ||
237072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F7 ||
237172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F8 ||
237272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F9 ||
237372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      key_code == ui::VKEY_F10) {
237472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
237572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
237672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
237772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return command_id == IDC_CLOSE_TAB ||
2379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_CLOSE_WINDOW ||
2380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_NEW_INCOGNITO_WINDOW ||
2381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_NEW_TAB ||
2382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_NEW_WINDOW ||
2383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_RESTORE_TAB ||
2384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_SELECT_NEXT_TAB ||
2385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_SELECT_PREVIOUS_TAB ||
23863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         command_id == IDC_TABPOSE ||
2387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_EXIT ||
2388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         command_id == IDC_SEARCH;
2389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SetBlockCommandExecution(bool block) {
2392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  block_command_execution_ = block;
2393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (block) {
2394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    last_blocked_command_id_ = -1;
2395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    last_blocked_command_disposition_ = CURRENT_TAB;
2396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint Browser::GetLastBlockedCommand(WindowOpenDisposition* disposition) {
2400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (disposition)
2401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *disposition = last_blocked_command_disposition_;
2402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return last_blocked_command_id_;
2403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::UpdateUIForNavigationInTab(TabContentsWrapper* contents,
2406731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         PageTransition::Type transition,
2407731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         bool user_initiated) {
2408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  tabstrip_model()->TabNavigating(contents, transition);
2409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool contents_is_selected = contents == GetSelectedTabContentsWrapper();
2411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (user_initiated && contents_is_selected && window()->GetLocationBar()) {
2412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Forcibly reset the location bar if the url is going to change in the
2413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // current tab, since otherwise it won't discard any ongoing user edits,
2414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // since it doesn't realize this is a user-initiated action.
2415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    window()->GetLocationBar()->Revert();
2416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (GetStatusBubble())
2419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    GetStatusBubble()->Hide();
2420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Update the location bar. This is synchronous. We specifically don't
2422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // update the load state since the load hasn't started yet and updating it
2423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // will put it out of sync with the actual state like whether we're
2424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // displaying a favicon, which controls the throbber. If we updated it here,
2425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // the throbber will show the default favicon for a split second when
2426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // navigating away from the new tab page.
2427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ScheduleUIUpdate(contents->tab_contents(), TabContents::INVALIDATE_URL);
2428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2429731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (contents_is_selected)
2430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    contents->tab_contents()->Focus();
2431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2432731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2433731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickGURL Browser::GetHomePage() const {
2434731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // --homepage overrides any preferences.
2435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2436731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (command_line.HasSwitch(switches::kHomePage)) {
2437513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // TODO(evanm): clean up usage of DIR_CURRENT.
2438513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    //   http://code.google.com/p/chromium/issues/detail?id=60630
2439513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // For now, allow this code to call getcwd().
2440513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::ThreadRestrictions::ScopedAllowIO allow_io;
2441513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    FilePath browser_directory;
2443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    PathService::Get(base::DIR_CURRENT, &browser_directory);
2444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    GURL home_page(URLFixerUpper::FixupRelativeFile(browser_directory,
2445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        command_line.GetSwitchValuePath(switches::kHomePage)));
2446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (home_page.is_valid())
2447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return home_page;
2448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (profile_->GetPrefs()->GetBoolean(prefs::kHomePageIsNewTabPage))
2451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return GURL(chrome::kChromeUINewTabURL);
2452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  GURL home_page(URLFixerUpper::FixupURL(
2453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      profile_->GetPrefs()->GetString(prefs::kHomePage),
2454731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      std::string()));
2455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!home_page.is_valid())
2456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return GURL(chrome::kChromeUINewTabURL);
2457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return home_page;
2458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Browser, PageNavigator implementation:
2462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
24633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::OpenURL(const GURL& url, const GURL& referrer,
24643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      WindowOpenDisposition disposition,
24653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                      PageTransition::Type transition) {
24663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  OpenURLFromTab(NULL, url, referrer, disposition, transition);
24673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick///////////////////////////////////////////////////////////////////////////////
2470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, CommandUpdater::CommandUpdaterDelegate implementation:
2471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ExecuteCommand(int id) {
2473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExecuteCommandWithDisposition(id, CURRENT_TAB);
2474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
24773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Browser, TabHandlerDelegate implementation:
24783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24793345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickProfile* Browser::GetProfile() const {
24803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return profile();
24813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24833345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBrowser* Browser::AsBrowser() {
24843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return this;
24853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick///////////////////////////////////////////////////////////////////////////////
2488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, TabStripModelDelegate implementation:
2489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::AddBlankTab(bool foreground) {
2491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return AddBlankTabAt(-1, foreground);
2492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2494201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::AddBlankTabAt(int index, bool foreground) {
2495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Time new tab page creation time.  We keep track of the timing data in
2496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents, but we want to include the time it takes to create the
2497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TabContents object too.
2498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
2499513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::NavigateParams params(this, GURL(chrome::kChromeUINewTabURL),
2500513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                 PageTransition::TYPED);
2501513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.disposition = foreground ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
2502513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.tabstrip_index = index;
2503513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::Navigate(&params);
2504201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  params.target_contents->tab_contents()->set_new_tab_start_time(
2505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      new_tab_start_time);
2506513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  return params.target_contents;
2507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochBrowser* Browser::CreateNewStripWithContents(
2510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* detached_contents,
2511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const gfx::Rect& window_bounds,
2512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const DockInfo& dock_info,
2513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    bool maximize) {
2514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(CanSupportWindowFeature(FEATURE_TABSTRIP));
2515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect new_window_bounds = window_bounds;
2517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (dock_info.GetNewWindowBounds(&new_window_bounds, &maximize))
2518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    dock_info.AdjustOtherWindowBounds();
2519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create an empty new browser window the same size as the old one.
2521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Browser* browser = new Browser(TYPE_NORMAL, profile_);
2522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->set_override_bounds(new_window_bounds);
2523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->set_maximized_state(
2524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      maximize ? MAXIMIZED_STATE_MAXIMIZED : MAXIMIZED_STATE_UNMAXIMIZED);
2525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser->InitBrowserWindow();
2526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  browser->tabstrip_model()->AppendTabContents(detached_contents, true);
2527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the loading state is updated correctly, otherwise the throbber
2528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // won't start if the page is loading.
2529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  browser->LoadingStateChanged(detached_contents->tab_contents());
2530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
2531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint Browser::GetDragActions() const {
25343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return TabStripModelDelegate::TAB_TEAROFF_ACTION | (tab_count() > 1 ?
25353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TabStripModelDelegate::TAB_MOVE_ACTION : 0);
2536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::CreateTabContentsForURL(
2539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url, const GURL& referrer, Profile* profile,
2540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PageTransition::Type transition, bool defer_load,
2541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SiteInstance* instance) const {
2542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents = TabContentsFactory(profile, instance,
25433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      MSG_ROUTING_NONE,
2544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      GetSelectedTabContents(), NULL);
2545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!defer_load) {
2546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Load the initial URL before adding the new tab contents to the tab strip
2547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // so that the tab contents has navigation state.
2548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    contents->controller().LoadURL(url, referrer, transition);
2549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return contents;
2552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanDuplicateContentsAt(int index) {
2555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController& nc = GetTabContentsAt(index)->controller();
2556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return nc.tab_contents() && nc.GetLastCommittedEntry();
2557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::DuplicateContentsAt(int index) {
2560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* contents = GetTabContentsWrapperAt(index);
256121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  CHECK(contents);
256221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  TabContentsWrapper* contents_dupe = contents->Clone();
25633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  TabContents* new_contents = contents_dupe->tab_contents();
25643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
25653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  bool pinned = false;
25663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
25673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // If this is a tabbed browser, just create a duplicate tab inside the same
25683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // window next to the tab being duplicated.
25693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int index = tab_handler_->GetTabStripModel()->
25703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        GetIndexOfTabContents(contents);
25713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    pinned = tab_handler_->GetTabStripModel()->IsTabPinned(index);
2572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int add_types = TabStripModel::ADD_ACTIVE |
25733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        TabStripModel::ADD_INHERIT_GROUP |
25743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        (pinned ? TabStripModel::ADD_PINNED : 0);
25753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
25763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                          contents_dupe,
25773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                          add_types);
25783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  } else {
25793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    Browser* browser = NULL;
25803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (type_ & TYPE_APP) {
2581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      CHECK_EQ((type_ & TYPE_POPUP), 0);
2582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      CHECK_NE(type_, TYPE_APP_PANEL);
25833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      browser = Browser::CreateForApp(app_name_, gfx::Size(), profile_,
25843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                      false);
25853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else if (type_ == TYPE_POPUP) {
25863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      browser = Browser::CreateForType(TYPE_POPUP, profile_);
25873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
25883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
25893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // Preserve the size of the original window. The new window has already
25903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // been given an offset by the OS, so we shouldn't copy the old bounds.
25913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    BrowserWindow* new_window = browser->window();
25923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
25933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                          window()->GetRestoredBounds().size()));
25943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
259572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // We need to show the browser now.  Otherwise ContainerWin assumes the
25963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // TabContents is invisible and won't size it.
25973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    browser->window()->Show();
25983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
25993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // The page transition below is only for the purpose of inserting the tab.
26003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    browser->AddTab(contents_dupe, PageTransition::LINK);
26013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
26023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
26033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (profile_->HasSessionService()) {
26043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    SessionService* session_service = profile_->GetSessionService();
26053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (session_service)
26063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      session_service->TabRestored(&new_contents->controller(), pinned);
26073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
2608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseFrameAfterDragSession() {
2611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) || defined(OS_LINUX)
2612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is scheduled to run after we return to the message loop because
2613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // otherwise the frame will think the drag session is still active and ignore
2614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the request.
2615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(port): figure out what is required here in a cross-platform world
2616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostTask(
2617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
2618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2621201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::CreateHistoricalTab(TabContentsWrapper* contents) {
2622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't create historical tabs for incognito windows or windows without
2623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // profiles.
2624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!profile() || profile()->IsOffTheRecord() ||
2625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !profile()->GetTabRestoreService()) {
2626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only create historical tab entries for tabbed browser windows.
2630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
2631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile()->GetTabRestoreService()->CreateHistoricalTab(
2632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &contents->controller(),
2633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        tab_handler_->GetTabStripModel()->GetIndexOfTabContents(contents));
2634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2637201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Browser::RunUnloadListenerBeforeClosing(TabContentsWrapper* contents) {
2638201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return Browser::RunUnloadEventsHelper(contents->tab_contents());
2639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanReloadContents(TabContents* source) const {
2642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return type() != TYPE_DEVTOOLS;
2643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanCloseContentsAt(int index) {
2646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!CanCloseTab())
2647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
26483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tab_handler_->GetTabStripModel()->count() > 1)
2649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
2650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We are closing the last tab for this browser. Make sure to check for
2651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in-progress downloads.
2652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that the next call when it returns false will ask the user for
2653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // confirmation before closing the browser if the user decides so.
2654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return CanCloseWithInProgressDownloads();
2655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanBookmarkAllTabs() const {
2658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkModel* model = profile()->GetBookmarkModel();
2659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (model && model->IsLoaded()) &&
2660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         tab_count() > 1 &&
2661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         edit_bookmarks_enabled_.GetValue();
2662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::BookmarkAllTabs() {
2665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkModel* model = profile()->GetBookmarkModel();
2666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(model && model->IsLoaded());
2667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkEditor::EditDetails details;
2669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  details.type = BookmarkEditor::EditDetails::NEW_FOLDER;
2670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bookmark_utils::GetURLsForOpenTabs(this, &(details.urls));
2671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!details.urls.empty());
2672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BookmarkEditor::Show(window()->GetNativeHandle(), profile_,
2674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       model->GetParentForNewNodes(),  details,
2675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       BookmarkEditor::SHOW_TREE);
2676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::CanCloseTab() const {
2679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabCloseableStateWatcher* watcher =
2680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_browser_process->tab_closeable_state_watcher();
2681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !watcher || watcher->CanCloseTab(this);
2682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ToggleUseVerticalTabs() {
2685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  use_vertical_tabs_.SetValue(!UseVerticalTabs());
2686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UseVerticalTabsChanged();
2687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Browser::LargeIconsPermitted() const {
26903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
26913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // for those windows, we already have a big icon in the top-left outside any
26923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // tab. Having big tab icons too looks kinda redonk.
269321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return true;
26943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
26953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
2697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, TabStripModelObserver implementation:
2698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2699201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabInsertedAt(TabContentsWrapper* contents,
2700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            int index,
2701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            bool foreground) {
2702dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetAsDelegate(contents, this);
2703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  contents->controller().SetWindowID(session_id());
2704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Each renderer holds the ID of the window that hosts it. Notify the
2706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // renderer that the window ID changed.
2707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  contents->render_view_host()->UpdateBrowserWindowId(
2708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      contents->controller().window_id().id());
2709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncHistoryWithTabs(index);
2711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the loading state is updated correctly, otherwise the throbber
2713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // won't start if the page is loading.
2714201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  LoadingStateChanged(contents->tab_contents());
2715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the tab crashes in the beforeunload or unload handler, it won't be
2717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // able to ack. But we know we can close it.
2718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
2719201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 Source<TabContentsWrapper>(contents));
2720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2722731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::TabClosingAt(TabStripModel* tab_strip_model,
2723201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                           TabContentsWrapper* contents,
2724731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           int index) {
2725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
2726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::TAB_CLOSING,
2727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<NavigationController>(&contents->controller()),
2728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::NoDetails());
2729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sever the TabContents' connection back to us.
2731dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetAsDelegate(contents, NULL);
2732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2734201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabDetachedAt(TabContentsWrapper* contents, int index) {
2735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabDetachedAtImpl(contents, index, DETACH_TYPE_DETACH);
2736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2738dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Browser::TabDeselected(TabContentsWrapper* contents) {
2739731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (instant())
2740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    instant()->DestroyPreviewContents();
27413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save what the user's currently typing, so it can be restored when we
2743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // switch back to this tab.
2744201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  window_->GetLocationBar()->SaveStateToContents(contents->tab_contents());
2745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2747201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabSelectedAt(TabContentsWrapper* old_contents,
2748201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            TabContentsWrapper* new_contents,
2749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            int index,
2750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            bool user_gesture) {
2751dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (old_contents == new_contents)
2752dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
2753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // On some platforms we want to automatically reload tabs that are
275572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // killed when the user selects them.
275672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (user_gesture && new_contents->tab_contents()->crashed_status() ==
275772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        base::TERMINATION_STATUS_PROCESS_WAS_KILLED) {
275872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
275972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (parsed_command_line.HasSwitch(switches::kReloadKilledTabs)) {
276072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Reload(CURRENT_TAB);
276172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return;
276272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
276372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
276472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we have any update pending, do it now.
2766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!chrome_updater_factory_.empty() && old_contents)
2767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessPendingUIUpdates();
2768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Propagate the profile to the location bar.
2770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateToolbar(true);
2771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Update reload/stop state.
2773201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  UpdateReloadStopState(new_contents->tab_contents()->is_loading(), true);
2774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Update commands to reflect current state.
2776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCommandsForTabState();
2777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the status bubble.
2779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StatusBubble* status_bubble = GetStatusBubble();
2780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (status_bubble) {
2781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_bubble->Hide();
2782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Show the loading state (if any).
2784dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    status_bubble->SetStatus(GetSelectedTabContentsWrapper()->GetStatusText());
2785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (HasFindBarController()) {
278872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    find_bar_controller_->ChangeTabContents(new_contents);
2789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true);
2790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Update sessions. Don't force creation of sessions. If sessions doesn't
2793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // exist, the change will be picked up by sessions when created.
2794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile_->HasSessionService()) {
2795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SessionService* session_service = profile_->GetSessionService();
27963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (session_service && !tab_handler_->GetTabStripModel()->closing_all()) {
2797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      session_service->SetSelectedTabInWindow(
2798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          session_id(), tab_handler_->GetTabStripModel()->active_index());
2799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
2800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2803201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabMoved(TabContentsWrapper* contents,
2804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       int from_index,
2805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       int to_index) {
2806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(from_index >= 0 && to_index >= 0);
2807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Notify the history service.
2808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SyncHistoryWithTabs(std::min(from_index, to_index));
2809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
281172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::TabReplacedAt(TabStripModel* tab_strip_model,
281272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            TabContentsWrapper* old_contents,
2813201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                            TabContentsWrapper* new_contents,
2814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                            int index) {
2815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabDetachedAtImpl(old_contents, index, DETACH_TYPE_REPLACE);
2816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabInsertedAt(new_contents, index,
2817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                (index == tab_handler_->GetTabStripModel()->active_index()));
2818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int entry_count = new_contents->controller().entry_count();
2820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (entry_count > 0) {
2821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Send out notification so that observers are updated appropriately.
2822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    new_contents->controller().NotifyEntryChanged(
2823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new_contents->controller().GetEntryAtIndex(entry_count - 1),
2824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        entry_count - 1);
2825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2826731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2827731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SessionService* session_service = profile()->GetSessionService();
2828731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (session_service) {
2829731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // The new_contents may end up with a different navigation stack. Force
2830731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // the session service to update itself.
2831731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    session_service->TabRestored(
2832731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        &new_contents->controller(),
2833731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        tab_handler_->GetTabStripModel()->IsTabPinned(index));
2834731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
283572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
283672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
283772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (devtools_manager)  // NULL in unit tests.
283872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    devtools_manager->TabReplaced(old_contents, new_contents);
2839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2841201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabPinnedStateChanged(TabContentsWrapper* contents, int index) {
2842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!profile()->HasSessionService())
2843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SessionService* session_service = profile()->GetSessionService();
2845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (session_service) {
2846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    session_service->SetPinnedState(
2847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        session_id(),
2848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GetTabContentsAt(index)->controller().session_id(),
28493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        tab_handler_->GetTabStripModel()->IsTabPinned(index));
2850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::TabStripEmpty() {
2854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Close the frame after we return to the message loop (not immediately,
2855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // otherwise it will destroy this object before the stack has a chance to
2856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // cleanly unwind.)
2857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note: This will be called several times if TabStripEmpty is called several
2858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //       times. This is because it does not close the window if tabs are
2859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //       still present.
2860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // NOTE: If you change to be immediate (no invokeLater) then you'll need to
2861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //       update BrowserList::CloseAllBrowsers.
2862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->PostTask(
2863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FROM_HERE, method_factory_.NewRunnableMethod(&Browser::CloseFrame));
2864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
2867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, TabContentsDelegate implementation:
2868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OpenURLFromTab(TabContents* source,
2870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const GURL& url,
2871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const GURL& referrer,
2872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             WindowOpenDisposition disposition,
2873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             PageTransition::Type transition) {
2874513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::NavigateParams params(this, url, transition);
2875201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  params.source_contents =
2876201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    tabstrip_model()->GetTabContentsAt(
2877201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      tabstrip_model()->GetWrapperIndex(source));
2878513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.referrer = referrer;
2879513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.disposition = disposition;
2880513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  params.tabstrip_add_types = TabStripModel::ADD_NONE;
2881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  params.window_action = browser::NavigateParams::SHOW_WINDOW;
2882513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  browser::Navigate(&params);
2883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::NavigationStateChanged(const TabContents* source,
2886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     unsigned changed_flags) {
2887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only update the UI when something visible has changed.
2888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags)
2889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ScheduleUIUpdate(source, changed_flags);
2890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't schedule updates to commands since they will only change once per
2892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // navigation, so we don't have to worry about flickering.
2893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags & TabContents::INVALIDATE_URL)
2894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateCommandsForTabState();
2895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::AddNewContents(TabContents* source,
2898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             TabContents* new_contents,
2899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             WindowOpenDisposition disposition,
2900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             const gfx::Rect& initial_pos,
2901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             bool user_gesture) {
2902513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // No code for this yet
2903513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(disposition != SAVE_TO_DISK);
2904513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Can't create a new contents for the current tab - invalid case.
2905513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  DCHECK(disposition != CURRENT_TAB);
2906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2907513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // TODO(beng): This belongs behind the platform-specific View interface.
2908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //             That's why it's there. http://crbug.com/78853
2909731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_CHROMEOS)
2910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (disposition == NEW_POPUP) {
2911513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // If the popup is bigger than a given factor of the screen, then
2912513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // turn it into a foreground tab (on chrome os only)
2913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Also check for width or height == 0, which would otherwise indicate
2914513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // a tab sized popup window.
2915513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    GdkScreen* screen = gdk_screen_get_default();
2916513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    int max_width = gdk_screen_get_width(screen) * kPopupMaxWidthFactor;
2917513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    int max_height = gdk_screen_get_height(screen) * kPopupMaxHeightFactor;
2918513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (initial_pos.width() > max_width || initial_pos.width() == 0 ||
2919513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        initial_pos.height() > max_height || initial_pos.height() == 0) {
2920513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      disposition = NEW_FOREGROUND_TAB;
2921731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
2922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2923513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif
2924513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2925201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
2926201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  browser::NavigateParams params(this, wrapper);
2927201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  params.source_contents =
2928201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      tabstrip_model()->GetTabContentsAt(
2929201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          tabstrip_model()->GetWrapperIndex(source));
2930201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  params.disposition = disposition;
2931201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  params.window_bounds = initial_pos;
2932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we create a popup or panel from a non user-gesture, don't activate
2933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the new window / panel.
2934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (disposition == NEW_POPUP && !user_gesture)
2935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    params.window_action = browser::NavigateParams::SHOW_WINDOW_INACTIVE;
2936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else
2937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    params.window_action = browser::NavigateParams::SHOW_WINDOW;
2938201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  browser::Navigate(&params);
2939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ActivateContents(TabContents* contents) {
2942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_handler_->GetTabStripModel()->ActivateTabAt(
2943201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      tab_handler_->GetTabStripModel()->GetWrapperIndex(contents), false);
2944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->Activate();
2945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::DeactivateContents(TabContents* contents) {
29483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  window_->Deactivate();
29493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
29503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::LoadingStateChanged(TabContents* source) {
29523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  window_->UpdateLoadingAnimations(
29533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      tab_handler_->GetTabStripModel()->TabsAreLoading());
2954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->UpdateTitleBar();
2955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2956201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* selected_contents = GetSelectedTabContents();
2957201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (source == selected_contents) {
2958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateReloadStopState(source->is_loading(), false);
29593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (GetStatusBubble()) {
2960dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      GetStatusBubble()->SetStatus(
2961dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          GetSelectedTabContentsWrapper()->GetStatusText());
29623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
29633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!source->is_loading() &&
2965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        pending_web_app_action_ == UPDATE_SHORTCUT) {
2966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Schedule a shortcut update when web application info is available if
2967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // last committed entry is not NULL. Last committed entry could be NULL
2968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // when an interstitial page is injected (e.g. bad https certificate,
2969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // malware site etc). When this happens, we abort the shortcut update.
2970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NavigationEntry* entry = source->controller().GetLastCommittedEntry();
2971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (entry) {
2972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        TabContentsWrapper::GetCurrentWrapperForContents(source)->
2973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            extension_tab_helper()->GetApplicationInfo(entry->page_id());
2974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
2975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        pending_web_app_action_ = NONE;
2976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
2977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
2978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseContents(TabContents* source) {
2982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_attempting_to_close_browser_) {
2983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If we're trying to close the browser, just clear the state related to
2984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // waiting for unload to fire. Don't actually try to close the tab as it
2985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // will go down the slow shutdown path instead of the fast path of killing
2986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // all the renderer processes.
298772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ClearUnloadState(source, true);
2988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
2992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (index == TabStripModel::kNoTab) {
2993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "CloseContents called for tab not in our strip";
2994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
2995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
29963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_handler_->GetTabStripModel()->CloseTabContentsAt(
2997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      index,
2998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
2999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::MoveContents(TabContents* source, const gfx::Rect& pos) {
3002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((type() & TYPE_POPUP) == 0) {
3003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "moving invalid browser type";
3004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->SetBounds(pos);
3007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::DetachContents(TabContents* source) {
3010201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int index = tab_handler_->GetTabStripModel()->GetWrapperIndex(source);
3011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (index >= 0)
30123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tab_handler_->GetTabStripModel()->DetachTabContentsAt(index);
3013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Browser::IsPopup(const TabContents* source) const {
3016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A non-tabbed BROWSER is an unconstrained popup.
3017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !!(type() & TYPE_POPUP);
3018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ContentsMouseEvent(
3021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* source, const gfx::Point& location, bool motion) {
3022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!GetStatusBubble())
3023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (source == GetSelectedTabContents()) {
3026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetStatusBubble()->MouseMoved(location, !motion);
3027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!motion)
30283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetStatusBubble()->SetURL(GURL(), string16());
3029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateTargetURL(TabContents* source, const GURL& url) {
3033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!GetStatusBubble())
3034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (source == GetSelectedTabContents()) {
3037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PrefService* prefs = profile_->GetPrefs();
3038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetStatusBubble()->SetURL(
30393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        url, UTF8ToUTF16(prefs->GetString(prefs::kAcceptLanguages)));
3040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateDownloadShelfVisibility(bool visible) {
3044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetStatusBubble())
3045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GetStatusBubble()->UpdateDownloadShelfVisibility(visible);
3046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::UseVerticalTabs() const {
3049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return use_vertical_tabs_.GetValue();
3050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ContentsZoomChange(bool zoom_in) {
3053731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
3054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OnContentSettingsChange(TabContents* source) {
3057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (source == GetSelectedTabContents()) {
3058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LocationBar* location_bar = window()->GetLocationBar();
3059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (location_bar)
3060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      location_bar->UpdateContentSettingsIcons();
3061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SetTabContentBlocked(TabContents* contents, bool blocked) {
3065201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int index = tabstrip_model()->GetWrapperIndex(contents);
3066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (index == TabStripModel::kNoTab) {
3067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
3068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabstrip_model()->SetTabBlocked(index, blocked);
3071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::TabContentsFocused(TabContents* tab_content) {
3074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->TabContentsFocused(tab_content);
3075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::TakeFocus(bool reverse) {
3078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
3079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::FOCUS_RETURNED_TO_BROWSER,
3080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Source<Browser>(this),
3081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::NoDetails());
3082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
3083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::IsApplication() const {
3086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return (type_ & TYPE_APP) != 0;
3087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ConvertContentsToApplication(TabContents* contents) {
3090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL& url = contents->controller().GetActiveEntry()->url();
30913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string app_name = web_app::GenerateApplicationNameFromURL(url);
309272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RegisterAppPrefs(app_name, contents->profile());
3093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DetachContents(contents);
309521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Browser* app_browser = Browser::CreateForApp(
309621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      app_name, gfx::Size(), profile_, false);
3097201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = new TabContentsWrapper(contents);
3098201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  app_browser->tabstrip_model()->AppendTabContents(wrapper, true);
3099201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
3101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  contents->render_view_host()->SyncRendererPrefs();
3102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  app_browser->window()->Show();
3103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::ShouldDisplayURLField() {
3106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !IsApplication();
3107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::BeforeUnloadFired(TabContents* tab,
3110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                bool proceed,
3111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                bool* proceed_to_fire_unload) {
3112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_attempting_to_close_browser_) {
3113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *proceed_to_fire_unload = proceed;
3114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!proceed)
3115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab->set_closed_by_user_gesture(false);
3116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!proceed) {
3120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CancelWindowClose();
3121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *proceed_to_fire_unload = false;
3122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab->set_closed_by_user_gesture(false);
3123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (RemoveFromSet(&tabs_needing_before_unload_fired_, tab)) {
3127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now that beforeunload has fired, put the tab on the queue to fire
3128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // unload.
3129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tabs_needing_unload_fired_.insert(tab);
3130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProcessPendingTabs();
3131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We want to handle firing the unload event ourselves since we want to
3132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // fire all the beforeunload events before attempting to fire the unload
3133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // events should the user cancel closing the browser.
3134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *proceed_to_fire_unload = false;
3135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  *proceed_to_fire_unload = true;
3139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowHtmlDialog(HtmlDialogUIDelegate* delegate,
3142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             gfx::NativeWindow parent_window) {
3143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ShowHTMLDialog(delegate, parent_window);
3144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SetFocusToLocationBar(bool select_all) {
3147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Two differences between this and FocusLocationBar():
3148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (1) This doesn't get recorded in user metrics, since it's called
3149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //     internally.
3150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (2) This checks whether the location bar can be focused, and if not, clears
3151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //     the focus.  FocusLocationBar() is only reached when the location bar is
3152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //     focusable, but this may be reached at other times, e.g. while in
3153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //     fullscreen mode, where we need to leave focus in a consistent state.
3154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->SetFocusToLocationBar(select_all);
3155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::RenderWidgetShowing() {
3158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->DisableInactiveFrame();
3159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint Browser::GetExtraRenderViewHeight() const {
3162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return window_->GetExtraRenderViewHeight();
3163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Browser::OnStartDownload(DownloadItem* download, TabContents* tab) {
3166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!window())
3167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
3170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't show content browser for extension/theme downloads from gallery.
3171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (download->is_extension_install()) {
317221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ExtensionService* service = profile_->GetExtensionService();
3173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (service && service->IsDownloadFromGallery(download->url(),
3174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                  download->referrer_url())) {
3175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return;
3176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
3177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
3178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Open the Active Downloads ui for chromeos.
3179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ActiveDownloadsUI::OpenPopup(profile_);
3180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
3181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // GetDownloadShelf creates the download shelf if it was not yet created.
3182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->GetDownloadShelf()->AddDownload(new DownloadItemModel(download));
3183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't show the animation for "Save file" downloads.
3185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (download->total_bytes() <= 0)
3186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // For non-theme extensions, we don't show the download animation.
3189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (download->is_extension_install() &&
319021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      !ExtensionService::IsDownloadFromMiniGallery(download->url()))
3191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* current_tab = GetSelectedTabContents();
3194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We make this check for the case of minimized windows, unit tests, etc.
3195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (platform_util::IsVisible(current_tab->GetNativeView()) &&
31963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      ui::Animation::ShouldRenderRichAnimation()) {
3197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DownloadStartedAnimation::Show(current_tab);
3198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
32003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
32013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If the download occurs in a new tab, close it
32023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tab->controller().IsInitialNavigation() &&
32033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetConstrainingContents(tab) == tab && tab_count() > 1) {
32043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CloseContents(tab);
32053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
3206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowPageInfo(Profile* profile,
3209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const GURL& url,
3210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           const NavigationEntry::SSLStatus& ssl,
3211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           bool show_history) {
3212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->ShowPageInfo(profile, url, ssl, show_history);
3213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
321521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid Browser::ViewSourceForTab(TabContents* source, const GURL& page_url) {
321621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(source);
321721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int index = tabstrip_model()->GetWrapperIndex(source);
321821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
321921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ViewSource(wrapper);
322021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
322121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::ViewSourceForFrame(TabContents* source,
3223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 const GURL& frame_url,
3224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 const std::string& frame_content_state) {
3225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(source);
3226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int index = tabstrip_model()->GetWrapperIndex(source);
3227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContentsWrapper* wrapper = tabstrip_model()->GetTabContentsAt(index);
3228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ViewSource(wrapper, frame_url, frame_content_state);
3229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
3232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     bool* is_keyboard_shortcut) {
3233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return window()->PreHandleKeyboardEvent(event, is_keyboard_shortcut);
3234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
3237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->HandleKeyboardEvent(event);
3238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowRepostFormWarningDialog(TabContents *tab_contents) {
3241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->ShowRepostFormWarningDialog(tab_contents);
3242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::ShowContentSettingsPage(ContentSettingsType content_type) {
3245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ShowOptionsTab(
3246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      chrome::kContentSettingsExceptionsSubPage + std::string(kHashMark) +
3247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ContentSettingsHandler::ContentSettingsTypeToGroupName(content_type));
3248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ShowCollectedCookiesDialog(TabContents *tab_contents) {
3251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window()->ShowCollectedCookiesDialog(tab_contents);
3252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Browser::ShouldAddNavigationToHistory(
32553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const history::HistoryAddPageArgs& add_page_args,
32563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NavigationType::Type navigation_type) {
3257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't update history if running as app.
3258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return !IsApplication();
3259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::ContentRestrictionsChanged(TabContents* source) {
3262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateCommandsForContentRestrictionState();
3263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::WorkerCrashed() {
3266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TabContents* tab_contents = GetSelectedTabContents();
3267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!tab_contents)
3268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
3269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_contents->AddInfoBar(new SimpleAlertInfoBarDelegate(tab_contents, NULL,
3270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      l10n_util::GetStringUTF16(IDS_WEBWORKER_CRASHED_PROMPT), true));
3271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen///////////////////////////////////////////////////////////////////////////////
3274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Browser, TabContentsWrapperDelegate implementation:
3275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::URLStarredChanged(TabContentsWrapper* source, bool starred) {
3277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (source == GetSelectedTabContentsWrapper())
3278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    window_->SetStarredState(starred);
3279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OnDidGetApplicationInfo(TabContentsWrapper* source,
3282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      int32 page_id) {
3283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (GetSelectedTabContentsWrapper() != source)
3284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NavigationEntry* entry = source->controller().GetLastCommittedEntry();
3287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry || (entry->page_id() != page_id))
3288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (pending_web_app_action_) {
3291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case CREATE_SHORTCUT: {
3292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      window()->ShowCreateWebAppShortcutsDialog(source);
3293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case UPDATE_SHORTCUT: {
3296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      web_app::UpdateShortcutForTabContents(source);
3297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
3300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
3301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pending_web_app_action_ = NONE;
3305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::OnInstallApplication(TabContentsWrapper* source,
3308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                   const WebApplicationInfo& web_app) {
330921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* extensions_service = profile()->GetExtensionService();
3310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!extensions_service)
3311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
3312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<CrxInstaller> installer(
3314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      new CrxInstaller(extensions_service,
3315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       extensions_service->show_extensions_prompts() ?
3316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                       new ExtensionInstallUI(profile()) : NULL));
3317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  installer->InstallWebApp(web_app);
3318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
3319201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
332072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen///////////////////////////////////////////////////////////////////////////////
3321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Browser, SearchEngineTabHelperDelegate implementation:
3322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Browser::ConfirmSetDefaultSearchProvider(
3324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TabContents* tab_contents,
3325dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TemplateURL* template_url,
3326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    TemplateURLModel* template_url_model) {
3327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  window()->ConfirmSetDefaultSearchProvider(tab_contents, template_url,
3328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                            template_url_model);
3329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
3330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Browser::ConfirmAddSearchProvider(const TemplateURL* template_url,
3332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                       Profile* profile) {
3333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  window()->ConfirmAddSearchProvider(template_url, profile);
3334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
3335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen///////////////////////////////////////////////////////////////////////////////
3337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, SelectFileDialog::Listener implementation:
3338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FileSelected(const FilePath& path, int index, void* params) {
3340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->set_last_selected_directory(path.DirName());
3341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL file_url = net::FilePathToFileURL(path);
3342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!file_url.is_empty())
3343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OpenURL(file_url, GURL(), CURRENT_TAB, PageTransition::TYPED);
3344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, NotificationObserver implementation:
3348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::Observe(NotificationType type,
3350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const NotificationSource& source,
3351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      const NotificationDetails& details) {
3352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
3353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::TAB_CONTENTS_DISCONNECTED:
3354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (is_attempting_to_close_browser_) {
335572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Pass in false so that we delay processing. We need to delay the
335672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // processing as it may close the tab, which is currently on the call
335772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // stack above us.
335872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ClearUnloadState(Source<TabContents>(source).ptr(), false);
3359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
3360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::SSL_VISIBLE_STATE_CHANGED:
3363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // When the current tab's SSL state changes, we need to update the URL
3364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // bar to reflect the new state. Note that it's possible for the selected
3365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // tab contents to be NULL. This is because we listen for all sources
3366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // (NavigationControllers) for convenience, so the notification could
3367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // actually be for a different window while we're doing asynchronous
3368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // closing of this one.
3369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (GetSelectedTabContents() &&
3370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &GetSelectedTabContents()->controller() ==
3371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Source<NavigationController>(source).ptr())
3372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UpdateToolbar(false);
3373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UPDATE_DISABLED: {
3376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Show the UI if the extension was disabled for escalated permissions.
3377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Profile* profile = Source<Profile>(source).ptr();
33783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (profile_->IsSameProfile(profile)) {
337921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        ExtensionService* service = profile->GetExtensionService();
33803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DCHECK(service);
3381513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        const Extension* extension = Details<const Extension>(details).ptr();
33823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (service->extension_prefs()->DidExtensionEscalatePermissions(
33833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                extension->id()))
33843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ShowExtensionDisabledUI(service, profile_, extension);
33853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
3386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case NotificationType::EXTENSION_UNLOADED: {
3390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window()->GetLocationBar()->UpdatePageActions();
3391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Close any tabs from the unloaded extension.
339321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      const Extension* extension =
339421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          Details<UnloadedExtensionInfo>(details)->extension;
33953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      TabStripModel* model = tab_handler_->GetTabStripModel();
33963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      for (int i = model->count() - 1; i >= 0; --i) {
3397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        TabContents* tc = model->GetTabContentsAt(i)->tab_contents();
3398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (tc->GetURL().SchemeIs(chrome::kExtensionScheme) &&
3399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            tc->GetURL().host() == extension->id()) {
3400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CloseTabContents(tc);
3401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
3402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
3403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_PROCESS_TERMINATED: {
3408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window()->GetLocationBar()->InvalidatePageActions();
3409dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      break;
3410dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
3411dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_UNINSTALLED:
3413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    case NotificationType::EXTENSION_LOADED:
3414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window()->GetLocationBar()->UpdatePageActions();
3415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::BROWSER_THEME_CHANGED:
3418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      window()->UserChangedTheme();
3419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_READY_FOR_INSTALL: {
3422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Handle EXTENSION_READY_FOR_INSTALL for last active normal browser.
3423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (BrowserList::FindBrowserWithType(profile(),
3424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           Browser::TYPE_NORMAL,
3425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                           true) != this)
3426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
3427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We only want to show the loading dialog for themes, but we don't want
3429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // to wait until unpack to find out an extension is a theme, so we test
3430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the download_url GURL instead. This means that themes in the extensions
3431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // gallery won't get the loading dialog.
3432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL download_url = *(Details<GURL>(details).ptr());
343321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      if (ExtensionService::IsDownloadFromMiniGallery(download_url))
3434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        window()->ShowThemeInstallBubble();
3435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::PREF_CHANGED: {
3439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& pref_name = *Details<std::string>(details).ptr();
3440731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (pref_name == prefs::kUseVerticalTabs) {
3441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        UseVerticalTabsChanged();
3442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else if (pref_name == prefs::kPrintingEnabled) {
3443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        UpdatePrintingState(0);
3444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else if (pref_name == prefs::kInstantEnabled) {
3445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        if (!InstantController::IsEnabled(profile())) {
3446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          if (instant()) {
3447731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            instant()->DestroyPreviewContents();
3448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            instant_.reset();
3449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            instant_unload_handler_.reset();
3450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          }
3451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        } else {
3452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          CreateInstantIfNecessary();
3453731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        }
3454513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      } else if (pref_name == prefs::kDevToolsDisabled) {
3455513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        UpdateCommandsForDevTools();
3456513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        if (dev_tools_disabled_.GetValue())
3457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          g_browser_process->devtools_manager()->CloseAllClientHosts();
345872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else if (pref_name == prefs::kIncognitoEnabled) {
345972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        break;  // No further action is required.
3460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else if (pref_name == prefs::kEditBookmarksEnabled) {
3461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        UpdateCommandsForBookmarkEditing();
3462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      } else {
3463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
3464731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
3465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
3466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
3469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED() << "Got a notification we didn't register for.";
3470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, ProfileSyncServiceObserver implementation:
3475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::OnStateChanged() {
3477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile_->GetProfileSyncService());
3478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
3480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool show_main_ui = (type() == TYPE_NORMAL) && !window_->IsFullscreen();
3481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
3482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool show_main_ui = (type() == TYPE_NORMAL);
3483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
3486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      show_main_ui && profile_->IsSyncAccessible());
3487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3490731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Browser, InstantDelegate implementation:
34913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
34924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid Browser::PrepareForInstant() {
34934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  window_->PrepareForInstant();
34944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
34954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3496201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::ShowInstant(TabContentsWrapper* preview_contents) {
3497201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK(instant_->tab_contents() == GetSelectedTabContentsWrapper());
3498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window_->ShowInstant(preview_contents);
34993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
35003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3501731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::HideInstant() {
3502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  window_->HideInstant(instant_->is_active());
35033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
35043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::CommitInstant(TabContentsWrapper* preview_contents) {
3506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* tab_contents = instant_->tab_contents();
3507201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int index =
3508201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      tab_handler_->GetTabStripModel()->GetIndexOfTabContents(tab_contents);
3509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DCHECK_NE(TabStripModel::kNoTab, index);
35103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TabStripModel takes ownership of preview_contents.
3511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_handler_->GetTabStripModel()->ReplaceTabContentsAt(
3512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      index, preview_contents);
3513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // InstantUnloadHandler takes ownership of tab_contents.
3514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  instant_unload_handler_->RunUnloadListenersOrDestroy(tab_contents, index);
3515dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
3516dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  GURL url = preview_contents->tab_contents()->GetURL();
3517dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(profile_->GetExtensionService());
3518dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (profile_->GetExtensionService()->IsInstalledApp(url)) {
3519dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    UMA_HISTOGRAM_ENUMERATION(extension_misc::kAppLaunchHistogram,
3520dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                              extension_misc::APP_LAUNCH_OMNIBOX_INSTANT,
3521dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                              extension_misc::APP_LAUNCH_BUCKET_BOUNDARY);
3522dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
35233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
35243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::SetSuggestedText(const string16& text,
3526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               InstantCompleteBehavior behavior) {
3527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  window()->GetLocationBar()->SetSuggestedText(text, behavior);
35283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
35293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3530731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickgfx::Rect Browser::GetInstantBounds() {
3531731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return window()->GetInstantBounds();
35323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
35333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
35343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick///////////////////////////////////////////////////////////////////////////////
3535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Browser, protected:
3536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBrowserWindow* Browser::CreateBrowserWindow() {
3538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (type() == Browser::TYPE_APP_PANEL &&
3539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels))
3540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return PanelManager::GetInstance()->CreatePanel(this);
3541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return BrowserWindow::CreateBrowserWindow(this);
3543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen///////////////////////////////////////////////////////////////////////////////
3547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Command and state updating (private):
3548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::InitCommandState() {
3550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // All browser commands whose state isn't set automagically some other way
3551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // (like Back & Forward with initial page load) must have their state
3552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // initialized here, otherwise they will be forever disabled.
3553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigation commands
3555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
3556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
3557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Window management commands
3559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_NEW_WINDOW, true);
356072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  command_updater_.UpdateCommandEnabled(IDC_NEW_INCOGNITO_WINDOW,
356172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        incognito_mode_allowed_.GetValue());
3562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
3563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
3564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
3565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
3566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
3567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_EXIT, true);
3568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
3569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page-related commands
3571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true);
3572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true);
3573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true);
3574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true);
3575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true);
3576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true);
3577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true);
3578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true);
3579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true);
3580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true);
3581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true);
3582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true);
3583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true);
3584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true);
3585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true);
3586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true);
3587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true);
3588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true);
3589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true);
3590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true);
3591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true);
3592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true);
3593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true);
3594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true);
3595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true);
3596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true);
3597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true);
3598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true);
3599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true);
3600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true);
3601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true);
3602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true);
3603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true);
3604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true);
3605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true);
3606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true);
3607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true);
3608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true);
3609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true);
3610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Zoom
3612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
3613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
3614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
3615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
3616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show various bits of UI
3618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, true);
3619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
3620513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  UpdateCommandsForDevTools();
3621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, true);
3622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, true);
36233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER,
36243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        browser_defaults::bookmarks_enabled);
3625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
3626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE, true);
3627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true);
3628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
3630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  command_updater_.UpdateCommandEnabled(IDC_FILE_MANAGER, true);
3631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SEARCH, true);
363221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  command_updater_.UpdateCommandEnabled(IDC_SHOW_KEYBOARD_OVERLAY, true);
3633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SYSTEM_OPTIONS, true);
3634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_INTERNET_OPTIONS, true);
3635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* extensions_service = profile()->GetExtensionService();
3638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool enable_extensions =
3639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service && extensions_service->extensions_enabled();
3640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS,
3641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        enable_extensions);
3642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize other commands based on the window type.
3644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool normal_window = type() == TYPE_NORMAL;
3645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool non_devtools_window = type() != TYPE_DEVTOOLS;
3646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigation commands
3648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
3649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Window management commands
36513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN,
36523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      type() != TYPE_APP_PANEL);
3653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
3654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB,
3655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        normal_window);
3656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window);
3657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window);
3658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window);
3659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window);
3660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window);
3661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window);
3662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window);
3663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window);
3664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window);
3665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window);
3666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window);
36673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_MACOSX)
36683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
36693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
3670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Clipboard commands
3672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_COPY_URL, non_devtools_window);
3673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Find-in-page
3675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FIND, non_devtools_window);
3676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, non_devtools_window);
3677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, non_devtools_window);
3678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Autofill
3680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_AUTOFILL_DEFAULT,
3681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        non_devtools_window);
3682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show various bits of UI
3684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
3685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3686513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // The upgrade entry and the view incompatibility entry should always be
3687513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // enabled. Whether they are visible is a separate matter determined on menu
3688513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // show.
36893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true);
3690513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true);
36913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3692201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // View Background Pages entry is always enabled, but is hidden if there are
3693201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // no background pages.
3694201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
3695201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize other commands whose state changes based on fullscreen mode.
3697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateCommandsForFullscreenMode(false);
3698731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3699731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UpdateCommandsForContentRestrictionState();
3700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateCommandsForBookmarkEditing();
3702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateCommandsForTabState() {
3705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabContents* current_tab = GetSelectedTabContents();
370672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
370772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!current_tab || !current_tab_wrapper)  // May be NULL during tab restore.
3708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Navigation commands
3711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController& nc = current_tab->controller();
3712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_BACK, nc.CanGoBack());
3713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_FORWARD, nc.CanGoForward());
3714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RELOAD,
3715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        CanReloadContents(current_tab));
3716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE,
3717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        CanReloadContents(current_tab));
3718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Window management commands
3720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool non_app_window = !(type() & TYPE_APP);
3721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
3722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      non_app_window && CanDuplicateContentsAt(active_index()));
3723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Page-related commands
372572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  window_->SetStarredState(current_tab_wrapper->is_starred());
3726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
3727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      current_tab->controller().CanViewSource());
3728731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
3729731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      current_tab->ShouldDisplayURL() && current_tab->GetURL().is_valid());
3730731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3731731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Changing the encoding is not possible on Chrome-internal webpages.
3732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Instead of using GetURL here, we use url() (which is the "real" url of the
3733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // page) from the NavigationEntry because its reflects their origin rather
3734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // than the display one (returned by GetURL) which may be different (like
3735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // having "view-source:" on the front).
3736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* active_entry = nc.GetActiveEntry();
37373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool is_chrome_internal = (active_entry ?
37383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      active_entry->url().SchemeIs(chrome::kChromeUIScheme) : false);
37393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU,
37403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      !is_chrome_internal && SavePackage::IsSavableContents(
37413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          current_tab->contents_mime_type()));
37423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Show various bits of UI
3744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(pinkerton): Disable app-mode in the model until we implement it
3745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
3746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
3747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
3748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      web_app::IsValidUrl(current_tab->GetURL()));
3749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3750731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3751731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UpdateCommandsForContentRestrictionState();
3752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UpdateCommandsForBookmarkEditing();
37533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
37543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3755731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::UpdateCommandsForContentRestrictionState() {
3756731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int restrictions = 0;
3757731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  TabContents* current_tab = GetSelectedTabContents();
3758731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (current_tab) {
3759731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    restrictions = current_tab->content_restrictions();
3760731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NavigationEntry* active_entry = current_tab->controller().GetActiveEntry();
3761731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // See comment in UpdateCommandsForTabState about why we call url().
3762731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!SavePackage::IsSavableURL(active_entry ? active_entry->url() : GURL()))
3763731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      restrictions |= CONTENT_RESTRICTION_SAVE;
3764731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
3765731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3766731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(
3767731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY));
3768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(
3769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT));
3770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(
3771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE));
3772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(
3773731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      IDC_SAVE_PAGE, !(restrictions & CONTENT_RESTRICTION_SAVE));
3774731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  UpdatePrintingState(restrictions);
3775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
3776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3777731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::UpdatePrintingState(int content_restrictions) {
3778731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bool enabled = true;
3779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (content_restrictions & CONTENT_RESTRICTION_PRINT) {
3780731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    enabled = false;
3781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else if (g_browser_process->local_state()) {
3782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    enabled = printing_enabled_.GetValue();
3783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
3784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_updater_.UpdateCommandEnabled(IDC_PRINT, enabled);
3785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateReloadStopState(bool is_loading, bool force) {
3788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->UpdateReloadStopState(is_loading, force);
3789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading);
3790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3792513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid Browser::UpdateCommandsForDevTools() {
3793513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool dev_tools_enabled = !dev_tools_disabled_.GetValue();
3794513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS,
3795513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                        dev_tools_enabled);
3796513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE,
3797513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                        dev_tools_enabled);
3798513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT,
3799513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                        dev_tools_enabled);
3800513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
3801513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
3802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::UpdateCommandsForBookmarkEditing() {
3803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool enabled = edit_bookmarks_enabled_.GetValue() &&
3804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                 browser_defaults::bookmarks_enabled;
3805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
3807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      enabled && type() == TYPE_NORMAL);
3808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
3809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      enabled && CanBookmarkAllTabs());
3810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, UI update coalescing and handling (private):
3814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::UpdateToolbar(bool should_restore_state) {
3816201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  window_->UpdateToolbar(GetSelectedTabContentsWrapper(), should_restore_state);
3817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ScheduleUIUpdate(const TabContents* source,
3820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               unsigned changed_flags) {
3821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!source)
3822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do some synchronous updates.
3825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags & TabContents::INVALIDATE_URL &&
3826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      source == GetSelectedTabContents()) {
3827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Only update the URL for the current tab. Note that we do not update
3828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the navigation commands since those would have already been updated
3829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // synchronously by NavigationStateChanged.
3830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateToolbar(false);
3831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    changed_flags &= ~TabContents::INVALIDATE_URL;
3832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags & TabContents::INVALIDATE_LOAD) {
3834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Update the loading state synchronously. This is so the throbber will
3835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // immediately start/stop, which gives a more snappy feel. We want to do
3836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // this for any tab so they start & stop quickly.
38373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
38383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        tab_handler_->GetTabStripModel()->GetIndexOfController(
38393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            &source->controller()),
3840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        TabStripModelObserver::LOADING_ONLY);
3841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The status bubble needs to be updated during INVALIDATE_LOAD too, but
3842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // we do that asynchronously by not stripping INVALIDATE_LOAD from
3843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // changed_flags.
3844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags & TabContents::INVALIDATE_TITLE && !source->is_loading()) {
3847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // To correctly calculate whether the title changed while not loading
3848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // we need to process the update synchronously. This state only matters for
3849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the TabStripModel, so we notify the TabStripModel now and notify others
3850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // asynchronously.
38513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
38523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        tab_handler_->GetTabStripModel()->GetIndexOfController(
38533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            &source->controller()),
3854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        TabStripModelObserver::TITLE_NOT_LOADING);
3855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (changed_flags & TabContents::INVALIDATE_BOOKMARK_BAR) {
3858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    window()->ShelfVisibilityChanged();
38593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    changed_flags &= ~TabContents::INVALIDATE_BOOKMARK_BAR;
3860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the only updates were synchronously handled above, we're done.
3863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (changed_flags == 0)
3864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save the dirty bits.
3867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scheduled_updates_[source] |= changed_flags;
3868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (chrome_updater_factory_.empty()) {
3870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // No task currently scheduled, start another.
3871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostDelayedTask(
3872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE,
3873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        chrome_updater_factory_.NewRunnableMethod(
3874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            &Browser::ProcessPendingUIUpdates),
3875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            kUIUpdateCoalescingTimeMS);
3876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ProcessPendingUIUpdates() {
3880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NDEBUG
3881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Validate that all tabs we have pending updates for exist. This is scary
3882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // because the pending list must be kept in sync with any detached or
3883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // deleted tabs.
3884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UpdateMap::const_iterator i = scheduled_updates_.begin();
3885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       i != scheduled_updates_.end(); ++i) {
3886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool found = false;
3887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int tab = 0; tab < tab_count(); tab++) {
3888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (GetTabContentsAt(tab) == i->first) {
3889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        found = true;
3890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
3891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
3892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(found);
3894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  chrome_updater_factory_.RevokeAll();
3898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UpdateMap::const_iterator i = scheduled_updates_.begin();
3900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       i != scheduled_updates_.end(); ++i) {
3901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Do not dereference |contents|, it may be out-of-date!
3902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const TabContents* contents = i->first;
3903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned flags = i->second;
3904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (contents == GetSelectedTabContents()) {
3906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Updates that only matter when the tab is selected go here.
3907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (flags & TabContents::INVALIDATE_PAGE_ACTIONS) {
3909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        LocationBar* location_bar = window()->GetLocationBar();
3910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (location_bar)
3911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          location_bar->UpdatePageActions();
3912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
3913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Updating the URL happens synchronously in ScheduleUIUpdate.
3914dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (flags & TabContents::INVALIDATE_LOAD && GetStatusBubble()) {
3915dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        GetStatusBubble()->SetStatus(
3916dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen            GetSelectedTabContentsWrapper()->GetStatusText());
3917dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
3918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (flags & (TabContents::INVALIDATE_TAB |
3920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   TabContents::INVALIDATE_TITLE)) {
3921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(pinkerton): Disable app-mode in the model until we implement it
3922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148
3923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
3924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS,
3925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            web_app::IsValidUrl(contents->GetURL()));
3926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        window_->UpdateTitleBar();
3928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
3929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Updates that don't depend upon the selected state go here.
3932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (flags & (TabContents::INVALIDATE_TAB | TabContents::INVALIDATE_TITLE)) {
39333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      tab_handler_->GetTabStripModel()->UpdateTabContentsStateAt(
3934201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          tab_handler_->GetTabStripModel()->GetWrapperIndex(contents),
3935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          TabStripModelObserver::ALL);
3936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We don't need to process INVALIDATE_STATE, since that's not visible.
3939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scheduled_updates_.clear();
3942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::RemoveScheduledUpdatesFor(TabContents* contents) {
3945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!contents)
3946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateMap::iterator i = scheduled_updates_.find(contents);
3949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (i != scheduled_updates_.end())
3950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scheduled_updates_.erase(i);
3951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Getters for UI (private):
3956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3957c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochStatusBubble* Browser::GetStatusBubble() {
3958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
3959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // In kiosk mode, we want to always hide the status bubble.
3960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
3961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
3962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
3963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return window_ ? window_->GetStatusBubble() : NULL;
3964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Session restore functions (private):
3968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::SyncHistoryWithTabs(int index) {
3970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!profile()->HasSessionService())
3971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
3972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SessionService* session_service = profile()->GetSessionService();
3973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (session_service) {
3974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = index; i < tab_count(); ++i) {
3975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      TabContents* contents = GetTabContentsAt(i);
3976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (contents) {
3977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        session_service->SetTabIndexInWindow(
3978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            session_id(), contents->controller().session_id(), i);
39793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        session_service->SetPinnedState(
39803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            session_id(),
39813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            contents->controller().session_id(),
39823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            tab_handler_->GetTabStripModel()->IsTabPinned(i));
3983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
3984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
3989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, OnBeforeUnload handling (private):
3990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::ProcessPendingTabs() {
399272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!is_attempting_to_close_browser_) {
399372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Because we might invoke this after a delay it's possible for the value of
399472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // is_attempting_to_close_browser_ to have changed since we scheduled the
399572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // task.
399672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
399772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
3998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (HasCompletedUnloadProcessing()) {
4000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We've finished all the unload events and can proceed to close the
4001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // browser.
4002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    OnWindowClosing();
4003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
4004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Process beforeunload tabs first. When that queue is empty, process
4007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // unload tabs.
4008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!tabs_needing_before_unload_fired_.empty()) {
4009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* tab = *(tabs_needing_before_unload_fired_.begin());
4010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Null check render_view_host here as this gets called on a PostTask and
4011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the tab's render_view_host may have been nulled out.
4012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (tab->render_view_host()) {
4013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab->render_view_host()->FirePageBeforeUnload(false);
4014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
401572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ClearUnloadState(tab, true);
4016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
4017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (!tabs_needing_unload_fired_.empty()) {
4018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We've finished firing all beforeunload events and can proceed with unload
4019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // events.
4020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(ojan): We should add a call to browser_shutdown::OnShutdownStarting
4021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // somewhere around here so that we have accurate measurements of shutdown
4022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // time.
4023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(ojan): We can probably fire all the unload events in parallel and
4024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // get a perf benefit from that in the cases where the tab hangs in it's
4025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // unload handler or takes a long time to page in.
4026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TabContents* tab = *(tabs_needing_unload_fired_.begin());
4027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Null check render_view_host here as this gets called on a PostTask and
4028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the tab's render_view_host may have been nulled out.
4029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (tab->render_view_host()) {
4030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab->render_view_host()->ClosePage(false, -1, -1);
4031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
403272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ClearUnloadState(tab, true);
4033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
4034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
4035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
4036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::HasCompletedUnloadProcessing() const {
4040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return is_attempting_to_close_browser_ &&
4041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tabs_needing_before_unload_fired_.empty() &&
4042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tabs_needing_unload_fired_.empty();
4043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CancelWindowClose() {
4046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Closing of window can be canceled from:
4047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - canceling beforeunload
4048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - disallowing closing from IsClosingPermitted.
4049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(is_attempting_to_close_browser_);
4050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabs_needing_before_unload_fired_.clear();
4051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tabs_needing_unload_fired_.clear();
4052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_attempting_to_close_browser_ = false;
4053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Inform TabCloseableStateWatcher that closing of window has been canceled.
4055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TabCloseableStateWatcher* watcher =
4056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      g_browser_process->tab_closeable_state_watcher();
4057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (watcher)
4058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    watcher->OnWindowCloseCanceled(this);
4059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Browser::RemoveFromSet(UnloadListenerSet* set, TabContents* tab) {
4062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(is_attempting_to_close_browser_);
4063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UnloadListenerSet::iterator iter = std::find(set->begin(), set->end(), tab);
4065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (iter != set->end()) {
4066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    set->erase(iter);
4067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
4068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
4070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::ClearUnloadState(TabContents* tab, bool process_now) {
4073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Closing of browser could be canceled (via IsClosingPermitted) between the
4074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // time when request was initiated and when this method is called, so check
4075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // for is_attempting_to_close_browser_ flag before proceeding.
4076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_attempting_to_close_browser_) {
4077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemoveFromSet(&tabs_needing_before_unload_fired_, tab);
4078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemoveFromSet(&tabs_needing_unload_fired_, tab);
407972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (process_now) {
408072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ProcessPendingTabs();
408172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else {
408272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      MessageLoop::current()->PostTask(
408372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          FROM_HERE,
408472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          method_factory_.NewRunnableMethod(&Browser::ProcessPendingTabs));
408572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
4086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
4090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, In-progress download termination handling (private):
4091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid Browser::CheckDownloadsInProgress(bool* normal_downloads_are_present,
409321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       bool* incognito_downloads_are_present) {
409421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  *normal_downloads_are_present = false;
409521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  *incognito_downloads_are_present = false;
409621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If there are no download in-progress, our job is done.
40983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DownloadManager* download_manager = NULL;
40993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // But first we need to check for the existance of the download manager, as
41003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // GetDownloadManager() will unnecessarily try to create one if it does not
41013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // exist.
410221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (profile()->HasCreatedDownloadManager())
410321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    download_manager = profile()->GetDownloadManager();
410421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (profile()->IsOffTheRecord()) {
4105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Browser is incognito and so download_manager if present is for incognito
4106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // downloads.
410721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    *incognito_downloads_are_present =
4108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (download_manager && download_manager->in_progress_count() != 0);
4109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Check original profile.
411021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (profile()->GetOriginalProfile()->HasCreatedDownloadManager())
411121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      download_manager = profile()->GetOriginalProfile()->GetDownloadManager();
4112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  *normal_downloads_are_present =
4115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (download_manager && download_manager->in_progress_count() != 0);
411621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
411721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
411821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool Browser::CanCloseWithInProgressDownloads() {
411921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (cancel_download_confirmation_state_ != NOT_PROMPTED) {
412021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (cancel_download_confirmation_state_ == WAITING_FOR_RESPONSE) {
412121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // We need to hear from the user before we can close.
412221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return false;
412321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
412421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // RESPONSE_RECEIVED case, the user decided to go along with the closing.
412521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return true;
412621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
412721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Indicated that normal (non-incognito) downloads are pending.
412821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool normal_downloads_are_present = false;
412921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool incognito_downloads_are_present = false;
413021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  CheckDownloadsInProgress(&normal_downloads_are_present,
413121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                      &incognito_downloads_are_present);
4132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!normal_downloads_are_present && !incognito_downloads_are_present)
4133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
4134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_attempting_to_close_browser_)
4136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
4137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((!normal_downloads_are_present && !profile()->IsOffTheRecord()) ||
4139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (!incognito_downloads_are_present && profile()->IsOffTheRecord()))
4140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
4141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let's figure out if we are the last window for our profile.
4143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we cannot just use BrowserList::GetBrowserCount as browser
4144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // windows closing is delayed and the returned count might include windows
4145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that are being closed.
4146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The browser allowed to be closed only if:
4147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 1. It is a regular browser and there are no regular downloads present or
4148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    this is not the last regular browser window.
4149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 2. It is an incognito browser and there are no incognito downloads present
4150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //    or this is not the last incognito browser window.
4151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int count = 0;
4152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (BrowserList::const_iterator iter = BrowserList::begin();
4153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != BrowserList::end(); ++iter) {
4154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Don't count this browser window or any other in the process of closing.
415521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Only consider normal browser windows, not popups.
415621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Browser* const browser = *iter;
415721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (browser == this
415821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        || browser->is_attempting_to_close_browser_
415921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        || browser->type() != Browser::TYPE_NORMAL)
4160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
4161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Verify that this is not the last non-incognito or incognito browser,
4163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // depending on the pending downloads.
4164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (normal_downloads_are_present && !profile()->IsOffTheRecord() &&
416521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        browser->profile()->IsOffTheRecord())
4166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
4167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (incognito_downloads_are_present && profile()->IsOffTheRecord() &&
416821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        !browser->profile()->IsOffTheRecord())
4169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
4170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We test the original profile, because an incognito browser window keeps
4172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the original profile alive (and its DownloadManager).
4173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We also need to test explicitly the profile directly so that 2 incognito
4174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // profiles count as a match.
4175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if ((*iter)->profile() == profile() ||
4176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        (*iter)->profile()->GetOriginalProfile() == profile())
4177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      count++;
4178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (count > 0)
4180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
4181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE;
4183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->ConfirmBrowserCloseWithPendingDownloads();
4184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return false so the browser does not close.  We'll close if the user
4186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // confirms in the dialog.
4187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
4188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
4191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Browser, Assorted utility functions (private):
4192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
41943345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickBrowser* Browser::GetTabbedBrowser(Profile* profile, bool match_incognito) {
41953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return BrowserList::FindBrowserWithType(profile, TYPE_NORMAL,
41963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                          match_incognito);
41973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
41983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
41993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static
4200c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowser* Browser::GetOrCreateTabbedBrowser(Profile* profile) {
42013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Browser* browser = GetTabbedBrowser(profile, false);
4202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!browser)
4203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    browser = Browser::Create(profile);
4204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return browser;
4205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid Browser::SetAsDelegate(TabContentsWrapper* tab, Browser* delegate) {
4208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab->tab_contents()->set_delegate(delegate);
4209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab->set_delegate(delegate);
4210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  tab->search_engine_tab_helper()->set_delegate(delegate);
4211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
4212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
4213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::FindInPage(bool find_next, bool forward_direction) {
4214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowFindBar();
4215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (find_next) {
4216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    string16 find_text;
4217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX)
4218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We always want to search for the contents of the find pasteboard on OS X.
4219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_text = GetFindPboardText();
4220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
422172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GetSelectedTabContentsWrapper()->
4222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        find_tab_helper()->StartFinding(find_text,
4223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                        forward_direction,
4224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                                        false);  // Not case sensitive.
4225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::CloseFrame() {
4229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_->Close();
4230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid Browser::TabDetachedAtImpl(TabContentsWrapper* contents, int index,
4233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                DetachType type) {
4234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == DETACH_TYPE_DETACH) {
42354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Save the current location bar state, but only if the tab being detached
42364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // is the selected tab.  Because saving state can conditionally revert the
42374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // location bar, saving the current tab's location bar state to a
42384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // non-selected tab can corrupt both tabs.
4239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (contents == GetSelectedTabContentsWrapper()) {
4240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      LocationBar* location_bar = window()->GetLocationBar();
4241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (location_bar)
4242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        location_bar->SaveStateToContents(contents->tab_contents());
4243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
4244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!tab_handler_->GetTabStripModel()->closing_all())
4246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      SyncHistoryWithTabs(0);
4247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
4248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4249dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetAsDelegate(contents, NULL);
4250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  RemoveScheduledUpdatesFor(contents->tab_contents());
4251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (find_bar_controller_.get() &&
4253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      index == tab_handler_->GetTabStripModel()->active_index()) {
4254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    find_bar_controller_->ChangeTabContents(NULL);
42553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
425772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (is_attempting_to_close_browser_) {
425872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // If this is the last tab with unload handlers, then ProcessPendingTabs
425972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // would call back into the TabStripModel (which is invoking this method on
426072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // us). Avoid that by passing in false so that the call to
426172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // ProcessPendingTabs is delayed.
426272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ClearUnloadState(contents->tab_contents(), false);
426372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
426472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Remove(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
4266201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    Source<TabContentsWrapper>(contents));
4267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
427072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Browser::RegisterAppPrefs(const std::string& app_name, Profile* profile) {
4271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A set of apps that we've already started.
42723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static std::set<std::string>* g_app_names = NULL;
4273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!g_app_names)
42753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    g_app_names = new std::set<std::string>;
4276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Only register once for each app name.
4278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (g_app_names->find(app_name) != g_app_names->end())
4279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
4280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_app_names->insert(app_name);
4281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We need to register the window position pref.
42833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string window_pref(prefs::kBrowserWindowPlacement);
42843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  window_pref.append("_");
4285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  window_pref.append(app_name);
428672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  profile->GetPrefs()->RegisterDictionaryPref(window_pref.c_str());
4287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::TabRestoreServiceChanged(TabRestoreService* service) {
4290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB,
4291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        !service->entries().empty());
4292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Browser::TabRestoreServiceDestroyed(TabRestoreService* service) {
4295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!tab_restore_service_)
4296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
4297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(tab_restore_service_, service);
4299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_restore_service_->RemoveObserver(this);
4300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  tab_restore_service_ = NULL;
4301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Centralized method for creating a TabContents, configuring and installing
4304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// all its supporting objects and observers.
4305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContentsWrapper* Browser::TabContentsFactory(
4306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    Profile* profile,
4307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SiteInstance* site_instance,
4308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int routing_id,
4309201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const TabContents* base_tab_contents,
4310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SessionStorageNamespace* session_storage_namespace) {
4311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContents* new_contents = new TabContents(profile, site_instance,
4312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                              routing_id, base_tab_contents,
4313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                              session_storage_namespace);
4314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  TabContentsWrapper* wrapper = new TabContentsWrapper(new_contents);
4315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  return wrapper;
4316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
4317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
4318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool Browser::OpenInstant(WindowOpenDisposition disposition) {
43193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (!instant() || !instant()->is_active() || !instant()->IsCurrent() ||
43203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      disposition == NEW_BACKGROUND_TAB) {
43213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // NEW_BACKGROUND_TAB results in leaving the omnibox open, so we don't
43223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // attempt to use the instant preview.
4323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
43243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  }
43253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
43263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (disposition == CURRENT_TAB) {
4327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    instant()->CommitCurrentPreview(INSTANT_COMMIT_PRESSED_ENTER);
43283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
4329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
43303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (disposition == NEW_FOREGROUND_TAB) {
4331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    TabContentsWrapper* preview_contents = instant()->ReleasePreviewContents(
4332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        INSTANT_COMMIT_PRESSED_ENTER);
43333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // HideInstant is invoked after release so that InstantController is not
43343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    // active when HideInstant asks it for its state.
43353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    HideInstant();
43363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    preview_contents->controller().PruneAllButActive();
43373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    tab_handler_->GetTabStripModel()->AddTabContents(
43383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        preview_contents,
43393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        -1,
4340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        instant()->last_transition_type(),
4341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        TabStripModel::ADD_ACTIVE);
4342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    instant()->CompleteRelease(preview_contents->tab_contents());
43433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
43443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
43453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The omnibox currently doesn't use other dispositions, so we don't attempt
43463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to handle them. If you hit this NOTREACHED file a bug and I'll (sky) add
43473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // support for the new disposition.
43483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  NOTREACHED();
43493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return false;
4350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
4351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
4352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Browser::CreateInstantIfNecessary() {
4353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (type() == TYPE_NORMAL && InstantController::IsEnabled(profile()) &&
4354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      !profile()->IsOffTheRecord()) {
4355513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    instant_.reset(new InstantController(profile_, this));
4356201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    instant_unload_handler_.reset(new InstantUnloadHandler(this));
4357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
4358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
435921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
436021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid Browser::ViewSource(TabContentsWrapper* contents) {
4361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(contents);
4362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
4363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NavigationEntry* active_entry = contents->controller().GetActiveEntry();
4364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!active_entry)
4365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
4366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
4367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ViewSource(contents, active_entry->url(), active_entry->content_state());
4368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
4369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
4370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid Browser::ViewSource(TabContentsWrapper* contents,
4371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         const GURL& url,
4372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         const std::string& content_state) {
437321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(UserMetricsAction("ViewSource"), profile_);
437421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(contents);
437521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
437621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  TabContentsWrapper* view_source_contents = contents->Clone();
437721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  view_source_contents->controller().PruneAllButActive();
437821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NavigationEntry* active_entry =
437921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      view_source_contents->controller().GetActiveEntry();
438021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!active_entry)
438121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
438221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GURL view_source_url = GURL(chrome::kViewSourceScheme + std::string(":") +
4384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url.spec());
4385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  active_entry->set_virtual_url(view_source_url);
4386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
438721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Do not restore scroller position.
4388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  active_entry->set_content_state(
4389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      webkit_glue::RemoveScrollOffsetFromHistoryState(content_state));
439021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
439121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Do not restore title, derive it from the url.
439221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  active_entry->set_title(string16());
439321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  // Now show view-source entry.
439521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (CanSupportWindowFeature(FEATURE_TABSTRIP)) {
439621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // If this is a tabbed browser, just create a duplicate tab inside the same
439721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // window next to the tab being duplicated.
439821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    int index = tab_handler_->GetTabStripModel()->
439921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        GetIndexOfTabContents(contents);
4400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int add_types = TabStripModel::ADD_ACTIVE |
44013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        TabStripModel::ADD_INHERIT_GROUP;
440221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    tab_handler_->GetTabStripModel()->InsertTabContentsAt(index + 1,
44033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                          view_source_contents,
440421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                                          add_types);
440521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
44063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    Browser* browser = Browser::CreateForType(TYPE_NORMAL, profile_);
440721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
440821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Preserve the size of the original window. The new window has already
440921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // been given an offset by the OS, so we shouldn't copy the old bounds.
441021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserWindow* new_window = browser->window();
441121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
441221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          window()->GetRestoredBounds().size()));
441321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
441421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // We need to show the browser now. Otherwise ContainerWin assumes the
441521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // TabContents is invisible and won't size it.
441621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    browser->window()->Show();
441721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
441821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // The page transition below is only for the purpose of inserting the tab.
44193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    browser->AddTab(view_source_contents, PageTransition::LINK);
442021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
442121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
442221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (profile_->HasSessionService()) {
442321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    SessionService* session_service = profile_->GetSessionService();
442421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (session_service)
44253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      session_service->TabRestored(&view_source_contents->controller(), false);
442621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
442721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
4428