ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / ui / browser_commands.cc
blobbececbe68688e4d5d9fe749d8ce3843513f24f66
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/browser_commands.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/browsing_data/browsing_data_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_remover.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/devtools/devtools_window.h"
18 #include "chrome/browser/dom_distiller/tab_utils.h"
19 #include "chrome/browser/favicon/favicon_tab_helper.h"
20 #include "chrome/browser/lifetime/application_lifetime.h"
21 #include "chrome/browser/platform_util.h"
22 #include "chrome/browser/prefs/incognito_mode_prefs.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/rlz/rlz.h"
25 #include "chrome/browser/search/search.h"
26 #include "chrome/browser/sessions/session_service_factory.h"
27 #include "chrome/browser/sessions/tab_restore_service.h"
28 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
29 #include "chrome/browser/sessions/tab_restore_service_factory.h"
30 #include "chrome/browser/signin/signin_header_helper.h"
31 #include "chrome/browser/translate/chrome_translate_client.h"
32 #include "chrome/browser/ui/accelerator_utils.h"
33 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
34 #include "chrome/browser/ui/browser.h"
35 #include "chrome/browser/ui/browser_command_controller.h"
36 #include "chrome/browser/ui/browser_dialogs.h"
37 #include "chrome/browser/ui/browser_instant_controller.h"
38 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
39 #include "chrome/browser/ui/browser_tabstrip.h"
40 #include "chrome/browser/ui/browser_window.h"
41 #include "chrome/browser/ui/chrome_pages.h"
42 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
43 #include "chrome/browser/ui/find_bar/find_bar.h"
44 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
45 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
46 #include "chrome/browser/ui/location_bar/location_bar.h"
47 #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h"
48 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
49 #include "chrome/browser/ui/search/search_tab_helper.h"
50 #include "chrome/browser/ui/status_bubble.h"
51 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
52 #include "chrome/browser/ui/tab_dialogs.h"
53 #include "chrome/browser/ui/tabs/tab_strip_model.h"
54 #include "chrome/browser/upgrade_detector.h"
55 #include "chrome/common/chrome_switches.h"
56 #include "chrome/common/chrome_version_info.h"
57 #include "chrome/common/content_restriction.h"
58 #include "chrome/common/pref_names.h"
59 #include "components/bookmarks/browser/bookmark_model.h"
60 #include "components/bookmarks/browser/bookmark_utils.h"
61 #include "components/google/core/browser/google_util.h"
62 #include "components/translate/core/browser/language_state.h"
63 #include "components/ui/zoom/page_zoom.h"
64 #include "components/ui/zoom/zoom_controller.h"
65 #include "components/web_modal/popup_manager.h"
66 #include "content/public/browser/devtools_agent_host.h"
67 #include "content/public/browser/navigation_controller.h"
68 #include "content/public/browser/navigation_entry.h"
69 #include "content/public/browser/notification_service.h"
70 #include "content/public/browser/page_navigator.h"
71 #include "content/public/browser/render_view_host.h"
72 #include "content/public/browser/render_widget_host_view.h"
73 #include "content/public/browser/user_metrics.h"
74 #include "content/public/browser/web_contents.h"
75 #include "content/public/common/page_state.h"
76 #include "content/public/common/renderer_preferences.h"
77 #include "content/public/common/url_constants.h"
78 #include "content/public/common/url_utils.h"
79 #include "content/public/common/user_agent.h"
80 #include "net/base/escape.h"
81 #include "ui/events/keycodes/keyboard_codes.h"
83 #if defined(OS_WIN)
84 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
85 #endif
87 #if defined(ENABLE_EXTENSIONS)
88 #include "chrome/browser/extensions/api/commands/command_service.h"
89 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
90 #include "chrome/browser/extensions/tab_helper.h"
91 #include "chrome/browser/web_applications/web_app.h"
92 #include "chrome/common/extensions/extension_metrics.h"
93 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
94 #include "extensions/browser/extension_registry.h"
95 #include "extensions/browser/extension_system.h"
96 #include "extensions/common/extension.h"
97 #include "extensions/common/extension_set.h"
98 #endif
100 #if defined(ENABLE_PRINTING)
101 #include "chrome/browser/printing/print_view_manager_common.h"
102 #if defined(ENABLE_PRINT_PREVIEW)
103 #include "chrome/browser/printing/print_preview_dialog_controller.h"
104 #endif // defined(ENABLE_PRINT_PREVIEW)
105 #endif // defined(ENABLE_PRINTING)
107 namespace {
108 const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
111 using base::UserMetricsAction;
112 using bookmarks::BookmarkModel;
113 using content::NavigationController;
114 using content::NavigationEntry;
115 using content::OpenURLParams;
116 using content::Referrer;
117 using content::SSLStatus;
118 using content::WebContents;
120 namespace chrome {
121 namespace {
123 bool CanBookmarkCurrentPageInternal(const Browser* browser,
124 bool check_remove_bookmark_ui) {
125 BookmarkModel* model =
126 BookmarkModelFactory::GetForProfile(browser->profile());
127 return browser_defaults::bookmarks_enabled &&
128 browser->profile()->GetPrefs()->GetBoolean(
129 bookmarks::prefs::kEditBookmarksEnabled) &&
130 model && model->loaded() && browser->is_type_tabbed() &&
131 (!check_remove_bookmark_ui ||
132 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
135 #if defined(ENABLE_EXTENSIONS)
136 bool GetBookmarkOverrideCommand(
137 Profile* profile,
138 const extensions::Extension** extension,
139 extensions::Command* command,
140 extensions::CommandService::ExtensionCommandType* command_type) {
141 DCHECK(extension);
142 DCHECK(command);
143 DCHECK(command_type);
145 ui::Accelerator bookmark_page_accelerator =
146 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
147 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
148 return false;
150 extensions::CommandService* command_service =
151 extensions::CommandService::Get(profile);
152 const extensions::ExtensionSet& extension_set =
153 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
154 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
155 i != extension_set.end();
156 ++i) {
157 extensions::Command prospective_command;
158 extensions::CommandService::ExtensionCommandType prospective_command_type;
159 if (command_service->GetSuggestedExtensionCommand(
160 (*i)->id(), bookmark_page_accelerator, &prospective_command,
161 &prospective_command_type)) {
162 *extension = i->get();
163 *command = prospective_command;
164 *command_type = prospective_command_type;
165 return true;
168 return false;
170 #endif
172 // Based on |disposition|, creates a new tab as necessary, and returns the
173 // appropriate tab to navigate. If that tab is the current tab, reverts the
174 // location bar contents, since all browser-UI-triggered navigations should
175 // revert any omnibox edits in the current tab.
176 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
177 WindowOpenDisposition disposition) {
178 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
179 switch (disposition) {
180 case NEW_FOREGROUND_TAB:
181 case NEW_BACKGROUND_TAB: {
182 WebContents* new_tab = current_tab->Clone();
183 browser->tab_strip_model()->AddWebContents(
184 new_tab, -1, ui::PAGE_TRANSITION_LINK,
185 (disposition == NEW_FOREGROUND_TAB) ?
186 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
187 return new_tab;
189 case NEW_WINDOW: {
190 WebContents* new_tab = current_tab->Clone();
191 Browser* new_browser = new Browser(Browser::CreateParams(
192 browser->profile(), browser->host_desktop_type()));
193 new_browser->tab_strip_model()->AddWebContents(
194 new_tab, -1, ui::PAGE_TRANSITION_LINK,
195 TabStripModel::ADD_ACTIVE);
196 new_browser->window()->Show();
197 return new_tab;
199 default:
200 browser->window()->GetLocationBar()->Revert();
201 return current_tab;
205 void ReloadInternal(Browser* browser,
206 WindowOpenDisposition disposition,
207 bool ignore_cache) {
208 // As this is caused by a user action, give the focus to the page.
210 // Also notify RenderViewHostDelegate of the user gesture; this is
211 // normally done in Browser::Navigate, but a reload bypasses Navigate.
212 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
213 new_tab->UserGestureDone();
214 if (!new_tab->FocusLocationBarByDefault())
215 new_tab->Focus();
216 if (ignore_cache)
217 new_tab->GetController().ReloadIgnoringCache(true);
218 else
219 new_tab->GetController().Reload(true);
222 bool IsShowingWebContentsModalDialog(Browser* browser) {
223 WebContents* web_contents =
224 browser->tab_strip_model()->GetActiveWebContents();
225 if (!web_contents)
226 return false;
228 // In test code we may not have a popup manager.
229 if (!browser->popup_manager())
230 return false;
232 // TODO(gbillock): This is currently called in production by the CanPrint
233 // method, and may be too restrictive if we allow print preview to overlap.
234 // Re-assess how to queue print preview after we know more about popup
235 // management policy.
236 return browser->popup_manager()->IsWebModalDialogActive(web_contents);
239 #if defined(ENABLE_BASIC_PRINTING)
240 bool PrintPreviewShowing(const Browser* browser) {
241 #if defined(ENABLE_PRINT_PREVIEW)
242 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
243 printing::PrintPreviewDialogController* controller =
244 printing::PrintPreviewDialogController::GetInstance();
245 return controller && (controller->GetPrintPreviewForContents(contents) ||
246 controller->is_creating_print_preview_dialog());
247 #else
248 return false;
249 #endif
251 #endif // ENABLE_BASIC_PRINTING
253 } // namespace
255 bool IsCommandEnabled(Browser* browser, int command) {
256 return browser->command_controller()->command_updater()->IsCommandEnabled(
257 command);
260 bool SupportsCommand(Browser* browser, int command) {
261 return browser->command_controller()->command_updater()->SupportsCommand(
262 command);
265 bool ExecuteCommand(Browser* browser, int command) {
266 return browser->command_controller()->command_updater()->ExecuteCommand(
267 command);
270 bool ExecuteCommandWithDisposition(Browser* browser,
271 int command,
272 WindowOpenDisposition disposition) {
273 return browser->command_controller()->command_updater()->
274 ExecuteCommandWithDisposition(command, disposition);
277 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
278 browser->command_controller()->command_updater()->UpdateCommandEnabled(
279 command, enabled);
282 void AddCommandObserver(Browser* browser,
283 int command,
284 CommandObserver* observer) {
285 browser->command_controller()->command_updater()->AddCommandObserver(
286 command, observer);
289 void RemoveCommandObserver(Browser* browser,
290 int command,
291 CommandObserver* observer) {
292 browser->command_controller()->command_updater()->RemoveCommandObserver(
293 command, observer);
296 int GetContentRestrictions(const Browser* browser) {
297 int content_restrictions = 0;
298 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
299 if (current_tab) {
300 CoreTabHelper* core_tab_helper =
301 CoreTabHelper::FromWebContents(current_tab);
302 content_restrictions = core_tab_helper->content_restrictions();
303 NavigationEntry* last_committed_entry =
304 current_tab->GetController().GetLastCommittedEntry();
305 if (!content::IsSavableURL(
306 last_committed_entry ? last_committed_entry->GetURL() : GURL()) ||
307 current_tab->ShowingInterstitialPage())
308 content_restrictions |= CONTENT_RESTRICTION_SAVE;
309 if (current_tab->ShowingInterstitialPage())
310 content_restrictions |= CONTENT_RESTRICTION_PRINT;
312 return content_restrictions;
315 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
316 bool incognito = profile->IsOffTheRecord();
317 PrefService* prefs = profile->GetPrefs();
318 if (incognito) {
319 if (IncognitoModePrefs::GetAvailability(prefs) ==
320 IncognitoModePrefs::DISABLED) {
321 incognito = false;
323 } else if (profile->IsGuestSession() ||
324 (browser_defaults::kAlwaysOpenIncognitoWindow &&
325 IncognitoModePrefs::ShouldLaunchIncognito(
326 *base::CommandLine::ForCurrentProcess(), prefs))) {
327 incognito = true;
330 if (incognito) {
331 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
332 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
333 } else {
334 content::RecordAction(UserMetricsAction("NewWindow"));
335 SessionService* session_service =
336 SessionServiceFactory::GetForProfileForSessionRestore(
337 profile->GetOriginalProfile());
338 if (!session_service ||
339 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
340 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
345 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
346 Browser* browser = new Browser(
347 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
348 AddTabAt(browser, GURL(), -1, true);
349 browser->window()->Show();
350 return browser;
353 void OpenWindowWithRestoredTabs(Profile* profile,
354 HostDesktopType host_desktop_type) {
355 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
356 if (service)
357 service->RestoreMostRecentEntry(NULL, host_desktop_type);
360 void OpenURLOffTheRecord(Profile* profile,
361 const GURL& url,
362 chrome::HostDesktopType desktop_type) {
363 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
364 desktop_type);
365 AddSelectedTabWithURL(displayer.browser(), url,
366 ui::PAGE_TRANSITION_LINK);
369 bool CanGoBack(const Browser* browser) {
370 return browser->tab_strip_model()->GetActiveWebContents()->
371 GetController().CanGoBack();
374 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
375 content::RecordAction(UserMetricsAction("Back"));
377 if (CanGoBack(browser)) {
378 WebContents* current_tab =
379 browser->tab_strip_model()->GetActiveWebContents();
380 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
381 // If we are on an interstitial page and clone the tab, it won't be copied
382 // to the new tab, so we don't need to go back.
383 if ((new_tab == current_tab) || !current_tab->ShowingInterstitialPage())
384 new_tab->GetController().GoBack();
388 bool CanGoForward(const Browser* browser) {
389 return browser->tab_strip_model()->GetActiveWebContents()->
390 GetController().CanGoForward();
393 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
394 content::RecordAction(UserMetricsAction("Forward"));
395 if (CanGoForward(browser)) {
396 GetTabAndRevertIfNecessary(browser, disposition)->
397 GetController().GoForward();
401 bool NavigateToIndexWithDisposition(Browser* browser,
402 int index,
403 WindowOpenDisposition disposition) {
404 NavigationController* controller =
405 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
406 if (index < 0 || index >= controller->GetEntryCount())
407 return false;
408 controller->GoToIndex(index);
409 return true;
412 void Reload(Browser* browser, WindowOpenDisposition disposition) {
413 content::RecordAction(UserMetricsAction("Reload"));
414 ReloadInternal(browser, disposition, false);
417 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
418 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
419 ReloadInternal(browser, disposition, true);
422 bool CanReload(const Browser* browser) {
423 return !browser->is_devtools();
426 void Home(Browser* browser, WindowOpenDisposition disposition) {
427 content::RecordAction(UserMetricsAction("Home"));
429 std::string extra_headers;
430 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
431 // If the home page is a Google home page, add the RLZ header to the request.
432 PrefService* pref_service = browser->profile()->GetPrefs();
433 if (pref_service) {
434 if (google_util::IsGoogleHomePageUrl(
435 GURL(pref_service->GetString(prefs::kHomePage)))) {
436 extra_headers = RLZTracker::GetAccessPointHttpHeader(
437 RLZTracker::ChromeHomePage());
440 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
442 GURL url = browser->profile()->GetHomePage();
444 #if defined(ENABLE_EXTENSIONS)
445 // With bookmark apps enabled, hosted apps should return to their launch page
446 // when the home button is pressed.
447 if (browser->is_app()) {
448 const extensions::Extension* extension =
449 extensions::ExtensionRegistry::Get(browser->profile())
450 ->GetExtensionById(
451 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
452 extensions::ExtensionRegistry::EVERYTHING);
453 if (!extension)
454 return;
456 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
458 #endif
460 OpenURLParams params(
461 url, Referrer(), disposition,
462 ui::PageTransitionFromInt(
463 ui::PAGE_TRANSITION_AUTO_BOOKMARK |
464 ui::PAGE_TRANSITION_HOME_PAGE),
465 false);
466 params.extra_headers = extra_headers;
467 browser->OpenURL(params);
470 void OpenCurrentURL(Browser* browser) {
471 content::RecordAction(UserMetricsAction("LoadURL"));
472 LocationBar* location_bar = browser->window()->GetLocationBar();
473 if (!location_bar)
474 return;
476 GURL url(location_bar->GetDestinationURL());
478 ui::PageTransition page_transition = location_bar->GetPageTransition();
479 ui::PageTransition page_transition_without_qualifier(
480 ui::PageTransitionStripQualifier(page_transition));
481 WindowOpenDisposition open_disposition =
482 location_bar->GetWindowOpenDisposition();
483 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
484 // open URLs with instant_controller since in some cases it disregards it
485 // and performs a search instead. For example, when using CTRL-Enter, the
486 // location_bar is aware of the URL but instant is not.
487 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
488 // of the omnibox text may be stale if the user focuses in the omnibox and
489 // presses enter without typing anything.
490 if (page_transition_without_qualifier != ui::PAGE_TRANSITION_TYPED &&
491 page_transition_without_qualifier != ui::PAGE_TRANSITION_RELOAD &&
492 browser->instant_controller() &&
493 browser->instant_controller()->OpenInstant(open_disposition, url))
494 return;
496 NavigateParams params(browser, url, page_transition);
497 params.disposition = open_disposition;
498 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
499 // inherit the opener. In some cases the tabstrip will determine the group
500 // should be inherited, in which case the group is inherited instead of the
501 // opener.
502 params.tabstrip_add_types =
503 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
504 Navigate(&params);
506 #if defined(ENABLE_EXTENSIONS)
507 DCHECK(extensions::ExtensionSystem::Get(
508 browser->profile())->extension_service());
509 const extensions::Extension* extension =
510 extensions::ExtensionRegistry::Get(browser->profile())
511 ->enabled_extensions().GetAppByURL(url);
512 if (extension) {
513 extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
514 extension->GetType());
516 #endif
519 void Stop(Browser* browser) {
520 content::RecordAction(UserMetricsAction("Stop"));
521 browser->tab_strip_model()->GetActiveWebContents()->Stop();
524 void NewWindow(Browser* browser) {
525 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
526 browser->host_desktop_type());
529 void NewIncognitoWindow(Browser* browser) {
530 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
531 browser->host_desktop_type());
534 void CloseWindow(Browser* browser) {
535 content::RecordAction(UserMetricsAction("CloseWindow"));
536 browser->window()->Close();
539 void NewTab(Browser* browser) {
540 content::RecordAction(UserMetricsAction("NewTab"));
541 // TODO(asvitkine): This is invoked programmatically from several places.
542 // Audit the code and change it so that the histogram only gets collected for
543 // user-initiated commands.
544 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
545 TabStripModel::NEW_TAB_ENUM_COUNT);
547 if (browser->is_type_tabbed()) {
548 AddTabAt(browser, GURL(), -1, true);
549 browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
550 } else {
551 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
552 browser->host_desktop_type());
553 Browser* b = displayer.browser();
554 AddTabAt(b, GURL(), -1, true);
555 b->window()->Show();
556 // The call to AddBlankTabAt above did not set the focus to the tab as its
557 // window was not active, so we have to do it explicitly.
558 // See http://crbug.com/6380.
559 b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
563 void CloseTab(Browser* browser) {
564 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
565 browser->tab_strip_model()->CloseSelectedTabs();
568 bool CanZoomIn(content::WebContents* contents) {
569 ui_zoom::ZoomController* zoom_controller =
570 ui_zoom::ZoomController::FromWebContents(contents);
571 return zoom_controller->GetZoomPercent() != contents->GetMaximumZoomPercent();
574 bool CanZoomOut(content::WebContents* contents) {
575 ui_zoom::ZoomController* zoom_controller =
576 ui_zoom::ZoomController::FromWebContents(contents);
577 return zoom_controller->GetZoomPercent() !=
578 contents->GetMinimumZoomPercent();
581 bool IsAtDefaultZoom(content::WebContents* contents) {
582 ui_zoom::ZoomController* zoom_controller =
583 ui_zoom::ZoomController::FromWebContents(contents);
584 return zoom_controller->IsAtDefaultZoom();
587 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
588 const Browser* browser) {
589 TabRestoreService* service =
590 TabRestoreServiceFactory::GetForProfile(browser->profile());
591 if (!service || service->entries().empty())
592 return TabStripModelDelegate::RESTORE_NONE;
593 if (service->entries().front()->type == TabRestoreService::WINDOW)
594 return TabStripModelDelegate::RESTORE_WINDOW;
595 return TabStripModelDelegate::RESTORE_TAB;
598 void SelectNextTab(Browser* browser) {
599 content::RecordAction(UserMetricsAction("SelectNextTab"));
600 browser->tab_strip_model()->SelectNextTab();
603 void SelectPreviousTab(Browser* browser) {
604 content::RecordAction(UserMetricsAction("SelectPrevTab"));
605 browser->tab_strip_model()->SelectPreviousTab();
608 void MoveTabNext(Browser* browser) {
609 content::RecordAction(UserMetricsAction("MoveTabNext"));
610 browser->tab_strip_model()->MoveTabNext();
613 void MoveTabPrevious(Browser* browser) {
614 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
615 browser->tab_strip_model()->MoveTabPrevious();
618 void SelectNumberedTab(Browser* browser, int index) {
619 if (index < browser->tab_strip_model()->count()) {
620 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
621 browser->tab_strip_model()->ActivateTabAt(index, true);
625 void SelectLastTab(Browser* browser) {
626 content::RecordAction(UserMetricsAction("SelectLastTab"));
627 browser->tab_strip_model()->SelectLastTab();
630 void DuplicateTab(Browser* browser) {
631 content::RecordAction(UserMetricsAction("Duplicate"));
632 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
635 bool CanDuplicateTab(const Browser* browser) {
636 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
637 return contents && contents->GetController().GetLastCommittedEntry();
640 WebContents* DuplicateTabAt(Browser* browser, int index) {
641 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
642 CHECK(contents);
643 WebContents* contents_dupe = contents->Clone();
645 bool pinned = false;
646 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
647 // If this is a tabbed browser, just create a duplicate tab inside the same
648 // window next to the tab being duplicated.
649 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
650 pinned = browser->tab_strip_model()->IsTabPinned(index);
651 int add_types = TabStripModel::ADD_ACTIVE |
652 TabStripModel::ADD_INHERIT_GROUP |
653 (pinned ? TabStripModel::ADD_PINNED : 0);
654 browser->tab_strip_model()->InsertWebContentsAt(
655 index + 1, contents_dupe, add_types);
656 } else {
657 Browser* new_browser = NULL;
658 if (browser->is_app() && !browser->is_type_popup()) {
659 new_browser = new Browser(
660 Browser::CreateParams::CreateForApp(browser->app_name(),
661 browser->is_trusted_source(),
662 gfx::Rect(),
663 browser->profile(),
664 browser->host_desktop_type()));
665 } else {
666 new_browser = new Browser(
667 Browser::CreateParams(browser->type(), browser->profile(),
668 browser->host_desktop_type()));
670 // Preserve the size of the original window. The new window has already
671 // been given an offset by the OS, so we shouldn't copy the old bounds.
672 BrowserWindow* new_window = new_browser->window();
673 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
674 browser->window()->GetRestoredBounds().size()));
676 // We need to show the browser now. Otherwise ContainerWin assumes the
677 // WebContents is invisible and won't size it.
678 new_browser->window()->Show();
680 // The page transition below is only for the purpose of inserting the tab.
681 new_browser->tab_strip_model()->AddWebContents(
682 contents_dupe, -1,
683 ui::PAGE_TRANSITION_LINK,
684 TabStripModel::ADD_ACTIVE);
687 SessionService* session_service =
688 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
689 if (session_service)
690 session_service->TabRestored(contents_dupe, pinned);
691 return contents_dupe;
694 bool CanDuplicateTabAt(Browser* browser, int index) {
695 content::NavigationController& nc =
696 browser->tab_strip_model()->GetWebContentsAt(index)->GetController();
697 return nc.GetWebContents() && nc.GetLastCommittedEntry();
700 void ConvertPopupToTabbedBrowser(Browser* browser) {
701 content::RecordAction(UserMetricsAction("ShowAsTab"));
702 TabStripModel* tab_strip = browser->tab_strip_model();
703 WebContents* contents =
704 tab_strip->DetachWebContentsAt(tab_strip->active_index());
705 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
706 browser->host_desktop_type()));
707 b->tab_strip_model()->AppendWebContents(contents, true);
708 b->window()->Show();
711 void Exit() {
712 content::RecordAction(UserMetricsAction("Exit"));
713 chrome::AttemptUserExit();
716 void BookmarkCurrentPageIgnoringExtensionOverrides(Browser* browser) {
717 content::RecordAction(UserMetricsAction("Star"));
719 BookmarkModel* model =
720 BookmarkModelFactory::GetForProfile(browser->profile());
721 if (!model || !model->loaded())
722 return; // Ignore requests until bookmarks are loaded.
724 GURL url;
725 base::string16 title;
726 WebContents* web_contents =
727 browser->tab_strip_model()->GetActiveWebContents();
728 GetURLAndTitleToBookmark(web_contents, &url, &title);
729 bool is_bookmarked_by_any = model->IsBookmarked(url);
730 if (!is_bookmarked_by_any &&
731 web_contents->GetBrowserContext()->IsOffTheRecord()) {
732 // If we're incognito the favicon may not have been saved. Save it now
733 // so that bookmarks have an icon for the page.
734 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
736 bool was_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
737 bookmarks::AddIfNotBookmarked(model, url, title);
738 bool is_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
739 // Make sure the model actually added a bookmark before showing the star. A
740 // bookmark isn't created if the url is invalid.
741 if (browser->window()->IsActive() && is_bookmarked_by_user) {
742 // Only show the bubble if the window is active, otherwise we may get into
743 // weird situations where the bubble is deleted as soon as it is shown.
744 browser->window()->ShowBookmarkBubble(url, was_bookmarked_by_user);
748 void BookmarkCurrentPageAllowingExtensionOverrides(Browser* browser) {
749 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
751 #if defined(ENABLE_EXTENSIONS)
752 const extensions::Extension* extension = NULL;
753 extensions::Command command;
754 extensions::CommandService::ExtensionCommandType command_type;
755 if (GetBookmarkOverrideCommand(browser->profile(),
756 &extension,
757 &command,
758 &command_type)) {
759 switch (command_type) {
760 case extensions::CommandService::NAMED:
761 browser->window()->ExecuteExtensionCommand(extension, command);
762 break;
763 case extensions::CommandService::BROWSER_ACTION:
764 case extensions::CommandService::PAGE_ACTION:
765 // BookmarkCurrentPage is called through a user gesture, so it is safe
766 // to grant the active tab permission.
767 extensions::ExtensionActionAPI::Get(browser->profile())->
768 ShowExtensionActionPopup(extension, browser, true);
769 break;
771 return;
773 #endif
774 BookmarkCurrentPageIgnoringExtensionOverrides(browser);
777 bool CanBookmarkCurrentPage(const Browser* browser) {
778 return CanBookmarkCurrentPageInternal(browser, true);
781 void BookmarkAllTabs(Browser* browser) {
782 content::RecordAction(UserMetricsAction("BookmarkAllTabs"));
783 chrome::ShowBookmarkAllTabsDialog(browser);
786 bool CanBookmarkAllTabs(const Browser* browser) {
787 return browser->tab_strip_model()->count() > 1 &&
788 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
789 CanBookmarkCurrentPageInternal(browser, false);
792 void Translate(Browser* browser) {
793 if (!browser->window()->IsActive())
794 return;
796 WebContents* web_contents =
797 browser->tab_strip_model()->GetActiveWebContents();
798 ChromeTranslateClient* chrome_translate_client =
799 ChromeTranslateClient::FromWebContents(web_contents);
801 translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
802 if (chrome_translate_client) {
803 if (chrome_translate_client->GetLanguageState().translation_pending())
804 step = translate::TRANSLATE_STEP_TRANSLATING;
805 else if (chrome_translate_client->GetLanguageState().IsPageTranslated())
806 step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
808 browser->window()->ShowTranslateBubble(
809 web_contents, step, translate::TranslateErrors::NONE, true);
812 void ManagePasswordsForPage(Browser* browser) {
813 if (!browser->window()->IsActive())
814 return;
816 WebContents* web_contents =
817 browser->tab_strip_model()->GetActiveWebContents();
818 ManagePasswordsUIController* controller =
819 ManagePasswordsUIController::FromWebContents(web_contents);
820 TabDialogs::FromWebContents(web_contents)->ShowManagePasswordsBubble(
821 !controller->IsAutomaticallyOpeningBubble());
824 #if defined(OS_WIN)
825 void TogglePagePinnedToStartScreen(Browser* browser) {
826 MetroPinTabHelper::FromWebContents(
827 browser->tab_strip_model()->GetActiveWebContents())->
828 TogglePinnedToStartScreen();
830 #endif
832 void SavePage(Browser* browser) {
833 content::RecordAction(UserMetricsAction("SavePage"));
834 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
835 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
836 content::RecordAction(UserMetricsAction("PDF.SavePage"));
837 current_tab->OnSavePage();
840 bool CanSavePage(const Browser* browser) {
841 // LocalState can be NULL in tests.
842 if (g_browser_process->local_state() &&
843 !g_browser_process->local_state()->GetBoolean(
844 prefs::kAllowFileSelectionDialogs)) {
845 return false;
847 return !browser->is_devtools() &&
848 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
851 void ShowFindBar(Browser* browser) {
852 browser->GetFindBarController()->Show();
855 void ShowWebsiteSettings(Browser* browser,
856 content::WebContents* web_contents,
857 const GURL& url,
858 const SSLStatus& ssl) {
859 browser->window()->ShowWebsiteSettings(
860 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
861 web_contents, url, ssl);
864 void Print(Browser* browser) {
865 #if defined(ENABLE_PRINTING)
866 printing::StartPrint(
867 browser->tab_strip_model()->GetActiveWebContents(),
868 browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled),
869 false);
870 #endif // defined(ENABLE_PRINTING)
873 bool CanPrint(Browser* browser) {
874 // Do not print when printing is disabled via pref or policy.
875 // Do not print when a constrained window is showing. It's confusing.
876 // TODO(gbillock): Need to re-assess the call to
877 // IsShowingWebContentsModalDialog after a popup management policy is
878 // refined -- we will probably want to just queue the print request, not
879 // block it.
880 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
881 !(IsShowingWebContentsModalDialog(browser) ||
882 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
885 #if defined(ENABLE_BASIC_PRINTING)
886 void BasicPrint(Browser* browser) {
887 printing::StartBasicPrint(browser->tab_strip_model()->GetActiveWebContents());
890 bool CanBasicPrint(Browser* browser) {
891 // If printing is not disabled via pref or policy, it is always possible to
892 // advanced print when the print preview is visible. The exception to this
893 // is under Win8 ash, since showing the advanced print dialog will open it
894 // modally on the Desktop and hang the browser.
895 #if defined(OS_WIN)
896 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
897 return false;
898 #endif
900 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
901 (PrintPreviewShowing(browser) || CanPrint(browser));
903 #endif // ENABLE_BASIC_PRINTING
905 void EmailPageLocation(Browser* browser) {
906 content::RecordAction(UserMetricsAction("EmailPageLocation"));
907 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
908 DCHECK(wc);
910 std::string title = net::EscapeQueryParamValue(
911 base::UTF16ToUTF8(wc->GetTitle()), false);
912 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
913 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
914 title + "&body=%0A%0A" + page_url;
915 platform_util::OpenExternal(browser->profile(), GURL(mailto));
918 bool CanEmailPageLocation(const Browser* browser) {
919 return browser->toolbar_model()->ShouldDisplayURL() &&
920 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
923 void Cut(Browser* browser) {
924 content::RecordAction(UserMetricsAction("Cut"));
925 browser->window()->Cut();
928 void Copy(Browser* browser) {
929 content::RecordAction(UserMetricsAction("Copy"));
930 browser->window()->Copy();
933 void Paste(Browser* browser) {
934 content::RecordAction(UserMetricsAction("Paste"));
935 browser->window()->Paste();
938 void Find(Browser* browser) {
939 content::RecordAction(UserMetricsAction("Find"));
940 FindInPage(browser, false, false);
943 void FindNext(Browser* browser) {
944 content::RecordAction(UserMetricsAction("FindNext"));
945 FindInPage(browser, true, true);
948 void FindPrevious(Browser* browser) {
949 content::RecordAction(UserMetricsAction("FindPrevious"));
950 FindInPage(browser, true, false);
953 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
954 ShowFindBar(browser);
955 if (find_next) {
956 base::string16 find_text;
957 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
958 browser->tab_strip_model()->GetActiveWebContents());
959 #if defined(OS_MACOSX)
960 // We always want to search for the current contents of the find bar on
961 // OS X. For regular profile it's always the current find pboard. For
962 // Incognito window it's the newest value of the find pboard content and
963 // user-typed text.
964 FindBar* find_bar = browser->GetFindBarController()->find_bar();
965 find_text = find_bar->GetFindText();
966 #endif
967 find_helper->StartFinding(find_text, forward_direction, false);
971 void Zoom(Browser* browser, content::PageZoom zoom) {
972 ui_zoom::PageZoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
973 zoom);
976 void FocusToolbar(Browser* browser) {
977 content::RecordAction(UserMetricsAction("FocusToolbar"));
978 browser->window()->FocusToolbar();
981 void FocusLocationBar(Browser* browser) {
982 content::RecordAction(UserMetricsAction("FocusLocation"));
983 browser->window()->SetFocusToLocationBar(true);
986 void FocusSearch(Browser* browser) {
987 // TODO(beng): replace this with FocusLocationBar
988 content::RecordAction(UserMetricsAction("FocusSearch"));
989 browser->window()->GetLocationBar()->FocusSearch();
992 void FocusAppMenu(Browser* browser) {
993 content::RecordAction(UserMetricsAction("FocusAppMenu"));
994 browser->window()->FocusAppMenu();
997 void FocusBookmarksToolbar(Browser* browser) {
998 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
999 browser->window()->FocusBookmarksToolbar();
1002 void FocusInfobars(Browser* browser) {
1003 content::RecordAction(UserMetricsAction("FocusInfobars"));
1004 browser->window()->FocusInfobars();
1007 void FocusNextPane(Browser* browser) {
1008 content::RecordAction(UserMetricsAction("FocusNextPane"));
1009 browser->window()->RotatePaneFocus(true);
1012 void FocusPreviousPane(Browser* browser) {
1013 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1014 browser->window()->RotatePaneFocus(false);
1017 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1018 if (action.type() == DevToolsToggleAction::kShowConsole)
1019 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1020 else
1021 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1022 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1025 bool CanOpenTaskManager() {
1026 #if defined(ENABLE_TASK_MANAGER)
1027 return true;
1028 #else
1029 return false;
1030 #endif
1033 void OpenTaskManager(Browser* browser) {
1034 #if defined(ENABLE_TASK_MANAGER)
1035 content::RecordAction(UserMetricsAction("TaskManager"));
1036 chrome::ShowTaskManager(browser);
1037 #else
1038 NOTREACHED();
1039 #endif
1042 void OpenFeedbackDialog(Browser* browser) {
1043 content::RecordAction(UserMetricsAction("Feedback"));
1044 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1047 void ToggleBookmarkBar(Browser* browser) {
1048 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1049 ToggleBookmarkBarWhenVisible(browser->profile());
1052 void ShowAppMenu(Browser* browser) {
1053 // We record the user metric for this event in WrenchMenu::RunMenu.
1054 browser->window()->ShowAppMenu();
1057 void ShowAvatarMenu(Browser* browser) {
1058 browser->window()->ShowAvatarBubbleFromAvatarButton(
1059 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1060 signin::ManageAccountsParams());
1063 void OpenUpdateChromeDialog(Browser* browser) {
1064 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1065 content::NotificationService::current()->Notify(
1066 chrome::NOTIFICATION_OUTDATED_INSTALL,
1067 content::NotificationService::AllSources(),
1068 content::NotificationService::NoDetails());
1069 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1070 content::NotificationService::current()->Notify(
1071 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1072 content::NotificationService::AllSources(),
1073 content::NotificationService::NoDetails());
1074 } else {
1075 content::RecordAction(UserMetricsAction("UpdateChrome"));
1076 browser->window()->ShowUpdateChromeDialog();
1080 void ToggleSpeechInput(Browser* browser) {
1081 SearchTabHelper* search_tab_helper =
1082 SearchTabHelper::FromWebContents(
1083 browser->tab_strip_model()->GetActiveWebContents());
1084 // |search_tab_helper| can be null in unit tests.
1085 if (search_tab_helper)
1086 search_tab_helper->ToggleVoiceSearch();
1089 void DistillCurrentPage(Browser* browser) {
1090 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1093 bool CanRequestTabletSite(WebContents* current_tab) {
1094 return current_tab &&
1095 current_tab->GetController().GetLastCommittedEntry() != NULL;
1098 bool IsRequestingTabletSite(Browser* browser) {
1099 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1100 if (!current_tab)
1101 return false;
1102 content::NavigationEntry* entry =
1103 current_tab->GetController().GetLastCommittedEntry();
1104 if (!entry)
1105 return false;
1106 return entry->GetIsOverridingUserAgent();
1109 void ToggleRequestTabletSite(Browser* browser) {
1110 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1111 if (!current_tab)
1112 return;
1113 NavigationController& controller = current_tab->GetController();
1114 NavigationEntry* entry = controller.GetLastCommittedEntry();
1115 if (!entry)
1116 return;
1117 if (entry->GetIsOverridingUserAgent()) {
1118 entry->SetIsOverridingUserAgent(false);
1119 } else {
1120 entry->SetIsOverridingUserAgent(true);
1121 chrome::VersionInfo version_info;
1122 std::string product = version_info.ProductNameAndVersionForUserAgent();
1123 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1124 kOsOverrideForTabletSite, product));
1126 controller.ReloadOriginalRequestURL(true);
1129 void ToggleFullscreenMode(Browser* browser) {
1130 DCHECK(browser);
1131 browser->exclusive_access_manager()
1132 ->fullscreen_controller()
1133 ->ToggleBrowserFullscreenMode();
1136 void ClearCache(Browser* browser) {
1137 BrowsingDataRemover* remover =
1138 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1139 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1140 BrowsingDataHelper::UNPROTECTED_WEB);
1141 // BrowsingDataRemover takes care of deleting itself when done.
1144 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1145 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1146 return contents ?
1147 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1150 void ViewSource(Browser* browser, WebContents* contents) {
1151 DCHECK(contents);
1153 // Use the last committed entry, since the pending entry hasn't loaded yet and
1154 // won't be copied into the cloned tab.
1155 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1156 if (!entry)
1157 return;
1159 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1162 void ViewSource(Browser* browser,
1163 WebContents* contents,
1164 const GURL& url,
1165 const content::PageState& page_state) {
1166 content::RecordAction(UserMetricsAction("ViewSource"));
1167 DCHECK(contents);
1169 WebContents* view_source_contents = contents->Clone();
1170 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1171 view_source_contents->GetController().PruneAllButLastCommitted();
1172 NavigationEntry* last_committed_entry =
1173 view_source_contents->GetController().GetLastCommittedEntry();
1174 if (!last_committed_entry)
1175 return;
1177 GURL view_source_url =
1178 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1179 last_committed_entry->SetVirtualURL(view_source_url);
1181 // Do not restore scroller position.
1182 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1184 // Do not restore title, derive it from the url.
1185 last_committed_entry->SetTitle(base::string16());
1187 // Now show view-source entry.
1188 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1189 // If this is a tabbed browser, just create a duplicate tab inside the same
1190 // window next to the tab being duplicated.
1191 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1192 int add_types = TabStripModel::ADD_ACTIVE |
1193 TabStripModel::ADD_INHERIT_GROUP;
1194 browser->tab_strip_model()->InsertWebContentsAt(
1195 index + 1,
1196 view_source_contents,
1197 add_types);
1198 } else {
1199 Browser* b = new Browser(
1200 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1201 browser->host_desktop_type()));
1203 // Preserve the size of the original window. The new window has already
1204 // been given an offset by the OS, so we shouldn't copy the old bounds.
1205 BrowserWindow* new_window = b->window();
1206 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1207 browser->window()->GetRestoredBounds().size()));
1209 // We need to show the browser now. Otherwise ContainerWin assumes the
1210 // WebContents is invisible and won't size it.
1211 b->window()->Show();
1213 // The page transition below is only for the purpose of inserting the tab.
1214 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1215 ui::PAGE_TRANSITION_LINK,
1216 TabStripModel::ADD_ACTIVE);
1219 SessionService* session_service =
1220 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1221 if (session_service)
1222 session_service->TabRestored(view_source_contents, false);
1225 void ViewSelectedSource(Browser* browser) {
1226 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1229 bool CanViewSource(const Browser* browser) {
1230 return !browser->is_devtools() &&
1231 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1232 CanViewSource();
1235 #if defined(ENABLE_EXTENSIONS)
1236 void CreateApplicationShortcuts(Browser* browser) {
1237 content::RecordAction(UserMetricsAction("CreateShortcut"));
1238 extensions::TabHelper::FromWebContents(
1239 browser->tab_strip_model()->GetActiveWebContents())->
1240 CreateApplicationShortcuts();
1243 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1244 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1245 extensions::TabHelper::FromWebContents(
1246 browser->tab_strip_model()->GetActiveWebContents())->
1247 CreateHostedAppFromWebContents();
1250 bool CanCreateApplicationShortcuts(const Browser* browser) {
1251 return extensions::TabHelper::FromWebContents(
1252 browser->tab_strip_model()->GetActiveWebContents())->
1253 CanCreateApplicationShortcuts();
1256 bool CanCreateBookmarkApp(const Browser* browser) {
1257 return extensions::TabHelper::FromWebContents(
1258 browser->tab_strip_model()->GetActiveWebContents())
1259 ->CanCreateBookmarkApp();
1262 void ConvertTabToAppWindow(Browser* browser,
1263 content::WebContents* contents) {
1264 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1265 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1267 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1268 if (index >= 0)
1269 browser->tab_strip_model()->DetachWebContentsAt(index);
1271 Browser* app_browser = new Browser(
1272 Browser::CreateParams::CreateForApp(app_name,
1273 true /* trusted_source */,
1274 gfx::Rect(),
1275 browser->profile(),
1276 browser->host_desktop_type()));
1277 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1279 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1280 contents->GetRenderViewHost()->SyncRendererPrefs();
1281 app_browser->window()->Show();
1283 #endif // defined(ENABLE_EXTENSIONS)
1285 } // namespace chrome