Componentize AccountReconcilor.
[chromium-blink-merge.git] / chrome / browser / ui / browser_commands.cc
blob94d132ee620cffe22210800a049917dba702d94c
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.h"
13 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
14 #include "chrome/browser/bookmarks/bookmark_utils.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/browsing_data/browsing_data_helper.h"
17 #include "chrome/browser/browsing_data/browsing_data_remover.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/chrome_page_zoom.h"
20 #include "chrome/browser/devtools/devtools_window.h"
21 #include "chrome/browser/extensions/api/commands/command_service.h"
22 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/browser/extensions/tab_helper.h"
24 #include "chrome/browser/favicon/favicon_tab_helper.h"
25 #include "chrome/browser/google/google_util.h"
26 #include "chrome/browser/lifetime/application_lifetime.h"
27 #include "chrome/browser/platform_util.h"
28 #include "chrome/browser/prefs/incognito_mode_prefs.h"
29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/rlz/rlz.h"
31 #include "chrome/browser/search/search.h"
32 #include "chrome/browser/sessions/session_service_factory.h"
33 #include "chrome/browser/sessions/tab_restore_service.h"
34 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
35 #include "chrome/browser/sessions/tab_restore_service_factory.h"
36 #include "chrome/browser/translate/translate_tab_helper.h"
37 #include "chrome/browser/ui/accelerator_utils.h"
38 #include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h"
39 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
40 #include "chrome/browser/ui/browser.h"
41 #include "chrome/browser/ui/browser_command_controller.h"
42 #include "chrome/browser/ui/browser_dialogs.h"
43 #include "chrome/browser/ui/browser_instant_controller.h"
44 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
45 #include "chrome/browser/ui/browser_tabstrip.h"
46 #include "chrome/browser/ui/browser_window.h"
47 #include "chrome/browser/ui/chrome_pages.h"
48 #include "chrome/browser/ui/find_bar/find_bar.h"
49 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
50 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
51 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
52 #include "chrome/browser/ui/omnibox/location_bar.h"
53 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
54 #include "chrome/browser/ui/search/search_tab_helper.h"
55 #include "chrome/browser/ui/status_bubble.h"
56 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
57 #include "chrome/browser/ui/tabs/tab_strip_model.h"
58 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
59 #include "chrome/browser/upgrade_detector.h"
60 #include "chrome/browser/web_applications/web_app.h"
61 #include "chrome/common/chrome_switches.h"
62 #include "chrome/common/chrome_version_info.h"
63 #include "chrome/common/content_restriction.h"
64 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
65 #include "chrome/common/pref_names.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/browser/web_contents_view.h"
77 #include "content/public/common/renderer_preferences.h"
78 #include "content/public/common/url_constants.h"
79 #include "content/public/common/url_utils.h"
80 #include "content/public/common/user_agent.h"
81 #include "extensions/browser/extension_system.h"
82 #include "net/base/escape.h"
83 #include "ui/events/keycodes/keyboard_codes.h"
85 #if defined(OS_WIN)
86 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
87 #include "win8/util/win8_util.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 ExtensionService* extension_service =
144 extensions::ExtensionSystem::Get(profile)->extension_service();
145 // Extension service may be NULL during test execution.
146 if (!extension_service)
147 return false;
148 const extensions::ExtensionSet* extension_set =
149 extension_service->extensions();
150 for (extensions::ExtensionSet::const_iterator i = extension_set->begin();
151 i != extension_set->end(); ++i) {
152 extensions::Command prospective_command;
153 extensions::CommandService::ExtensionCommandType prospective_command_type;
154 if (command_service->GetBoundExtensionCommand((*i)->id(),
155 bookmark_page_accelerator,
156 &prospective_command,
157 &prospective_command_type)) {
158 *extension = i->get();
159 *command = prospective_command;
160 *command_type = prospective_command_type;
161 return true;
165 return false;
168 void BookmarkCurrentPageInternal(Browser* browser, bool from_star) {
169 content::RecordAction(UserMetricsAction("Star"));
171 BookmarkModel* model =
172 BookmarkModelFactory::GetForProfile(browser->profile());
173 if (!model || !model->loaded())
174 return; // Ignore requests until bookmarks are loaded.
176 GURL url;
177 base::string16 title;
178 WebContents* web_contents =
179 browser->tab_strip_model()->GetActiveWebContents();
180 GetURLAndTitleToBookmark(web_contents, &url, &title);
181 bool was_bookmarked = model->IsBookmarked(url);
182 if (!was_bookmarked && web_contents->GetBrowserContext()->IsOffTheRecord()) {
183 // If we're incognito the favicon may not have been saved. Save it now
184 // so that bookmarks have an icon for the page.
185 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
187 bookmark_utils::AddIfNotBookmarked(model, url, title);
188 if (from_star && !was_bookmarked)
189 BookmarkPromptController::AddedBookmark(browser, url);
190 // Make sure the model actually added a bookmark before showing the star. A
191 // bookmark isn't created if the url is invalid.
192 if (browser->window()->IsActive() && model->IsBookmarked(url)) {
193 // Only show the bubble if the window is active, otherwise we may get into
194 // weird situations where the bubble is deleted as soon as it is shown.
195 browser->window()->ShowBookmarkBubble(url, was_bookmarked);
199 // Based on |disposition|, creates a new tab as necessary, and returns the
200 // appropriate tab to navigate. If that tab is the current tab, reverts the
201 // location bar contents, since all browser-UI-triggered navigations should
202 // revert any omnibox edits in the current tab.
203 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
204 WindowOpenDisposition disposition) {
205 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
206 switch (disposition) {
207 case NEW_FOREGROUND_TAB:
208 case NEW_BACKGROUND_TAB: {
209 WebContents* new_tab = current_tab->Clone();
210 browser->tab_strip_model()->AddWebContents(
211 new_tab, -1, content::PAGE_TRANSITION_LINK,
212 (disposition == NEW_FOREGROUND_TAB) ?
213 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
214 return new_tab;
216 case NEW_WINDOW: {
217 WebContents* new_tab = current_tab->Clone();
218 Browser* new_browser = new Browser(Browser::CreateParams(
219 browser->profile(), browser->host_desktop_type()));
220 new_browser->tab_strip_model()->AddWebContents(
221 new_tab, -1, content::PAGE_TRANSITION_LINK,
222 TabStripModel::ADD_ACTIVE);
223 new_browser->window()->Show();
224 return new_tab;
226 default:
227 browser->window()->GetLocationBar()->Revert();
228 return current_tab;
232 void ReloadInternal(Browser* browser,
233 WindowOpenDisposition disposition,
234 bool ignore_cache) {
235 // As this is caused by a user action, give the focus to the page.
237 // Also notify RenderViewHostDelegate of the user gesture; this is
238 // normally done in Browser::Navigate, but a reload bypasses Navigate.
239 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
240 new_tab->UserGestureDone();
241 if (!new_tab->FocusLocationBarByDefault())
242 new_tab->GetView()->Focus();
243 if (ignore_cache)
244 new_tab->GetController().ReloadIgnoringCache(true);
245 else
246 new_tab->GetController().Reload(true);
249 bool IsShowingWebContentsModalDialog(const Browser* browser) {
250 WebContents* web_contents =
251 browser->tab_strip_model()->GetActiveWebContents();
252 if (!web_contents)
253 return false;
255 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
256 WebContentsModalDialogManager::FromWebContents(web_contents);
257 return web_contents_modal_dialog_manager->IsDialogActive();
260 bool PrintPreviewShowing(const Browser* browser) {
261 #if defined(ENABLE_FULL_PRINTING)
262 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
263 printing::PrintPreviewDialogController* controller =
264 printing::PrintPreviewDialogController::GetInstance();
265 return controller && (controller->GetPrintPreviewForContents(contents) ||
266 controller->is_creating_print_preview_dialog());
267 #else
268 return false;
269 #endif
272 } // namespace
274 bool IsCommandEnabled(Browser* browser, int command) {
275 return browser->command_controller()->command_updater()->IsCommandEnabled(
276 command);
279 bool SupportsCommand(Browser* browser, int command) {
280 return browser->command_controller()->command_updater()->SupportsCommand(
281 command);
284 bool ExecuteCommand(Browser* browser, int command) {
285 return browser->command_controller()->command_updater()->ExecuteCommand(
286 command);
289 bool ExecuteCommandWithDisposition(Browser* browser,
290 int command,
291 WindowOpenDisposition disposition) {
292 return browser->command_controller()->command_updater()->
293 ExecuteCommandWithDisposition(command, disposition);
296 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
297 browser->command_controller()->command_updater()->UpdateCommandEnabled(
298 command, enabled);
301 void AddCommandObserver(Browser* browser,
302 int command,
303 CommandObserver* observer) {
304 browser->command_controller()->command_updater()->AddCommandObserver(
305 command, observer);
308 void RemoveCommandObserver(Browser* browser,
309 int command,
310 CommandObserver* observer) {
311 browser->command_controller()->command_updater()->RemoveCommandObserver(
312 command, observer);
315 int GetContentRestrictions(const Browser* browser) {
316 int content_restrictions = 0;
317 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
318 if (current_tab) {
319 CoreTabHelper* core_tab_helper =
320 CoreTabHelper::FromWebContents(current_tab);
321 content_restrictions = core_tab_helper->content_restrictions();
322 NavigationEntry* active_entry =
323 current_tab->GetController().GetActiveEntry();
324 // See comment in UpdateCommandsForTabState about why we call url().
325 if (!content::IsSavableURL(
326 active_entry ? active_entry->GetURL() : GURL()) ||
327 current_tab->ShowingInterstitialPage())
328 content_restrictions |= CONTENT_RESTRICTION_SAVE;
329 if (current_tab->ShowingInterstitialPage())
330 content_restrictions |= CONTENT_RESTRICTION_PRINT;
332 return content_restrictions;
335 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
336 bool incognito = profile->IsOffTheRecord();
337 PrefService* prefs = profile->GetPrefs();
338 if (incognito) {
339 if (IncognitoModePrefs::GetAvailability(prefs) ==
340 IncognitoModePrefs::DISABLED) {
341 incognito = false;
343 } else {
344 if (browser_defaults::kAlwaysOpenIncognitoWindow &&
345 IncognitoModePrefs::ShouldLaunchIncognito(
346 *CommandLine::ForCurrentProcess(), prefs)) {
347 incognito = true;
351 if (incognito) {
352 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
353 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
354 } else {
355 content::RecordAction(UserMetricsAction("NewWindow"));
356 SessionService* session_service =
357 SessionServiceFactory::GetForProfileForSessionRestore(
358 profile->GetOriginalProfile());
359 if (!session_service ||
360 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
361 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
366 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
367 Browser* browser = new Browser(
368 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
369 AddTabAt(browser, GURL(), -1, true);
370 browser->window()->Show();
371 return browser;
374 void OpenWindowWithRestoredTabs(Profile* profile,
375 HostDesktopType host_desktop_type) {
376 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
377 if (service)
378 service->RestoreMostRecentEntry(NULL, host_desktop_type);
381 void OpenURLOffTheRecord(Profile* profile,
382 const GURL& url,
383 chrome::HostDesktopType desktop_type) {
384 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
385 desktop_type);
386 AddSelectedTabWithURL(displayer.browser(), url,
387 content::PAGE_TRANSITION_LINK);
390 bool CanGoBack(const Browser* browser) {
391 return browser->tab_strip_model()->GetActiveWebContents()->
392 GetController().CanGoBack();
395 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
396 content::RecordAction(UserMetricsAction("Back"));
398 if (CanGoBack(browser)) {
399 WebContents* current_tab =
400 browser->tab_strip_model()->GetActiveWebContents();
401 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
402 // If we are on an interstitial page and clone the tab, it won't be copied
403 // to the new tab, so we don't need to go back.
404 if ((new_tab == current_tab) || !current_tab->ShowingInterstitialPage())
405 new_tab->GetController().GoBack();
409 bool CanGoForward(const Browser* browser) {
410 return browser->tab_strip_model()->GetActiveWebContents()->
411 GetController().CanGoForward();
414 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
415 content::RecordAction(UserMetricsAction("Forward"));
416 if (CanGoForward(browser)) {
417 GetTabAndRevertIfNecessary(browser, disposition)->
418 GetController().GoForward();
422 bool NavigateToIndexWithDisposition(Browser* browser,
423 int index,
424 WindowOpenDisposition disposition) {
425 NavigationController* controller =
426 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
427 if (index < 0 || index >= controller->GetEntryCount())
428 return false;
429 controller->GoToIndex(index);
430 return true;
433 void Reload(Browser* browser, WindowOpenDisposition disposition) {
434 content::RecordAction(UserMetricsAction("Reload"));
435 ReloadInternal(browser, disposition, false);
438 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
439 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
440 ReloadInternal(browser, disposition, true);
443 bool CanReload(const Browser* browser) {
444 return !browser->is_devtools();
447 void Home(Browser* browser, WindowOpenDisposition disposition) {
448 content::RecordAction(UserMetricsAction("Home"));
450 std::string extra_headers;
451 #if defined(ENABLE_RLZ)
452 // If the home page is a Google home page, add the RLZ header to the request.
453 PrefService* pref_service = browser->profile()->GetPrefs();
454 if (pref_service) {
455 if (google_util::IsGoogleHomePageUrl(
456 GURL(pref_service->GetString(prefs::kHomePage)))) {
457 extra_headers = RLZTracker::GetAccessPointHttpHeader(
458 RLZTracker::CHROME_HOME_PAGE);
461 #endif
463 GURL url = browser->profile()->GetHomePage();
465 // Streamlined hosted apps should return to their launch page when the home
466 // button is pressed.
467 if (browser->is_app()) {
468 const ExtensionService* service = browser->profile()->GetExtensionService();
469 if (!service)
470 return;
472 const extensions::Extension* extension =
473 service->GetInstalledExtension(
474 web_app::GetExtensionIdFromApplicationName(browser->app_name()));
475 if (!extension)
476 return;
478 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
481 OpenURLParams params(
482 url, Referrer(), disposition,
483 content::PageTransitionFromInt(
484 content::PAGE_TRANSITION_AUTO_BOOKMARK |
485 content::PAGE_TRANSITION_HOME_PAGE),
486 false);
487 params.extra_headers = extra_headers;
488 browser->OpenURL(params);
491 void OpenCurrentURL(Browser* browser) {
492 content::RecordAction(UserMetricsAction("LoadURL"));
493 LocationBar* location_bar = browser->window()->GetLocationBar();
494 if (!location_bar)
495 return;
497 GURL url(location_bar->GetDestinationURL());
499 content::PageTransition page_transition = location_bar->GetPageTransition();
500 content::PageTransition page_transition_without_qualifier(
501 PageTransitionStripQualifier(page_transition));
502 WindowOpenDisposition open_disposition =
503 location_bar->GetWindowOpenDisposition();
504 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
505 // open URLs with instant_controller since in some cases it disregards it
506 // and performs a search instead. For example, when using CTRL-Enter, the
507 // location_bar is aware of the URL but instant is not.
508 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
509 // of the omnibox text may be stale if the user focuses in the omnibox and
510 // presses enter without typing anything.
511 if (page_transition_without_qualifier != content::PAGE_TRANSITION_TYPED &&
512 page_transition_without_qualifier != content::PAGE_TRANSITION_RELOAD &&
513 browser->instant_controller() &&
514 browser->instant_controller()->OpenInstant(open_disposition, url))
515 return;
517 NavigateParams params(browser, url, page_transition);
518 params.disposition = open_disposition;
519 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
520 // inherit the opener. In some cases the tabstrip will determine the group
521 // should be inherited, in which case the group is inherited instead of the
522 // opener.
523 params.tabstrip_add_types =
524 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
525 Navigate(&params);
527 DCHECK(browser->profile()->GetExtensionService());
528 const extensions::Extension* extension =
529 browser->profile()->GetExtensionService()->GetInstalledApp(url);
530 if (extension) {
531 CoreAppLauncherHandler::RecordAppLaunchType(
532 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
533 extension->GetType());
537 void Stop(Browser* browser) {
538 content::RecordAction(UserMetricsAction("Stop"));
539 browser->tab_strip_model()->GetActiveWebContents()->Stop();
542 #if !defined(OS_WIN)
543 void NewWindow(Browser* browser) {
544 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
545 browser->host_desktop_type());
548 void NewIncognitoWindow(Browser* browser) {
549 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
550 browser->host_desktop_type());
552 #endif // OS_WIN
554 void CloseWindow(Browser* browser) {
555 content::RecordAction(UserMetricsAction("CloseWindow"));
556 browser->window()->Close();
559 void NewTab(Browser* browser) {
560 content::RecordAction(UserMetricsAction("NewTab"));
561 // TODO(asvitkine): This is invoked programmatically from several places.
562 // Audit the code and change it so that the histogram only gets collected for
563 // user-initiated commands.
564 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
565 TabStripModel::NEW_TAB_ENUM_COUNT);
567 if (browser->is_type_tabbed()) {
568 AddTabAt(browser, GURL(), -1, true);
569 browser->tab_strip_model()->GetActiveWebContents()->GetView()->
570 RestoreFocus();
571 } else {
572 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
573 browser->host_desktop_type());
574 Browser* b = displayer.browser();
575 AddTabAt(b, GURL(), -1, true);
576 b->window()->Show();
577 // The call to AddBlankTabAt above did not set the focus to the tab as its
578 // window was not active, so we have to do it explicitly.
579 // See http://crbug.com/6380.
580 b->tab_strip_model()->GetActiveWebContents()->GetView()->RestoreFocus();
584 void CloseTab(Browser* browser) {
585 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
586 browser->tab_strip_model()->CloseSelectedTabs();
589 void RestoreTab(Browser* browser) {
590 content::RecordAction(UserMetricsAction("RestoreTab"));
591 TabRestoreService* service =
592 TabRestoreServiceFactory::GetForProfile(browser->profile());
593 if (service)
594 service->RestoreMostRecentEntry(browser->tab_restore_service_delegate(),
595 browser->host_desktop_type());
598 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
599 const Browser* browser) {
600 TabRestoreService* service =
601 TabRestoreServiceFactory::GetForProfile(browser->profile());
602 if (!service || service->entries().empty())
603 return TabStripModelDelegate::RESTORE_NONE;
604 if (service->entries().front()->type == TabRestoreService::WINDOW)
605 return TabStripModelDelegate::RESTORE_WINDOW;
606 return TabStripModelDelegate::RESTORE_TAB;
609 void SelectNextTab(Browser* browser) {
610 content::RecordAction(UserMetricsAction("SelectNextTab"));
611 browser->tab_strip_model()->SelectNextTab();
614 void SelectPreviousTab(Browser* browser) {
615 content::RecordAction(UserMetricsAction("SelectPrevTab"));
616 browser->tab_strip_model()->SelectPreviousTab();
619 void MoveTabNext(Browser* browser) {
620 content::RecordAction(UserMetricsAction("MoveTabNext"));
621 browser->tab_strip_model()->MoveTabNext();
624 void MoveTabPrevious(Browser* browser) {
625 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
626 browser->tab_strip_model()->MoveTabPrevious();
629 void SelectNumberedTab(Browser* browser, int index) {
630 if (index < browser->tab_strip_model()->count()) {
631 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
632 browser->tab_strip_model()->ActivateTabAt(index, true);
636 void SelectLastTab(Browser* browser) {
637 content::RecordAction(UserMetricsAction("SelectLastTab"));
638 browser->tab_strip_model()->SelectLastTab();
641 void DuplicateTab(Browser* browser) {
642 content::RecordAction(UserMetricsAction("Duplicate"));
643 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
646 bool CanDuplicateTab(const Browser* browser) {
647 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
648 return contents && contents->GetController().GetLastCommittedEntry();
651 WebContents* DuplicateTabAt(Browser* browser, int index) {
652 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
653 CHECK(contents);
654 WebContents* contents_dupe = contents->Clone();
656 bool pinned = false;
657 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
658 // If this is a tabbed browser, just create a duplicate tab inside the same
659 // window next to the tab being duplicated.
660 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
661 pinned = browser->tab_strip_model()->IsTabPinned(index);
662 int add_types = TabStripModel::ADD_ACTIVE |
663 TabStripModel::ADD_INHERIT_GROUP |
664 (pinned ? TabStripModel::ADD_PINNED : 0);
665 browser->tab_strip_model()->InsertWebContentsAt(
666 index + 1, contents_dupe, add_types);
667 } else {
668 Browser* new_browser = NULL;
669 if (browser->is_app() &&
670 !browser->is_type_popup()) {
671 new_browser = new Browser(
672 Browser::CreateParams::CreateForApp(browser->type(),
673 browser->app_name(),
674 gfx::Rect(),
675 browser->profile(),
676 browser->host_desktop_type()));
677 } else {
678 new_browser = new Browser(
679 Browser::CreateParams(browser->type(), browser->profile(),
680 browser->host_desktop_type()));
682 // Preserve the size of the original window. The new window has already
683 // been given an offset by the OS, so we shouldn't copy the old bounds.
684 BrowserWindow* new_window = new_browser->window();
685 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
686 browser->window()->GetRestoredBounds().size()));
688 // We need to show the browser now. Otherwise ContainerWin assumes the
689 // WebContents is invisible and won't size it.
690 new_browser->window()->Show();
692 // The page transition below is only for the purpose of inserting the tab.
693 new_browser->tab_strip_model()->AddWebContents(
694 contents_dupe, -1,
695 content::PAGE_TRANSITION_LINK,
696 TabStripModel::ADD_ACTIVE);
699 SessionService* session_service =
700 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
701 if (session_service)
702 session_service->TabRestored(contents_dupe, pinned);
703 return contents_dupe;
706 bool CanDuplicateTabAt(Browser* browser, int index) {
707 content::NavigationController& nc =
708 browser->tab_strip_model()->GetWebContentsAt(index)->GetController();
709 return nc.GetWebContents() && nc.GetLastCommittedEntry();
712 void ConvertPopupToTabbedBrowser(Browser* browser) {
713 content::RecordAction(UserMetricsAction("ShowAsTab"));
714 TabStripModel* tab_strip = browser->tab_strip_model();
715 WebContents* contents =
716 tab_strip->DetachWebContentsAt(tab_strip->active_index());
717 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
718 browser->host_desktop_type()));
719 b->tab_strip_model()->AppendWebContents(contents, true);
720 b->window()->Show();
723 void Exit() {
724 content::RecordAction(UserMetricsAction("Exit"));
725 chrome::AttemptUserExit();
728 void BookmarkCurrentPage(Browser* browser) {
729 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
731 const extensions::Extension* extension = NULL;
732 extensions::Command command;
733 extensions::CommandService::ExtensionCommandType command_type;
734 if (GetBookmarkOverrideCommand(browser->profile(),
735 &extension,
736 &command,
737 &command_type)) {
738 switch (command_type) {
739 case extensions::CommandService::NAMED:
740 browser->window()->ExecuteExtensionCommand(extension, command);
741 return;
743 case extensions::CommandService::BROWSER_ACTION:
744 // BookmarkCurrentPage is called through a user gesture, so it is safe
745 // to call ShowBrowserActionPopup.
746 browser->window()->ShowBrowserActionPopup(extension);
747 return;
749 case extensions::CommandService::PAGE_ACTION:
750 browser->window()->ShowPageActionPopup(extension);
751 return;
755 BookmarkCurrentPageInternal(browser, false);
758 void BookmarkCurrentPageFromStar(Browser* browser) {
759 BookmarkCurrentPageInternal(browser, true);
762 bool CanBookmarkCurrentPage(const Browser* browser) {
763 return CanBookmarkCurrentPageInternal(browser, true);
766 void BookmarkAllTabs(Browser* browser) {
767 chrome::ShowBookmarkAllTabsDialog(browser);
770 bool CanBookmarkAllTabs(const Browser* browser) {
771 return browser->tab_strip_model()->count() > 1 &&
772 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
773 CanBookmarkCurrentPageInternal(browser, false);
776 void Translate(Browser* browser) {
777 if (!browser->window()->IsActive())
778 return;
780 WebContents* web_contents =
781 browser->tab_strip_model()->GetActiveWebContents();
782 TranslateTabHelper* translate_tab_helper =
783 TranslateTabHelper::FromWebContents(web_contents);
785 TranslateTabHelper::TranslateStep step = TranslateTabHelper::BEFORE_TRANSLATE;
786 if (translate_tab_helper) {
787 if (translate_tab_helper->GetLanguageState().translation_pending())
788 step = TranslateTabHelper::TRANSLATING;
789 else if (translate_tab_helper->GetLanguageState().IsPageTranslated())
790 step = TranslateTabHelper::AFTER_TRANSLATE;
792 browser->window()->ShowTranslateBubble(
793 web_contents, step, TranslateErrors::NONE);
796 void TogglePagePinnedToStartScreen(Browser* browser) {
797 #if defined(OS_WIN)
798 MetroPinTabHelper::FromWebContents(
799 browser->tab_strip_model()->GetActiveWebContents())->
800 TogglePinnedToStartScreen();
801 #endif
804 void SavePage(Browser* browser) {
805 content::RecordAction(UserMetricsAction("SavePage"));
806 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
807 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
808 content::RecordAction(UserMetricsAction("PDF.SavePage"));
809 current_tab->OnSavePage();
812 bool CanSavePage(const Browser* browser) {
813 // LocalState can be NULL in tests.
814 if (g_browser_process->local_state() &&
815 !g_browser_process->local_state()->GetBoolean(
816 prefs::kAllowFileSelectionDialogs)) {
817 return false;
819 return !browser->is_devtools() &&
820 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
823 void ShowFindBar(Browser* browser) {
824 browser->GetFindBarController()->Show();
827 void ShowWebsiteSettings(Browser* browser,
828 content::WebContents* web_contents,
829 const GURL& url,
830 const SSLStatus& ssl) {
831 browser->window()->ShowWebsiteSettings(
832 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
833 web_contents, url, ssl);
837 void Print(Browser* browser) {
838 #if defined(ENABLE_PRINTING)
839 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
840 #if defined(ENABLE_FULL_PRINTING)
841 printing::PrintViewManager* print_view_manager =
842 printing::PrintViewManager::FromWebContents(contents);
843 if (browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled))
844 print_view_manager->PrintNow();
845 else
846 print_view_manager->PrintPreviewNow(false);
847 #else
848 printing::PrintViewManagerBasic* print_view_manager =
849 printing::PrintViewManagerBasic::FromWebContents(contents);
850 print_view_manager->PrintNow();
851 #endif // defined(ENABLE_FULL_PRINTING)
852 #endif // defined(ENABLE_PRINTING)
855 bool CanPrint(const Browser* browser) {
856 // Do not print when printing is disabled via pref or policy.
857 // Do not print when a constrained window is showing. It's confusing.
858 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
859 !(IsShowingWebContentsModalDialog(browser) ||
860 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
863 void AdvancedPrint(Browser* browser) {
864 #if defined(ENABLE_FULL_PRINTING)
865 printing::PrintViewManager* print_view_manager =
866 printing::PrintViewManager::FromWebContents(
867 browser->tab_strip_model()->GetActiveWebContents());
868 print_view_manager->AdvancedPrintNow();
869 #endif
872 bool CanAdvancedPrint(const Browser* browser) {
873 // If printing is not disabled via pref or policy, it is always possible to
874 // advanced print when the print preview is visible. The exception to this
875 // is under Win8 ash, since showing the advanced print dialog will open it
876 // modally on the Desktop and hang the browser. We can remove this check
877 // once we integrate with the system print charm.
878 #if defined(OS_WIN)
879 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
880 return false;
881 #endif
883 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
884 (PrintPreviewShowing(browser) || CanPrint(browser));
887 void PrintToDestination(Browser* browser) {
888 #if defined(ENABLE_FULL_PRINTING)
889 printing::PrintViewManager* print_view_manager =
890 printing::PrintViewManager::FromWebContents(
891 browser->tab_strip_model()->GetActiveWebContents());
892 print_view_manager->PrintToDestination();
893 #endif
896 void EmailPageLocation(Browser* browser) {
897 content::RecordAction(UserMetricsAction("EmailPageLocation"));
898 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
899 DCHECK(wc);
901 std::string title = net::EscapeQueryParamValue(
902 base::UTF16ToUTF8(wc->GetTitle()), false);
903 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
904 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
905 title + "&body=%0A%0A" + page_url;
906 platform_util::OpenExternal(browser->profile(), GURL(mailto));
909 bool CanEmailPageLocation(const Browser* browser) {
910 return browser->toolbar_model()->ShouldDisplayURL() &&
911 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
914 void Cut(Browser* browser) {
915 content::RecordAction(UserMetricsAction("Cut"));
916 browser->window()->Cut();
919 void Copy(Browser* browser) {
920 content::RecordAction(UserMetricsAction("Copy"));
921 browser->window()->Copy();
924 void Paste(Browser* browser) {
925 content::RecordAction(UserMetricsAction("Paste"));
926 browser->window()->Paste();
929 void Find(Browser* browser) {
930 content::RecordAction(UserMetricsAction("Find"));
931 FindInPage(browser, false, false);
934 void FindNext(Browser* browser) {
935 content::RecordAction(UserMetricsAction("FindNext"));
936 FindInPage(browser, true, true);
939 void FindPrevious(Browser* browser) {
940 content::RecordAction(UserMetricsAction("FindPrevious"));
941 FindInPage(browser, true, false);
944 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
945 ShowFindBar(browser);
946 if (find_next) {
947 base::string16 find_text;
948 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
949 browser->tab_strip_model()->GetActiveWebContents());
950 #if defined(OS_MACOSX)
951 // We always want to search for the current contents of the find bar on
952 // OS X. For regular profile it's always the current find pboard. For
953 // Incognito window it's the newest value of the find pboard content and
954 // user-typed text.
955 FindBar* find_bar = browser->GetFindBarController()->find_bar();
956 find_text = find_bar->GetFindText();
957 #endif
958 find_helper->StartFinding(find_text, forward_direction, false);
962 void Zoom(Browser* browser, content::PageZoom zoom) {
963 chrome_page_zoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
964 zoom);
967 void FocusToolbar(Browser* browser) {
968 content::RecordAction(UserMetricsAction("FocusToolbar"));
969 browser->window()->FocusToolbar();
972 void FocusLocationBar(Browser* browser) {
973 content::RecordAction(UserMetricsAction("FocusLocation"));
974 browser->window()->SetFocusToLocationBar(true);
977 void FocusSearch(Browser* browser) {
978 // TODO(beng): replace this with FocusLocationBar
979 content::RecordAction(UserMetricsAction("FocusSearch"));
980 browser->window()->GetLocationBar()->FocusSearch();
983 void FocusAppMenu(Browser* browser) {
984 content::RecordAction(UserMetricsAction("FocusAppMenu"));
985 browser->window()->FocusAppMenu();
988 void FocusBookmarksToolbar(Browser* browser) {
989 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
990 browser->window()->FocusBookmarksToolbar();
993 void FocusInfobars(Browser* browser) {
994 content::RecordAction(UserMetricsAction("FocusInfobars"));
995 browser->window()->FocusInfobars();
998 void FocusNextPane(Browser* browser) {
999 content::RecordAction(UserMetricsAction("FocusNextPane"));
1000 browser->window()->RotatePaneFocus(true);
1003 void FocusPreviousPane(Browser* browser) {
1004 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1005 browser->window()->RotatePaneFocus(false);
1008 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1009 if (action.type() == DevToolsToggleAction::kShowConsole)
1010 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1011 else
1012 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1013 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1016 bool CanOpenTaskManager() {
1017 #if defined(ENABLE_TASK_MANAGER)
1018 #if defined(OS_WIN)
1019 // In metro we can't display the task manager, as it is a native window.
1020 return !win8::IsSingleWindowMetroMode();
1021 #else
1022 return true;
1023 #endif
1024 #else
1025 return false;
1026 #endif
1029 void OpenTaskManager(Browser* browser) {
1030 #if defined(ENABLE_TASK_MANAGER)
1031 content::RecordAction(UserMetricsAction("TaskManager"));
1032 chrome::ShowTaskManager(browser);
1033 #else
1034 NOTREACHED();
1035 #endif
1038 void OpenFeedbackDialog(Browser* browser) {
1039 content::RecordAction(UserMetricsAction("Feedback"));
1040 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1043 void ToggleBookmarkBar(Browser* browser) {
1044 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1045 ToggleBookmarkBarWhenVisible(browser->profile());
1048 void ShowAppMenu(Browser* browser) {
1049 // We record the user metric for this event in WrenchMenu::RunMenu.
1050 browser->window()->ShowAppMenu();
1053 void ShowAvatarMenu(Browser* browser) {
1054 browser->window()->ShowAvatarBubbleFromAvatarButton(
1055 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT);
1058 void OpenUpdateChromeDialog(Browser* browser) {
1059 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1060 content::NotificationService::current()->Notify(
1061 chrome::NOTIFICATION_OUTDATED_INSTALL,
1062 content::NotificationService::AllSources(),
1063 content::NotificationService::NoDetails());
1064 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1065 content::NotificationService::current()->Notify(
1066 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1067 content::NotificationService::AllSources(),
1068 content::NotificationService::NoDetails());
1069 } else {
1070 content::RecordAction(UserMetricsAction("UpdateChrome"));
1071 browser->window()->ShowUpdateChromeDialog();
1075 void ToggleSpeechInput(Browser* browser) {
1076 WebContents* web_contents =
1077 browser->tab_strip_model()->GetActiveWebContents();
1078 web_contents->GetRenderViewHost()->ToggleSpeechInput();
1080 SearchTabHelper* search_tab_helper =
1081 SearchTabHelper::FromWebContents(web_contents);
1082 // |search_tab_helper| can be null in unit tests.
1083 if (search_tab_helper)
1084 search_tab_helper->ToggleVoiceSearch();
1087 bool CanRequestTabletSite(WebContents* current_tab) {
1088 if (!current_tab)
1089 return false;
1090 return current_tab->GetController().GetActiveEntry() != NULL;
1093 bool IsRequestingTabletSite(Browser* browser) {
1094 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1095 if (!current_tab)
1096 return false;
1097 content::NavigationEntry* entry =
1098 current_tab->GetController().GetActiveEntry();
1099 if (!entry)
1100 return false;
1101 return entry->GetIsOverridingUserAgent();
1104 void ToggleRequestTabletSite(Browser* browser) {
1105 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1106 if (!current_tab)
1107 return;
1108 NavigationController& controller = current_tab->GetController();
1109 NavigationEntry* entry = controller.GetActiveEntry();
1110 if (!entry)
1111 return;
1112 if (entry->GetIsOverridingUserAgent()) {
1113 entry->SetIsOverridingUserAgent(false);
1114 } else {
1115 entry->SetIsOverridingUserAgent(true);
1116 chrome::VersionInfo version_info;
1117 std::string product;
1118 if (version_info.is_valid())
1119 product = version_info.ProductNameAndVersionForUserAgent();
1120 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1121 kOsOverrideForTabletSite, product));
1123 controller.ReloadOriginalRequestURL(true);
1126 void ToggleFullscreenMode(Browser* browser) {
1127 DCHECK(browser);
1128 browser->fullscreen_controller()->ToggleBrowserFullscreenMode();
1131 void ClearCache(Browser* browser) {
1132 BrowsingDataRemover* remover =
1133 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1134 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1135 BrowsingDataHelper::UNPROTECTED_WEB);
1136 // BrowsingDataRemover takes care of deleting itself when done.
1139 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1140 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1141 return contents ?
1142 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1145 void ViewSource(Browser* browser, WebContents* contents) {
1146 DCHECK(contents);
1148 // Use the last committed entry, since the pending entry hasn't loaded yet and
1149 // won't be copied into the cloned tab.
1150 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1151 if (!entry)
1152 return;
1154 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1157 void ViewSource(Browser* browser,
1158 WebContents* contents,
1159 const GURL& url,
1160 const content::PageState& page_state) {
1161 content::RecordAction(UserMetricsAction("ViewSource"));
1162 DCHECK(contents);
1164 // Note that Clone does not copy the pending or transient entries, so the
1165 // active entry in view_source_contents will be the last committed entry.
1166 WebContents* view_source_contents = contents->Clone();
1167 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1168 view_source_contents->GetController().PruneAllButLastCommitted();
1169 NavigationEntry* active_entry =
1170 view_source_contents->GetController().GetActiveEntry();
1171 if (!active_entry)
1172 return;
1174 GURL view_source_url =
1175 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1176 active_entry->SetVirtualURL(view_source_url);
1178 // Do not restore scroller position.
1179 active_entry->SetPageState(page_state.RemoveScrollOffset());
1181 // Do not restore title, derive it from the url.
1182 active_entry->SetTitle(base::string16());
1184 // Now show view-source entry.
1185 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1186 // If this is a tabbed browser, just create a duplicate tab inside the same
1187 // window next to the tab being duplicated.
1188 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1189 int add_types = TabStripModel::ADD_ACTIVE |
1190 TabStripModel::ADD_INHERIT_GROUP;
1191 browser->tab_strip_model()->InsertWebContentsAt(
1192 index + 1,
1193 view_source_contents,
1194 add_types);
1195 } else {
1196 Browser* b = new Browser(
1197 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1198 browser->host_desktop_type()));
1200 // Preserve the size of the original window. The new window has already
1201 // been given an offset by the OS, so we shouldn't copy the old bounds.
1202 BrowserWindow* new_window = b->window();
1203 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1204 browser->window()->GetRestoredBounds().size()));
1206 // We need to show the browser now. Otherwise ContainerWin assumes the
1207 // WebContents is invisible and won't size it.
1208 b->window()->Show();
1210 // The page transition below is only for the purpose of inserting the tab.
1211 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1212 content::PAGE_TRANSITION_LINK,
1213 TabStripModel::ADD_ACTIVE);
1216 SessionService* session_service =
1217 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1218 if (session_service)
1219 session_service->TabRestored(view_source_contents, false);
1222 void ViewSelectedSource(Browser* browser) {
1223 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1226 bool CanViewSource(const Browser* browser) {
1227 return !browser->is_devtools() &&
1228 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1229 CanViewSource();
1232 void CreateApplicationShortcuts(Browser* browser) {
1233 content::RecordAction(UserMetricsAction("CreateShortcut"));
1234 extensions::TabHelper::FromWebContents(
1235 browser->tab_strip_model()->GetActiveWebContents())->
1236 CreateApplicationShortcuts();
1239 void CreateHostedAppFromCurrentWebContents(Browser* browser) {
1240 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1241 extensions::TabHelper::FromWebContents(
1242 browser->tab_strip_model()->GetActiveWebContents())->
1243 CreateHostedAppFromWebContents();
1246 bool CanCreateApplicationShortcuts(const Browser* browser) {
1247 return extensions::TabHelper::FromWebContents(
1248 browser->tab_strip_model()->GetActiveWebContents())->
1249 CanCreateApplicationShortcuts();
1252 void ConvertTabToAppWindow(Browser* browser,
1253 content::WebContents* contents) {
1254 const GURL& url = contents->GetController().GetActiveEntry()->GetURL();
1255 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1257 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1258 if (index >= 0)
1259 browser->tab_strip_model()->DetachWebContentsAt(index);
1261 Browser* app_browser = new Browser(
1262 Browser::CreateParams::CreateForApp(
1263 Browser::TYPE_POPUP, app_name, gfx::Rect(), browser->profile(),
1264 browser->host_desktop_type()));
1265 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1267 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1268 contents->GetRenderViewHost()->SyncRendererPrefs();
1269 app_browser->window()->Show();
1272 } // namespace chrome