Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / ui / browser_commands.cc
blob62529595f58be5241f5814edc03c0d6ce0c2a9dd
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/chrome_page_zoom.h"
18 #include "chrome/browser/devtools/devtools_window.h"
19 #include "chrome/browser/dom_distiller/tab_utils.h"
20 #include "chrome/browser/extensions/api/commands/command_service.h"
21 #include "chrome/browser/extensions/tab_helper.h"
22 #include "chrome/browser/favicon/favicon_tab_helper.h"
23 #include "chrome/browser/google/google_util.h"
24 #include "chrome/browser/lifetime/application_lifetime.h"
25 #include "chrome/browser/platform_util.h"
26 #include "chrome/browser/prefs/incognito_mode_prefs.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/rlz/rlz.h"
29 #include "chrome/browser/search/search.h"
30 #include "chrome/browser/sessions/session_service_factory.h"
31 #include "chrome/browser/sessions/tab_restore_service.h"
32 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
33 #include "chrome/browser/sessions/tab_restore_service_factory.h"
34 #include "chrome/browser/signin/signin_header_helper.h"
35 #include "chrome/browser/translate/translate_tab_helper.h"
36 #include "chrome/browser/ui/accelerator_utils.h"
37 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
38 #include "chrome/browser/ui/browser.h"
39 #include "chrome/browser/ui/browser_command_controller.h"
40 #include "chrome/browser/ui/browser_dialogs.h"
41 #include "chrome/browser/ui/browser_instant_controller.h"
42 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
43 #include "chrome/browser/ui/browser_tabstrip.h"
44 #include "chrome/browser/ui/browser_window.h"
45 #include "chrome/browser/ui/chrome_pages.h"
46 #include "chrome/browser/ui/find_bar/find_bar.h"
47 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
48 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
49 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
50 #include "chrome/browser/ui/omnibox/location_bar.h"
51 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
52 #include "chrome/browser/ui/search/search_tab_helper.h"
53 #include "chrome/browser/ui/status_bubble.h"
54 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
55 #include "chrome/browser/ui/tabs/tab_strip_model.h"
56 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
57 #include "chrome/browser/upgrade_detector.h"
58 #include "chrome/browser/web_applications/web_app.h"
59 #include "chrome/common/chrome_switches.h"
60 #include "chrome/common/chrome_version_info.h"
61 #include "chrome/common/content_restriction.h"
62 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
63 #include "chrome/common/pref_names.h"
64 #include "components/bookmarks/browser/bookmark_model.h"
65 #include "components/bookmarks/browser/bookmark_utils.h"
66 #include "components/web_modal/web_contents_modal_dialog_manager.h"
67 #include "content/public/browser/devtools_agent_host.h"
68 #include "content/public/browser/navigation_controller.h"
69 #include "content/public/browser/navigation_entry.h"
70 #include "content/public/browser/notification_service.h"
71 #include "content/public/browser/page_navigator.h"
72 #include "content/public/browser/render_view_host.h"
73 #include "content/public/browser/render_widget_host_view.h"
74 #include "content/public/browser/user_metrics.h"
75 #include "content/public/browser/web_contents.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 "extensions/browser/extension_registry.h"
81 #include "extensions/common/extension.h"
82 #include "extensions/common/extension_set.h"
83 #include "net/base/escape.h"
84 #include "ui/events/keycodes/keyboard_codes.h"
86 #if defined(OS_WIN)
87 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
88 #endif
90 #if defined(ENABLE_PRINTING)
91 #if defined(ENABLE_FULL_PRINTING)
92 #include "chrome/browser/printing/print_preview_dialog_controller.h"
93 #include "chrome/browser/printing/print_view_manager.h"
94 #else
95 #include "chrome/browser/printing/print_view_manager_basic.h"
96 #endif // defined(ENABLE_FULL_PRINTING)
97 #endif // defined(ENABLE_PRINTING)
99 namespace {
100 const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
103 using base::UserMetricsAction;
104 using content::NavigationController;
105 using content::NavigationEntry;
106 using content::OpenURLParams;
107 using content::Referrer;
108 using content::SSLStatus;
109 using content::WebContents;
110 using web_modal::WebContentsModalDialogManager;
112 namespace chrome {
113 namespace {
115 bool CanBookmarkCurrentPageInternal(const Browser* browser,
116 bool check_remove_bookmark_ui) {
117 BookmarkModel* model =
118 BookmarkModelFactory::GetForProfile(browser->profile());
119 return browser_defaults::bookmarks_enabled &&
120 browser->profile()->GetPrefs()->GetBoolean(
121 prefs::kEditBookmarksEnabled) &&
122 model && model->loaded() && browser->is_type_tabbed() &&
123 (!check_remove_bookmark_ui ||
124 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
127 bool GetBookmarkOverrideCommand(
128 Profile* profile,
129 const extensions::Extension** extension,
130 extensions::Command* command,
131 extensions::CommandService::ExtensionCommandType* command_type) {
132 DCHECK(extension);
133 DCHECK(command);
134 DCHECK(command_type);
136 ui::Accelerator bookmark_page_accelerator =
137 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
138 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
139 return false;
141 extensions::CommandService* command_service =
142 extensions::CommandService::Get(profile);
143 const extensions::ExtensionSet& extension_set =
144 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
145 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
146 i != extension_set.end();
147 ++i) {
148 extensions::Command prospective_command;
149 extensions::CommandService::ExtensionCommandType prospective_command_type;
150 if (command_service->GetBoundExtensionCommand((*i)->id(),
151 bookmark_page_accelerator,
152 &prospective_command,
153 &prospective_command_type)) {
154 *extension = i->get();
155 *command = prospective_command;
156 *command_type = prospective_command_type;
157 return true;
161 return false;
164 void BookmarkCurrentPageInternal(Browser* browser) {
165 content::RecordAction(UserMetricsAction("Star"));
167 BookmarkModel* model =
168 BookmarkModelFactory::GetForProfile(browser->profile());
169 if (!model || !model->loaded())
170 return; // Ignore requests until bookmarks are loaded.
172 GURL url;
173 base::string16 title;
174 WebContents* web_contents =
175 browser->tab_strip_model()->GetActiveWebContents();
176 GetURLAndTitleToBookmark(web_contents, &url, &title);
177 bool was_bookmarked = model->IsBookmarked(url);
178 if (!was_bookmarked && web_contents->GetBrowserContext()->IsOffTheRecord()) {
179 // If we're incognito the favicon may not have been saved. Save it now
180 // so that bookmarks have an icon for the page.
181 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
183 bookmark_utils::AddIfNotBookmarked(model, url, title);
184 // Make sure the model actually added a bookmark before showing the star. A
185 // bookmark isn't created if the url is invalid.
186 if (browser->window()->IsActive() && model->IsBookmarked(url)) {
187 // Only show the bubble if the window is active, otherwise we may get into
188 // weird situations where the bubble is deleted as soon as it is shown.
189 browser->window()->ShowBookmarkBubble(url, was_bookmarked);
193 // Based on |disposition|, creates a new tab as necessary, and returns the
194 // appropriate tab to navigate. If that tab is the current tab, reverts the
195 // location bar contents, since all browser-UI-triggered navigations should
196 // revert any omnibox edits in the current tab.
197 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
198 WindowOpenDisposition disposition) {
199 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
200 switch (disposition) {
201 case NEW_FOREGROUND_TAB:
202 case NEW_BACKGROUND_TAB: {
203 WebContents* new_tab = current_tab->Clone();
204 browser->tab_strip_model()->AddWebContents(
205 new_tab, -1, content::PAGE_TRANSITION_LINK,
206 (disposition == NEW_FOREGROUND_TAB) ?
207 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
208 return new_tab;
210 case NEW_WINDOW: {
211 WebContents* new_tab = current_tab->Clone();
212 Browser* new_browser = new Browser(Browser::CreateParams(
213 browser->profile(), browser->host_desktop_type()));
214 new_browser->tab_strip_model()->AddWebContents(
215 new_tab, -1, content::PAGE_TRANSITION_LINK,
216 TabStripModel::ADD_ACTIVE);
217 new_browser->window()->Show();
218 return new_tab;
220 default:
221 browser->window()->GetLocationBar()->Revert();
222 return current_tab;
226 void ReloadInternal(Browser* browser,
227 WindowOpenDisposition disposition,
228 bool ignore_cache) {
229 // As this is caused by a user action, give the focus to the page.
231 // Also notify RenderViewHostDelegate of the user gesture; this is
232 // normally done in Browser::Navigate, but a reload bypasses Navigate.
233 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
234 new_tab->UserGestureDone();
235 if (!new_tab->FocusLocationBarByDefault())
236 new_tab->Focus();
237 if (ignore_cache)
238 new_tab->GetController().ReloadIgnoringCache(true);
239 else
240 new_tab->GetController().Reload(true);
243 bool IsShowingWebContentsModalDialog(const Browser* browser) {
244 WebContents* web_contents =
245 browser->tab_strip_model()->GetActiveWebContents();
246 if (!web_contents)
247 return false;
249 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
250 WebContentsModalDialogManager::FromWebContents(web_contents);
251 return web_contents_modal_dialog_manager->IsDialogActive();
254 bool PrintPreviewShowing(const Browser* browser) {
255 #if defined(ENABLE_FULL_PRINTING)
256 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
257 printing::PrintPreviewDialogController* controller =
258 printing::PrintPreviewDialogController::GetInstance();
259 return controller && (controller->GetPrintPreviewForContents(contents) ||
260 controller->is_creating_print_preview_dialog());
261 #else
262 return false;
263 #endif
266 } // namespace
268 bool IsCommandEnabled(Browser* browser, int command) {
269 return browser->command_controller()->command_updater()->IsCommandEnabled(
270 command);
273 bool SupportsCommand(Browser* browser, int command) {
274 return browser->command_controller()->command_updater()->SupportsCommand(
275 command);
278 bool ExecuteCommand(Browser* browser, int command) {
279 return browser->command_controller()->command_updater()->ExecuteCommand(
280 command);
283 bool ExecuteCommandWithDisposition(Browser* browser,
284 int command,
285 WindowOpenDisposition disposition) {
286 return browser->command_controller()->command_updater()->
287 ExecuteCommandWithDisposition(command, disposition);
290 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
291 browser->command_controller()->command_updater()->UpdateCommandEnabled(
292 command, enabled);
295 void AddCommandObserver(Browser* browser,
296 int command,
297 CommandObserver* observer) {
298 browser->command_controller()->command_updater()->AddCommandObserver(
299 command, observer);
302 void RemoveCommandObserver(Browser* browser,
303 int command,
304 CommandObserver* observer) {
305 browser->command_controller()->command_updater()->RemoveCommandObserver(
306 command, observer);
309 int GetContentRestrictions(const Browser* browser) {
310 int content_restrictions = 0;
311 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
312 if (current_tab) {
313 CoreTabHelper* core_tab_helper =
314 CoreTabHelper::FromWebContents(current_tab);
315 content_restrictions = core_tab_helper->content_restrictions();
316 NavigationEntry* last_committed_entry =
317 current_tab->GetController().GetLastCommittedEntry();
318 if (!content::IsSavableURL(
319 last_committed_entry ? last_committed_entry->GetURL() : GURL()) ||
320 current_tab->ShowingInterstitialPage())
321 content_restrictions |= CONTENT_RESTRICTION_SAVE;
322 if (current_tab->ShowingInterstitialPage())
323 content_restrictions |= CONTENT_RESTRICTION_PRINT;
325 return content_restrictions;
328 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
329 bool incognito = profile->IsOffTheRecord();
330 PrefService* prefs = profile->GetPrefs();
331 if (incognito) {
332 if (IncognitoModePrefs::GetAvailability(prefs) ==
333 IncognitoModePrefs::DISABLED) {
334 incognito = false;
336 } else if (profile->IsGuestSession() ||
337 (browser_defaults::kAlwaysOpenIncognitoWindow &&
338 IncognitoModePrefs::ShouldLaunchIncognito(
339 *CommandLine::ForCurrentProcess(), prefs))) {
340 incognito = true;
343 if (incognito) {
344 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
345 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
346 } else {
347 content::RecordAction(UserMetricsAction("NewWindow"));
348 SessionService* session_service =
349 SessionServiceFactory::GetForProfileForSessionRestore(
350 profile->GetOriginalProfile());
351 if (!session_service ||
352 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
353 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
358 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
359 Browser* browser = new Browser(
360 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
361 AddTabAt(browser, GURL(), -1, true);
362 browser->window()->Show();
363 return browser;
366 void OpenWindowWithRestoredTabs(Profile* profile,
367 HostDesktopType host_desktop_type) {
368 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
369 if (service)
370 service->RestoreMostRecentEntry(NULL, host_desktop_type);
373 void OpenURLOffTheRecord(Profile* profile,
374 const GURL& url,
375 chrome::HostDesktopType desktop_type) {
376 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
377 desktop_type);
378 AddSelectedTabWithURL(displayer.browser(), url,
379 content::PAGE_TRANSITION_LINK);
382 bool CanGoBack(const Browser* browser) {
383 return browser->tab_strip_model()->GetActiveWebContents()->
384 GetController().CanGoBack();
387 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
388 content::RecordAction(UserMetricsAction("Back"));
390 if (CanGoBack(browser)) {
391 WebContents* current_tab =
392 browser->tab_strip_model()->GetActiveWebContents();
393 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
394 // If we are on an interstitial page and clone the tab, it won't be copied
395 // to the new tab, so we don't need to go back.
396 if ((new_tab == current_tab) || !current_tab->ShowingInterstitialPage())
397 new_tab->GetController().GoBack();
401 bool CanGoForward(const Browser* browser) {
402 return browser->tab_strip_model()->GetActiveWebContents()->
403 GetController().CanGoForward();
406 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
407 content::RecordAction(UserMetricsAction("Forward"));
408 if (CanGoForward(browser)) {
409 GetTabAndRevertIfNecessary(browser, disposition)->
410 GetController().GoForward();
414 bool NavigateToIndexWithDisposition(Browser* browser,
415 int index,
416 WindowOpenDisposition disposition) {
417 NavigationController* controller =
418 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
419 if (index < 0 || index >= controller->GetEntryCount())
420 return false;
421 controller->GoToIndex(index);
422 return true;
425 void Reload(Browser* browser, WindowOpenDisposition disposition) {
426 content::RecordAction(UserMetricsAction("Reload"));
427 ReloadInternal(browser, disposition, false);
430 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
431 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
432 ReloadInternal(browser, disposition, true);
435 bool CanReload(const Browser* browser) {
436 return !browser->is_devtools();
439 void Home(Browser* browser, WindowOpenDisposition disposition) {
440 content::RecordAction(UserMetricsAction("Home"));
442 std::string extra_headers;
443 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
444 // If the home page is a Google home page, add the RLZ header to the request.
445 PrefService* pref_service = browser->profile()->GetPrefs();
446 if (pref_service) {
447 if (google_util::IsGoogleHomePageUrl(
448 GURL(pref_service->GetString(prefs::kHomePage)))) {
449 extra_headers = RLZTracker::GetAccessPointHttpHeader(
450 RLZTracker::ChromeHomePage());
453 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
455 GURL url = browser->profile()->GetHomePage();
457 // Streamlined hosted apps should return to their launch page when the home
458 // button is pressed.
459 if (browser->is_app()) {
460 const extensions::Extension* extension =
461 extensions::ExtensionRegistry::Get(browser->profile())
462 ->GetExtensionById(
463 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
464 extensions::ExtensionRegistry::EVERYTHING);
465 if (!extension)
466 return;
468 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
471 OpenURLParams params(
472 url, Referrer(), disposition,
473 content::PageTransitionFromInt(
474 content::PAGE_TRANSITION_AUTO_BOOKMARK |
475 content::PAGE_TRANSITION_HOME_PAGE),
476 false);
477 params.extra_headers = extra_headers;
478 browser->OpenURL(params);
481 void OpenCurrentURL(Browser* browser) {
482 content::RecordAction(UserMetricsAction("LoadURL"));
483 LocationBar* location_bar = browser->window()->GetLocationBar();
484 if (!location_bar)
485 return;
487 GURL url(location_bar->GetDestinationURL());
489 content::PageTransition page_transition = location_bar->GetPageTransition();
490 content::PageTransition page_transition_without_qualifier(
491 PageTransitionStripQualifier(page_transition));
492 WindowOpenDisposition open_disposition =
493 location_bar->GetWindowOpenDisposition();
494 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
495 // open URLs with instant_controller since in some cases it disregards it
496 // and performs a search instead. For example, when using CTRL-Enter, the
497 // location_bar is aware of the URL but instant is not.
498 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
499 // of the omnibox text may be stale if the user focuses in the omnibox and
500 // presses enter without typing anything.
501 if (page_transition_without_qualifier != content::PAGE_TRANSITION_TYPED &&
502 page_transition_without_qualifier != content::PAGE_TRANSITION_RELOAD &&
503 browser->instant_controller() &&
504 browser->instant_controller()->OpenInstant(open_disposition, url))
505 return;
507 NavigateParams params(browser, url, page_transition);
508 params.disposition = open_disposition;
509 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
510 // inherit the opener. In some cases the tabstrip will determine the group
511 // should be inherited, in which case the group is inherited instead of the
512 // opener.
513 params.tabstrip_add_types =
514 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
515 Navigate(&params);
517 DCHECK(browser->profile()->GetExtensionService());
518 const extensions::Extension* extension =
519 extensions::ExtensionRegistry::Get(browser->profile())
520 ->enabled_extensions().GetAppByURL(url);
521 if (extension) {
522 CoreAppLauncherHandler::RecordAppLaunchType(
523 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
524 extension->GetType());
528 void Stop(Browser* browser) {
529 content::RecordAction(UserMetricsAction("Stop"));
530 browser->tab_strip_model()->GetActiveWebContents()->Stop();
533 void NewWindow(Browser* browser) {
534 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
535 browser->host_desktop_type());
538 void NewIncognitoWindow(Browser* browser) {
539 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
540 browser->host_desktop_type());
543 void CloseWindow(Browser* browser) {
544 content::RecordAction(UserMetricsAction("CloseWindow"));
545 browser->window()->Close();
548 void NewTab(Browser* browser) {
549 content::RecordAction(UserMetricsAction("NewTab"));
550 // TODO(asvitkine): This is invoked programmatically from several places.
551 // Audit the code and change it so that the histogram only gets collected for
552 // user-initiated commands.
553 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
554 TabStripModel::NEW_TAB_ENUM_COUNT);
556 if (browser->is_type_tabbed()) {
557 AddTabAt(browser, GURL(), -1, true);
558 browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
559 } else {
560 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
561 browser->host_desktop_type());
562 Browser* b = displayer.browser();
563 AddTabAt(b, GURL(), -1, true);
564 b->window()->Show();
565 // The call to AddBlankTabAt above did not set the focus to the tab as its
566 // window was not active, so we have to do it explicitly.
567 // See http://crbug.com/6380.
568 b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
572 void CloseTab(Browser* browser) {
573 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
574 browser->tab_strip_model()->CloseSelectedTabs();
577 void RestoreTab(Browser* browser) {
578 content::RecordAction(UserMetricsAction("RestoreTab"));
579 TabRestoreService* service =
580 TabRestoreServiceFactory::GetForProfile(browser->profile());
581 if (service)
582 service->RestoreMostRecentEntry(browser->tab_restore_service_delegate(),
583 browser->host_desktop_type());
586 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
587 const Browser* browser) {
588 TabRestoreService* service =
589 TabRestoreServiceFactory::GetForProfile(browser->profile());
590 if (!service || service->entries().empty())
591 return TabStripModelDelegate::RESTORE_NONE;
592 if (service->entries().front()->type == TabRestoreService::WINDOW)
593 return TabStripModelDelegate::RESTORE_WINDOW;
594 return TabStripModelDelegate::RESTORE_TAB;
597 void SelectNextTab(Browser* browser) {
598 content::RecordAction(UserMetricsAction("SelectNextTab"));
599 browser->tab_strip_model()->SelectNextTab();
602 void SelectPreviousTab(Browser* browser) {
603 content::RecordAction(UserMetricsAction("SelectPrevTab"));
604 browser->tab_strip_model()->SelectPreviousTab();
607 void MoveTabNext(Browser* browser) {
608 content::RecordAction(UserMetricsAction("MoveTabNext"));
609 browser->tab_strip_model()->MoveTabNext();
612 void MoveTabPrevious(Browser* browser) {
613 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
614 browser->tab_strip_model()->MoveTabPrevious();
617 void SelectNumberedTab(Browser* browser, int index) {
618 if (index < browser->tab_strip_model()->count()) {
619 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
620 browser->tab_strip_model()->ActivateTabAt(index, true);
624 void SelectLastTab(Browser* browser) {
625 content::RecordAction(UserMetricsAction("SelectLastTab"));
626 browser->tab_strip_model()->SelectLastTab();
629 void DuplicateTab(Browser* browser) {
630 content::RecordAction(UserMetricsAction("Duplicate"));
631 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
634 bool CanDuplicateTab(const Browser* browser) {
635 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
636 return contents && contents->GetController().GetLastCommittedEntry();
639 WebContents* DuplicateTabAt(Browser* browser, int index) {
640 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
641 CHECK(contents);
642 WebContents* contents_dupe = contents->Clone();
644 bool pinned = false;
645 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
646 // If this is a tabbed browser, just create a duplicate tab inside the same
647 // window next to the tab being duplicated.
648 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
649 pinned = browser->tab_strip_model()->IsTabPinned(index);
650 int add_types = TabStripModel::ADD_ACTIVE |
651 TabStripModel::ADD_INHERIT_GROUP |
652 (pinned ? TabStripModel::ADD_PINNED : 0);
653 browser->tab_strip_model()->InsertWebContentsAt(
654 index + 1, contents_dupe, add_types);
655 } else {
656 Browser* new_browser = NULL;
657 if (browser->is_app() && !browser->is_type_popup()) {
658 new_browser = new Browser(
659 Browser::CreateParams::CreateForApp(browser->app_name(),
660 browser->is_trusted_source(),
661 gfx::Rect(),
662 browser->profile(),
663 browser->host_desktop_type()));
664 } else {
665 new_browser = new Browser(
666 Browser::CreateParams(browser->type(), browser->profile(),
667 browser->host_desktop_type()));
669 // Preserve the size of the original window. The new window has already
670 // been given an offset by the OS, so we shouldn't copy the old bounds.
671 BrowserWindow* new_window = new_browser->window();
672 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
673 browser->window()->GetRestoredBounds().size()));
675 // We need to show the browser now. Otherwise ContainerWin assumes the
676 // WebContents is invisible and won't size it.
677 new_browser->window()->Show();
679 // The page transition below is only for the purpose of inserting the tab.
680 new_browser->tab_strip_model()->AddWebContents(
681 contents_dupe, -1,
682 content::PAGE_TRANSITION_LINK,
683 TabStripModel::ADD_ACTIVE);
686 SessionService* session_service =
687 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
688 if (session_service)
689 session_service->TabRestored(contents_dupe, pinned);
690 return contents_dupe;
693 bool CanDuplicateTabAt(Browser* browser, int index) {
694 content::NavigationController& nc =
695 browser->tab_strip_model()->GetWebContentsAt(index)->GetController();
696 return nc.GetWebContents() && nc.GetLastCommittedEntry();
699 void ConvertPopupToTabbedBrowser(Browser* browser) {
700 content::RecordAction(UserMetricsAction("ShowAsTab"));
701 TabStripModel* tab_strip = browser->tab_strip_model();
702 WebContents* contents =
703 tab_strip->DetachWebContentsAt(tab_strip->active_index());
704 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
705 browser->host_desktop_type()));
706 b->tab_strip_model()->AppendWebContents(contents, true);
707 b->window()->Show();
710 void Exit() {
711 content::RecordAction(UserMetricsAction("Exit"));
712 chrome::AttemptUserExit();
715 void BookmarkCurrentPage(Browser* browser) {
716 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
718 const extensions::Extension* extension = NULL;
719 extensions::Command command;
720 extensions::CommandService::ExtensionCommandType command_type;
721 if (GetBookmarkOverrideCommand(browser->profile(),
722 &extension,
723 &command,
724 &command_type)) {
725 switch (command_type) {
726 case extensions::CommandService::NAMED:
727 browser->window()->ExecuteExtensionCommand(extension, command);
728 return;
730 case extensions::CommandService::BROWSER_ACTION:
731 // BookmarkCurrentPage is called through a user gesture, so it is safe
732 // to call ShowBrowserActionPopup.
733 browser->window()->ShowBrowserActionPopup(extension);
734 return;
736 case extensions::CommandService::PAGE_ACTION:
737 browser->window()->ShowPageActionPopup(extension);
738 return;
742 BookmarkCurrentPageInternal(browser);
745 bool CanBookmarkCurrentPage(const Browser* browser) {
746 return CanBookmarkCurrentPageInternal(browser, true);
749 void BookmarkAllTabs(Browser* browser) {
750 chrome::ShowBookmarkAllTabsDialog(browser);
753 bool CanBookmarkAllTabs(const Browser* browser) {
754 return browser->tab_strip_model()->count() > 1 &&
755 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
756 CanBookmarkCurrentPageInternal(browser, false);
759 void Translate(Browser* browser) {
760 if (!browser->window()->IsActive())
761 return;
763 WebContents* web_contents =
764 browser->tab_strip_model()->GetActiveWebContents();
765 TranslateTabHelper* translate_tab_helper =
766 TranslateTabHelper::FromWebContents(web_contents);
768 translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
769 if (translate_tab_helper) {
770 if (translate_tab_helper->GetLanguageState().translation_pending())
771 step = translate::TRANSLATE_STEP_TRANSLATING;
772 else if (translate_tab_helper->GetLanguageState().IsPageTranslated())
773 step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
775 browser->window()->ShowTranslateBubble(
776 web_contents, step, TranslateErrors::NONE);
779 void ManagePasswordsForPage(Browser* browser) {
780 // TODO(mkwst): Implement this feature on Mac: http://crbug.com/261628
781 #if !defined(OS_MACOSX)
782 if (!browser->window()->IsActive())
783 return;
785 WebContents* web_contents =
786 browser->tab_strip_model()->GetActiveWebContents();
787 chrome::ShowManagePasswordsBubble(web_contents);
788 #endif
791 void TogglePagePinnedToStartScreen(Browser* browser) {
792 #if defined(OS_WIN)
793 MetroPinTabHelper::FromWebContents(
794 browser->tab_strip_model()->GetActiveWebContents())->
795 TogglePinnedToStartScreen();
796 #endif
799 void SavePage(Browser* browser) {
800 content::RecordAction(UserMetricsAction("SavePage"));
801 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
802 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
803 content::RecordAction(UserMetricsAction("PDF.SavePage"));
804 current_tab->OnSavePage();
807 bool CanSavePage(const Browser* browser) {
808 // LocalState can be NULL in tests.
809 if (g_browser_process->local_state() &&
810 !g_browser_process->local_state()->GetBoolean(
811 prefs::kAllowFileSelectionDialogs)) {
812 return false;
814 return !browser->is_devtools() &&
815 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
818 void ShowFindBar(Browser* browser) {
819 browser->GetFindBarController()->Show();
822 void ShowWebsiteSettings(Browser* browser,
823 content::WebContents* web_contents,
824 const GURL& url,
825 const SSLStatus& ssl) {
826 browser->window()->ShowWebsiteSettings(
827 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
828 web_contents, url, ssl);
832 void Print(Browser* browser) {
833 #if defined(ENABLE_PRINTING)
834 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
835 #if defined(ENABLE_FULL_PRINTING)
836 printing::PrintViewManager* print_view_manager =
837 printing::PrintViewManager::FromWebContents(contents);
838 if (browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled))
839 print_view_manager->PrintNow();
840 else
841 print_view_manager->PrintPreviewNow(false);
842 #else
843 printing::PrintViewManagerBasic* print_view_manager =
844 printing::PrintViewManagerBasic::FromWebContents(contents);
845 print_view_manager->PrintNow();
846 #endif // defined(ENABLE_FULL_PRINTING)
847 #endif // defined(ENABLE_PRINTING)
850 bool CanPrint(const Browser* browser) {
851 // Do not print when printing is disabled via pref or policy.
852 // Do not print when a constrained window is showing. It's confusing.
853 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
854 !(IsShowingWebContentsModalDialog(browser) ||
855 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
858 void AdvancedPrint(Browser* browser) {
859 #if defined(ENABLE_FULL_PRINTING)
860 printing::PrintViewManager* print_view_manager =
861 printing::PrintViewManager::FromWebContents(
862 browser->tab_strip_model()->GetActiveWebContents());
863 print_view_manager->AdvancedPrintNow();
864 #endif
867 bool CanAdvancedPrint(const Browser* browser) {
868 // If printing is not disabled via pref or policy, it is always possible to
869 // advanced print when the print preview is visible. The exception to this
870 // is under Win8 ash, since showing the advanced print dialog will open it
871 // modally on the Desktop and hang the browser. We can remove this check
872 // once we integrate with the system print charm.
873 #if defined(OS_WIN)
874 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
875 return false;
876 #endif
878 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
879 (PrintPreviewShowing(browser) || CanPrint(browser));
882 void PrintToDestination(Browser* browser) {
883 #if defined(ENABLE_FULL_PRINTING)
884 printing::PrintViewManager* print_view_manager =
885 printing::PrintViewManager::FromWebContents(
886 browser->tab_strip_model()->GetActiveWebContents());
887 print_view_manager->PrintToDestination();
888 #endif
891 void EmailPageLocation(Browser* browser) {
892 content::RecordAction(UserMetricsAction("EmailPageLocation"));
893 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
894 DCHECK(wc);
896 std::string title = net::EscapeQueryParamValue(
897 base::UTF16ToUTF8(wc->GetTitle()), false);
898 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
899 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
900 title + "&body=%0A%0A" + page_url;
901 platform_util::OpenExternal(browser->profile(), GURL(mailto));
904 bool CanEmailPageLocation(const Browser* browser) {
905 return browser->toolbar_model()->ShouldDisplayURL() &&
906 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
909 void Cut(Browser* browser) {
910 content::RecordAction(UserMetricsAction("Cut"));
911 browser->window()->Cut();
914 void Copy(Browser* browser) {
915 content::RecordAction(UserMetricsAction("Copy"));
916 browser->window()->Copy();
919 void Paste(Browser* browser) {
920 content::RecordAction(UserMetricsAction("Paste"));
921 browser->window()->Paste();
924 void Find(Browser* browser) {
925 content::RecordAction(UserMetricsAction("Find"));
926 FindInPage(browser, false, false);
929 void FindNext(Browser* browser) {
930 content::RecordAction(UserMetricsAction("FindNext"));
931 FindInPage(browser, true, true);
934 void FindPrevious(Browser* browser) {
935 content::RecordAction(UserMetricsAction("FindPrevious"));
936 FindInPage(browser, true, false);
939 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
940 ShowFindBar(browser);
941 if (find_next) {
942 base::string16 find_text;
943 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
944 browser->tab_strip_model()->GetActiveWebContents());
945 #if defined(OS_MACOSX)
946 // We always want to search for the current contents of the find bar on
947 // OS X. For regular profile it's always the current find pboard. For
948 // Incognito window it's the newest value of the find pboard content and
949 // user-typed text.
950 FindBar* find_bar = browser->GetFindBarController()->find_bar();
951 find_text = find_bar->GetFindText();
952 #endif
953 find_helper->StartFinding(find_text, forward_direction, false);
957 void Zoom(Browser* browser, content::PageZoom zoom) {
958 chrome_page_zoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
959 zoom);
962 void FocusToolbar(Browser* browser) {
963 content::RecordAction(UserMetricsAction("FocusToolbar"));
964 browser->window()->FocusToolbar();
967 void FocusLocationBar(Browser* browser) {
968 content::RecordAction(UserMetricsAction("FocusLocation"));
969 browser->window()->SetFocusToLocationBar(true);
972 void FocusSearch(Browser* browser) {
973 // TODO(beng): replace this with FocusLocationBar
974 content::RecordAction(UserMetricsAction("FocusSearch"));
975 browser->window()->GetLocationBar()->FocusSearch();
978 void FocusAppMenu(Browser* browser) {
979 content::RecordAction(UserMetricsAction("FocusAppMenu"));
980 browser->window()->FocusAppMenu();
983 void FocusBookmarksToolbar(Browser* browser) {
984 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
985 browser->window()->FocusBookmarksToolbar();
988 void FocusInfobars(Browser* browser) {
989 content::RecordAction(UserMetricsAction("FocusInfobars"));
990 browser->window()->FocusInfobars();
993 void FocusNextPane(Browser* browser) {
994 content::RecordAction(UserMetricsAction("FocusNextPane"));
995 browser->window()->RotatePaneFocus(true);
998 void FocusPreviousPane(Browser* browser) {
999 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1000 browser->window()->RotatePaneFocus(false);
1003 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1004 if (action.type() == DevToolsToggleAction::kShowConsole)
1005 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1006 else
1007 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1008 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1011 bool CanOpenTaskManager() {
1012 #if defined(ENABLE_TASK_MANAGER)
1013 return true;
1014 #else
1015 return false;
1016 #endif
1019 void OpenTaskManager(Browser* browser) {
1020 #if defined(ENABLE_TASK_MANAGER)
1021 content::RecordAction(UserMetricsAction("TaskManager"));
1022 chrome::ShowTaskManager(browser);
1023 #else
1024 NOTREACHED();
1025 #endif
1028 void OpenFeedbackDialog(Browser* browser) {
1029 content::RecordAction(UserMetricsAction("Feedback"));
1030 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1033 void ToggleBookmarkBar(Browser* browser) {
1034 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1035 ToggleBookmarkBarWhenVisible(browser->profile());
1038 void ShowAppMenu(Browser* browser) {
1039 // We record the user metric for this event in WrenchMenu::RunMenu.
1040 browser->window()->ShowAppMenu();
1043 void ShowAvatarMenu(Browser* browser) {
1044 browser->window()->ShowAvatarBubbleFromAvatarButton(
1045 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1046 signin::GAIA_SERVICE_TYPE_NONE);
1049 void OpenUpdateChromeDialog(Browser* browser) {
1050 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1051 content::NotificationService::current()->Notify(
1052 chrome::NOTIFICATION_OUTDATED_INSTALL,
1053 content::NotificationService::AllSources(),
1054 content::NotificationService::NoDetails());
1055 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1056 content::NotificationService::current()->Notify(
1057 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1058 content::NotificationService::AllSources(),
1059 content::NotificationService::NoDetails());
1060 } else {
1061 content::RecordAction(UserMetricsAction("UpdateChrome"));
1062 browser->window()->ShowUpdateChromeDialog();
1066 void ToggleSpeechInput(Browser* browser) {
1067 SearchTabHelper* search_tab_helper =
1068 SearchTabHelper::FromWebContents(
1069 browser->tab_strip_model()->GetActiveWebContents());
1070 // |search_tab_helper| can be null in unit tests.
1071 if (search_tab_helper)
1072 search_tab_helper->ToggleVoiceSearch();
1075 void DistillCurrentPage(Browser* browser) {
1076 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1079 bool CanRequestTabletSite(WebContents* current_tab) {
1080 return current_tab &&
1081 current_tab->GetController().GetLastCommittedEntry() != NULL;
1084 bool IsRequestingTabletSite(Browser* browser) {
1085 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1086 if (!current_tab)
1087 return false;
1088 content::NavigationEntry* entry =
1089 current_tab->GetController().GetLastCommittedEntry();
1090 if (!entry)
1091 return false;
1092 return entry->GetIsOverridingUserAgent();
1095 void ToggleRequestTabletSite(Browser* browser) {
1096 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1097 if (!current_tab)
1098 return;
1099 NavigationController& controller = current_tab->GetController();
1100 NavigationEntry* entry = controller.GetLastCommittedEntry();
1101 if (!entry)
1102 return;
1103 if (entry->GetIsOverridingUserAgent()) {
1104 entry->SetIsOverridingUserAgent(false);
1105 } else {
1106 entry->SetIsOverridingUserAgent(true);
1107 chrome::VersionInfo version_info;
1108 std::string product;
1109 if (version_info.is_valid())
1110 product = version_info.ProductNameAndVersionForUserAgent();
1111 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1112 kOsOverrideForTabletSite, product));
1114 controller.ReloadOriginalRequestURL(true);
1117 void ToggleFullscreenMode(Browser* browser) {
1118 DCHECK(browser);
1119 browser->fullscreen_controller()->ToggleBrowserFullscreenMode();
1122 void ClearCache(Browser* browser) {
1123 BrowsingDataRemover* remover =
1124 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1125 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1126 BrowsingDataHelper::UNPROTECTED_WEB);
1127 // BrowsingDataRemover takes care of deleting itself when done.
1130 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1131 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1132 return contents ?
1133 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1136 void ViewSource(Browser* browser, WebContents* contents) {
1137 DCHECK(contents);
1139 // Use the last committed entry, since the pending entry hasn't loaded yet and
1140 // won't be copied into the cloned tab.
1141 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1142 if (!entry)
1143 return;
1145 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1148 void ViewSource(Browser* browser,
1149 WebContents* contents,
1150 const GURL& url,
1151 const content::PageState& page_state) {
1152 content::RecordAction(UserMetricsAction("ViewSource"));
1153 DCHECK(contents);
1155 WebContents* view_source_contents = contents->Clone();
1156 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1157 view_source_contents->GetController().PruneAllButLastCommitted();
1158 NavigationEntry* last_committed_entry =
1159 view_source_contents->GetController().GetLastCommittedEntry();
1160 if (!last_committed_entry)
1161 return;
1163 GURL view_source_url =
1164 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1165 last_committed_entry->SetVirtualURL(view_source_url);
1167 // Do not restore scroller position.
1168 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1170 // Do not restore title, derive it from the url.
1171 last_committed_entry->SetTitle(base::string16());
1173 // Now show view-source entry.
1174 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1175 // If this is a tabbed browser, just create a duplicate tab inside the same
1176 // window next to the tab being duplicated.
1177 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1178 int add_types = TabStripModel::ADD_ACTIVE |
1179 TabStripModel::ADD_INHERIT_GROUP;
1180 browser->tab_strip_model()->InsertWebContentsAt(
1181 index + 1,
1182 view_source_contents,
1183 add_types);
1184 } else {
1185 Browser* b = new Browser(
1186 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1187 browser->host_desktop_type()));
1189 // Preserve the size of the original window. The new window has already
1190 // been given an offset by the OS, so we shouldn't copy the old bounds.
1191 BrowserWindow* new_window = b->window();
1192 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1193 browser->window()->GetRestoredBounds().size()));
1195 // We need to show the browser now. Otherwise ContainerWin assumes the
1196 // WebContents is invisible and won't size it.
1197 b->window()->Show();
1199 // The page transition below is only for the purpose of inserting the tab.
1200 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1201 content::PAGE_TRANSITION_LINK,
1202 TabStripModel::ADD_ACTIVE);
1205 SessionService* session_service =
1206 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1207 if (session_service)
1208 session_service->TabRestored(view_source_contents, false);
1211 void ViewSelectedSource(Browser* browser) {
1212 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1215 bool CanViewSource(const Browser* browser) {
1216 return !browser->is_devtools() &&
1217 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1218 CanViewSource();
1221 void CreateApplicationShortcuts(Browser* browser) {
1222 content::RecordAction(UserMetricsAction("CreateShortcut"));
1223 extensions::TabHelper::FromWebContents(
1224 browser->tab_strip_model()->GetActiveWebContents())->
1225 CreateApplicationShortcuts();
1228 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1229 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1230 extensions::TabHelper::FromWebContents(
1231 browser->tab_strip_model()->GetActiveWebContents())->
1232 CreateHostedAppFromWebContents();
1235 bool CanCreateApplicationShortcuts(const Browser* browser) {
1236 return extensions::TabHelper::FromWebContents(
1237 browser->tab_strip_model()->GetActiveWebContents())->
1238 CanCreateApplicationShortcuts();
1241 bool CanCreateBookmarkApp(const Browser* browser) {
1242 return extensions::TabHelper::FromWebContents(
1243 browser->tab_strip_model()->GetActiveWebContents())
1244 ->CanCreateBookmarkApp();
1247 void ConvertTabToAppWindow(Browser* browser,
1248 content::WebContents* contents) {
1249 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1250 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1252 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1253 if (index >= 0)
1254 browser->tab_strip_model()->DetachWebContentsAt(index);
1256 Browser* app_browser = new Browser(
1257 Browser::CreateParams::CreateForApp(app_name,
1258 true /* trusted_source */,
1259 gfx::Rect(),
1260 browser->profile(),
1261 browser->host_desktop_type()));
1262 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1264 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1265 contents->GetRenderViewHost()->SyncRendererPrefs();
1266 app_browser->window()->Show();
1269 } // namespace chrome