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/favicon/favicon_tab_helper.h"
21 #include "chrome/browser/lifetime/application_lifetime.h"
22 #include "chrome/browser/platform_util.h"
23 #include "chrome/browser/prefs/incognito_mode_prefs.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/rlz/rlz.h"
26 #include "chrome/browser/search/search.h"
27 #include "chrome/browser/sessions/session_service_factory.h"
28 #include "chrome/browser/sessions/tab_restore_service.h"
29 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
30 #include "chrome/browser/sessions/tab_restore_service_factory.h"
31 #include "chrome/browser/signin/signin_header_helper.h"
32 #include "chrome/browser/translate/chrome_translate_client.h"
33 #include "chrome/browser/ui/accelerator_utils.h"
34 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/browser_command_controller.h"
37 #include "chrome/browser/ui/browser_dialogs.h"
38 #include "chrome/browser/ui/browser_instant_controller.h"
39 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
40 #include "chrome/browser/ui/browser_tabstrip.h"
41 #include "chrome/browser/ui/browser_window.h"
42 #include "chrome/browser/ui/chrome_pages.h"
43 #include "chrome/browser/ui/find_bar/find_bar.h"
44 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
45 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
46 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
47 #include "chrome/browser/ui/location_bar/location_bar.h"
48 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
49 #include "chrome/browser/ui/search/search_tab_helper.h"
50 #include "chrome/browser/ui/status_bubble.h"
51 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
52 #include "chrome/browser/ui/tabs/tab_strip_model.h"
53 #include "chrome/browser/ui/zoom/zoom_controller.h"
54 #include "chrome/browser/upgrade_detector.h"
55 #include "chrome/common/chrome_switches.h"
56 #include "chrome/common/chrome_version_info.h"
57 #include "chrome/common/content_restriction.h"
58 #include "chrome/common/pref_names.h"
59 #include "components/bookmarks/browser/bookmark_model.h"
60 #include "components/bookmarks/browser/bookmark_utils.h"
61 #include "components/google/core/browser/google_util.h"
62 #include "components/translate/core/browser/language_state.h"
63 #include "components/web_modal/popup_manager.h"
64 #include "content/public/browser/devtools_agent_host.h"
65 #include "content/public/browser/navigation_controller.h"
66 #include "content/public/browser/navigation_entry.h"
67 #include "content/public/browser/notification_service.h"
68 #include "content/public/browser/page_navigator.h"
69 #include "content/public/browser/render_view_host.h"
70 #include "content/public/browser/render_widget_host_view.h"
71 #include "content/public/browser/user_metrics.h"
72 #include "content/public/browser/web_contents.h"
73 #include "content/public/common/page_state.h"
74 #include "content/public/common/renderer_preferences.h"
75 #include "content/public/common/url_constants.h"
76 #include "content/public/common/url_utils.h"
77 #include "content/public/common/user_agent.h"
78 #include "net/base/escape.h"
79 #include "ui/events/keycodes/keyboard_codes.h"
82 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
85 #if defined(ENABLE_EXTENSIONS)
86 #include "chrome/browser/extensions/api/commands/command_service.h"
87 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
88 #include "chrome/browser/extensions/tab_helper.h"
89 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
90 #include "chrome/browser/web_applications/web_app.h"
91 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
92 #include "extensions/browser/extension_registry.h"
93 #include "extensions/browser/extension_system.h"
94 #include "extensions/common/extension.h"
95 #include "extensions/common/extension_set.h"
98 #if defined(ENABLE_PRINTING)
99 #if defined(ENABLE_FULL_PRINTING)
100 #include "chrome/browser/printing/print_preview_dialog_controller.h"
101 #include "chrome/browser/printing/print_view_manager.h"
103 #include "chrome/browser/printing/print_view_manager_basic.h"
104 #endif // defined(ENABLE_FULL_PRINTING)
105 #endif // defined(ENABLE_PRINTING)
108 const char kOsOverrideForTabletSite
[] = "Linux; Android 4.0.3";
111 using base::UserMetricsAction
;
112 using content::NavigationController
;
113 using content::NavigationEntry
;
114 using content::OpenURLParams
;
115 using content::Referrer
;
116 using content::SSLStatus
;
117 using content::WebContents
;
122 bool CanBookmarkCurrentPageInternal(const Browser
* browser
,
123 bool check_remove_bookmark_ui
) {
124 BookmarkModel
* model
=
125 BookmarkModelFactory::GetForProfile(browser
->profile());
126 return browser_defaults::bookmarks_enabled
&&
127 browser
->profile()->GetPrefs()->GetBoolean(
128 bookmarks::prefs::kEditBookmarksEnabled
) &&
129 model
&& model
->loaded() && browser
->is_type_tabbed() &&
130 (!check_remove_bookmark_ui
||
131 !chrome::ShouldRemoveBookmarkThisPageUI(browser
->profile()));
134 #if defined(ENABLE_EXTENSIONS)
135 bool GetBookmarkOverrideCommand(
137 const extensions::Extension
** extension
,
138 extensions::Command
* command
,
139 extensions::CommandService::ExtensionCommandType
* command_type
) {
142 DCHECK(command_type
);
144 ui::Accelerator bookmark_page_accelerator
=
145 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE
);
146 if (bookmark_page_accelerator
.key_code() == ui::VKEY_UNKNOWN
)
149 extensions::CommandService
* command_service
=
150 extensions::CommandService::Get(profile
);
151 const extensions::ExtensionSet
& extension_set
=
152 extensions::ExtensionRegistry::Get(profile
)->enabled_extensions();
153 for (extensions::ExtensionSet::const_iterator i
= extension_set
.begin();
154 i
!= extension_set
.end();
156 extensions::Command prospective_command
;
157 extensions::CommandService::ExtensionCommandType prospective_command_type
;
158 if (command_service
->GetBoundExtensionCommand((*i
)->id(),
159 bookmark_page_accelerator
,
160 &prospective_command
,
161 &prospective_command_type
)) {
162 *extension
= i
->get();
163 *command
= prospective_command
;
164 *command_type
= prospective_command_type
;
172 void BookmarkCurrentPageInternal(Browser
* browser
) {
173 content::RecordAction(UserMetricsAction("Star"));
175 BookmarkModel
* model
=
176 BookmarkModelFactory::GetForProfile(browser
->profile());
177 if (!model
|| !model
->loaded())
178 return; // Ignore requests until bookmarks are loaded.
181 base::string16 title
;
182 WebContents
* web_contents
=
183 browser
->tab_strip_model()->GetActiveWebContents();
184 GetURLAndTitleToBookmark(web_contents
, &url
, &title
);
185 bool is_bookmarked_by_any
= model
->IsBookmarked(url
);
186 if (!is_bookmarked_by_any
&&
187 web_contents
->GetBrowserContext()->IsOffTheRecord()) {
188 // If we're incognito the favicon may not have been saved. Save it now
189 // so that bookmarks have an icon for the page.
190 FaviconTabHelper::FromWebContents(web_contents
)->SaveFavicon();
192 bool was_bookmarked_by_user
= bookmarks::IsBookmarkedByUser(model
, url
);
193 bookmarks::AddIfNotBookmarked(model
, url
, title
);
194 bool is_bookmarked_by_user
= bookmarks::IsBookmarkedByUser(model
, url
);
195 // Make sure the model actually added a bookmark before showing the star. A
196 // bookmark isn't created if the url is invalid.
197 if (browser
->window()->IsActive() && is_bookmarked_by_user
) {
198 // Only show the bubble if the window is active, otherwise we may get into
199 // weird situations where the bubble is deleted as soon as it is shown.
200 browser
->window()->ShowBookmarkBubble(url
, was_bookmarked_by_user
);
204 // Based on |disposition|, creates a new tab as necessary, and returns the
205 // appropriate tab to navigate. If that tab is the current tab, reverts the
206 // location bar contents, since all browser-UI-triggered navigations should
207 // revert any omnibox edits in the current tab.
208 WebContents
* GetTabAndRevertIfNecessary(Browser
* browser
,
209 WindowOpenDisposition disposition
) {
210 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
211 switch (disposition
) {
212 case NEW_FOREGROUND_TAB
:
213 case NEW_BACKGROUND_TAB
: {
214 WebContents
* new_tab
= current_tab
->Clone();
215 browser
->tab_strip_model()->AddWebContents(
216 new_tab
, -1, ui::PAGE_TRANSITION_LINK
,
217 (disposition
== NEW_FOREGROUND_TAB
) ?
218 TabStripModel::ADD_ACTIVE
: TabStripModel::ADD_NONE
);
222 WebContents
* new_tab
= current_tab
->Clone();
223 Browser
* new_browser
= new Browser(Browser::CreateParams(
224 browser
->profile(), browser
->host_desktop_type()));
225 new_browser
->tab_strip_model()->AddWebContents(
226 new_tab
, -1, ui::PAGE_TRANSITION_LINK
,
227 TabStripModel::ADD_ACTIVE
);
228 new_browser
->window()->Show();
232 browser
->window()->GetLocationBar()->Revert();
237 void ReloadInternal(Browser
* browser
,
238 WindowOpenDisposition disposition
,
240 // As this is caused by a user action, give the focus to the page.
242 // Also notify RenderViewHostDelegate of the user gesture; this is
243 // normally done in Browser::Navigate, but a reload bypasses Navigate.
244 WebContents
* new_tab
= GetTabAndRevertIfNecessary(browser
, disposition
);
245 new_tab
->UserGestureDone();
246 if (!new_tab
->FocusLocationBarByDefault())
249 new_tab
->GetController().ReloadIgnoringCache(true);
251 new_tab
->GetController().Reload(true);
254 bool IsShowingWebContentsModalDialog(Browser
* browser
) {
255 WebContents
* web_contents
=
256 browser
->tab_strip_model()->GetActiveWebContents();
260 // In test code we may not have a popup manager.
261 if (!browser
->popup_manager())
264 // TODO(gbillock): This is currently called in production by the CanPrint
265 // method, and may be too restrictive if we allow print preview to overlap.
266 // Re-assess how to queue print preview after we know more about popup
267 // management policy.
268 return browser
->popup_manager()->IsWebModalDialogActive(web_contents
);
271 bool PrintPreviewShowing(const Browser
* browser
) {
272 #if defined(ENABLE_FULL_PRINTING)
273 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
274 printing::PrintPreviewDialogController
* controller
=
275 printing::PrintPreviewDialogController::GetInstance();
276 return controller
&& (controller
->GetPrintPreviewForContents(contents
) ||
277 controller
->is_creating_print_preview_dialog());
285 bool IsCommandEnabled(Browser
* browser
, int command
) {
286 return browser
->command_controller()->command_updater()->IsCommandEnabled(
290 bool SupportsCommand(Browser
* browser
, int command
) {
291 return browser
->command_controller()->command_updater()->SupportsCommand(
295 bool ExecuteCommand(Browser
* browser
, int command
) {
296 return browser
->command_controller()->command_updater()->ExecuteCommand(
300 bool ExecuteCommandWithDisposition(Browser
* browser
,
302 WindowOpenDisposition disposition
) {
303 return browser
->command_controller()->command_updater()->
304 ExecuteCommandWithDisposition(command
, disposition
);
307 void UpdateCommandEnabled(Browser
* browser
, int command
, bool enabled
) {
308 browser
->command_controller()->command_updater()->UpdateCommandEnabled(
312 void AddCommandObserver(Browser
* browser
,
314 CommandObserver
* observer
) {
315 browser
->command_controller()->command_updater()->AddCommandObserver(
319 void RemoveCommandObserver(Browser
* browser
,
321 CommandObserver
* observer
) {
322 browser
->command_controller()->command_updater()->RemoveCommandObserver(
326 int GetContentRestrictions(const Browser
* browser
) {
327 int content_restrictions
= 0;
328 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
330 CoreTabHelper
* core_tab_helper
=
331 CoreTabHelper::FromWebContents(current_tab
);
332 content_restrictions
= core_tab_helper
->content_restrictions();
333 NavigationEntry
* last_committed_entry
=
334 current_tab
->GetController().GetLastCommittedEntry();
335 if (!content::IsSavableURL(
336 last_committed_entry
? last_committed_entry
->GetURL() : GURL()) ||
337 current_tab
->ShowingInterstitialPage())
338 content_restrictions
|= CONTENT_RESTRICTION_SAVE
;
339 if (current_tab
->ShowingInterstitialPage())
340 content_restrictions
|= CONTENT_RESTRICTION_PRINT
;
342 return content_restrictions
;
345 void NewEmptyWindow(Profile
* profile
, HostDesktopType desktop_type
) {
346 bool incognito
= profile
->IsOffTheRecord();
347 PrefService
* prefs
= profile
->GetPrefs();
349 if (IncognitoModePrefs::GetAvailability(prefs
) ==
350 IncognitoModePrefs::DISABLED
) {
353 } else if (profile
->IsGuestSession() ||
354 (browser_defaults::kAlwaysOpenIncognitoWindow
&&
355 IncognitoModePrefs::ShouldLaunchIncognito(
356 *CommandLine::ForCurrentProcess(), prefs
))) {
361 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
362 OpenEmptyWindow(profile
->GetOffTheRecordProfile(), desktop_type
);
364 content::RecordAction(UserMetricsAction("NewWindow"));
365 SessionService
* session_service
=
366 SessionServiceFactory::GetForProfileForSessionRestore(
367 profile
->GetOriginalProfile());
368 if (!session_service
||
369 !session_service
->RestoreIfNecessary(std::vector
<GURL
>())) {
370 OpenEmptyWindow(profile
->GetOriginalProfile(), desktop_type
);
375 Browser
* OpenEmptyWindow(Profile
* profile
, HostDesktopType desktop_type
) {
376 Browser
* browser
= new Browser(
377 Browser::CreateParams(Browser::TYPE_TABBED
, profile
, desktop_type
));
378 AddTabAt(browser
, GURL(), -1, true);
379 browser
->window()->Show();
383 void OpenWindowWithRestoredTabs(Profile
* profile
,
384 HostDesktopType host_desktop_type
) {
385 TabRestoreService
* service
= TabRestoreServiceFactory::GetForProfile(profile
);
387 service
->RestoreMostRecentEntry(NULL
, host_desktop_type
);
390 void OpenURLOffTheRecord(Profile
* profile
,
392 chrome::HostDesktopType desktop_type
) {
393 ScopedTabbedBrowserDisplayer
displayer(profile
->GetOffTheRecordProfile(),
395 AddSelectedTabWithURL(displayer
.browser(), url
,
396 ui::PAGE_TRANSITION_LINK
);
399 bool CanGoBack(const Browser
* browser
) {
400 return browser
->tab_strip_model()->GetActiveWebContents()->
401 GetController().CanGoBack();
404 void GoBack(Browser
* browser
, WindowOpenDisposition disposition
) {
405 content::RecordAction(UserMetricsAction("Back"));
407 if (CanGoBack(browser
)) {
408 WebContents
* current_tab
=
409 browser
->tab_strip_model()->GetActiveWebContents();
410 WebContents
* new_tab
= GetTabAndRevertIfNecessary(browser
, disposition
);
411 // If we are on an interstitial page and clone the tab, it won't be copied
412 // to the new tab, so we don't need to go back.
413 if ((new_tab
== current_tab
) || !current_tab
->ShowingInterstitialPage())
414 new_tab
->GetController().GoBack();
418 bool CanGoForward(const Browser
* browser
) {
419 return browser
->tab_strip_model()->GetActiveWebContents()->
420 GetController().CanGoForward();
423 void GoForward(Browser
* browser
, WindowOpenDisposition disposition
) {
424 content::RecordAction(UserMetricsAction("Forward"));
425 if (CanGoForward(browser
)) {
426 GetTabAndRevertIfNecessary(browser
, disposition
)->
427 GetController().GoForward();
431 bool NavigateToIndexWithDisposition(Browser
* browser
,
433 WindowOpenDisposition disposition
) {
434 NavigationController
* controller
=
435 &GetTabAndRevertIfNecessary(browser
, disposition
)->GetController();
436 if (index
< 0 || index
>= controller
->GetEntryCount())
438 controller
->GoToIndex(index
);
442 void Reload(Browser
* browser
, WindowOpenDisposition disposition
) {
443 content::RecordAction(UserMetricsAction("Reload"));
444 ReloadInternal(browser
, disposition
, false);
447 void ReloadIgnoringCache(Browser
* browser
, WindowOpenDisposition disposition
) {
448 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
449 ReloadInternal(browser
, disposition
, true);
452 bool CanReload(const Browser
* browser
) {
453 return !browser
->is_devtools();
456 void Home(Browser
* browser
, WindowOpenDisposition disposition
) {
457 content::RecordAction(UserMetricsAction("Home"));
459 std::string extra_headers
;
460 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
461 // If the home page is a Google home page, add the RLZ header to the request.
462 PrefService
* pref_service
= browser
->profile()->GetPrefs();
464 if (google_util::IsGoogleHomePageUrl(
465 GURL(pref_service
->GetString(prefs::kHomePage
)))) {
466 extra_headers
= RLZTracker::GetAccessPointHttpHeader(
467 RLZTracker::ChromeHomePage());
470 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
472 GURL url
= browser
->profile()->GetHomePage();
474 #if defined(ENABLE_EXTENSIONS)
475 // Streamlined hosted apps should return to their launch page when the home
476 // button is pressed.
477 if (browser
->is_app()) {
478 const extensions::Extension
* extension
=
479 extensions::ExtensionRegistry::Get(browser
->profile())
481 web_app::GetExtensionIdFromApplicationName(browser
->app_name()),
482 extensions::ExtensionRegistry::EVERYTHING
);
486 url
= extensions::AppLaunchInfo::GetLaunchWebURL(extension
);
490 OpenURLParams
params(
491 url
, Referrer(), disposition
,
492 ui::PageTransitionFromInt(
493 ui::PAGE_TRANSITION_AUTO_BOOKMARK
|
494 ui::PAGE_TRANSITION_HOME_PAGE
),
496 params
.extra_headers
= extra_headers
;
497 browser
->OpenURL(params
);
500 void OpenCurrentURL(Browser
* browser
) {
501 content::RecordAction(UserMetricsAction("LoadURL"));
502 LocationBar
* location_bar
= browser
->window()->GetLocationBar();
506 GURL
url(location_bar
->GetDestinationURL());
508 ui::PageTransition page_transition
= location_bar
->GetPageTransition();
509 ui::PageTransition
page_transition_without_qualifier(
510 ui::PageTransitionStripQualifier(page_transition
));
511 WindowOpenDisposition open_disposition
=
512 location_bar
->GetWindowOpenDisposition();
513 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
514 // open URLs with instant_controller since in some cases it disregards it
515 // and performs a search instead. For example, when using CTRL-Enter, the
516 // location_bar is aware of the URL but instant is not.
517 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
518 // of the omnibox text may be stale if the user focuses in the omnibox and
519 // presses enter without typing anything.
520 if (page_transition_without_qualifier
!= ui::PAGE_TRANSITION_TYPED
&&
521 page_transition_without_qualifier
!= ui::PAGE_TRANSITION_RELOAD
&&
522 browser
->instant_controller() &&
523 browser
->instant_controller()->OpenInstant(open_disposition
, url
))
526 NavigateParams
params(browser
, url
, page_transition
);
527 params
.disposition
= open_disposition
;
528 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
529 // inherit the opener. In some cases the tabstrip will determine the group
530 // should be inherited, in which case the group is inherited instead of the
532 params
.tabstrip_add_types
=
533 TabStripModel::ADD_FORCE_INDEX
| TabStripModel::ADD_INHERIT_OPENER
;
536 #if defined(ENABLE_EXTENSIONS)
537 DCHECK(extensions::ExtensionSystem::Get(
538 browser
->profile())->extension_service());
539 const extensions::Extension
* extension
=
540 extensions::ExtensionRegistry::Get(browser
->profile())
541 ->enabled_extensions().GetAppByURL(url
);
543 CoreAppLauncherHandler::RecordAppLaunchType(
544 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION
,
545 extension
->GetType());
550 void Stop(Browser
* browser
) {
551 content::RecordAction(UserMetricsAction("Stop"));
552 browser
->tab_strip_model()->GetActiveWebContents()->Stop();
555 void NewWindow(Browser
* browser
) {
556 NewEmptyWindow(browser
->profile()->GetOriginalProfile(),
557 browser
->host_desktop_type());
560 void NewIncognitoWindow(Browser
* browser
) {
561 NewEmptyWindow(browser
->profile()->GetOffTheRecordProfile(),
562 browser
->host_desktop_type());
565 void CloseWindow(Browser
* browser
) {
566 content::RecordAction(UserMetricsAction("CloseWindow"));
567 browser
->window()->Close();
570 void NewTab(Browser
* browser
) {
571 content::RecordAction(UserMetricsAction("NewTab"));
572 // TODO(asvitkine): This is invoked programmatically from several places.
573 // Audit the code and change it so that the histogram only gets collected for
574 // user-initiated commands.
575 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND
,
576 TabStripModel::NEW_TAB_ENUM_COUNT
);
578 if (browser
->is_type_tabbed()) {
579 AddTabAt(browser
, GURL(), -1, true);
580 browser
->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
582 ScopedTabbedBrowserDisplayer
displayer(browser
->profile(),
583 browser
->host_desktop_type());
584 Browser
* b
= displayer
.browser();
585 AddTabAt(b
, GURL(), -1, true);
587 // The call to AddBlankTabAt above did not set the focus to the tab as its
588 // window was not active, so we have to do it explicitly.
589 // See http://crbug.com/6380.
590 b
->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
594 void CloseTab(Browser
* browser
) {
595 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
596 browser
->tab_strip_model()->CloseSelectedTabs();
599 bool CanZoomIn(content::WebContents
* contents
) {
600 ZoomController
* zoom_controller
= ZoomController::FromWebContents(contents
);
601 return zoom_controller
->GetZoomPercent() !=
602 contents
->GetMaximumZoomPercent() + 1;
605 bool CanZoomOut(content::WebContents
* contents
) {
606 ZoomController
* zoom_controller
= ZoomController::FromWebContents(contents
);
607 return zoom_controller
->GetZoomPercent() !=
608 contents
->GetMinimumZoomPercent();
611 bool ActualSize(content::WebContents
* contents
) {
612 ZoomController
* zoom_controller
= ZoomController::FromWebContents(contents
);
613 return zoom_controller
->GetZoomPercent() != 100.0f
;
616 TabStripModelDelegate::RestoreTabType
GetRestoreTabType(
617 const Browser
* browser
) {
618 TabRestoreService
* service
=
619 TabRestoreServiceFactory::GetForProfile(browser
->profile());
620 if (!service
|| service
->entries().empty())
621 return TabStripModelDelegate::RESTORE_NONE
;
622 if (service
->entries().front()->type
== TabRestoreService::WINDOW
)
623 return TabStripModelDelegate::RESTORE_WINDOW
;
624 return TabStripModelDelegate::RESTORE_TAB
;
627 void SelectNextTab(Browser
* browser
) {
628 content::RecordAction(UserMetricsAction("SelectNextTab"));
629 browser
->tab_strip_model()->SelectNextTab();
632 void SelectPreviousTab(Browser
* browser
) {
633 content::RecordAction(UserMetricsAction("SelectPrevTab"));
634 browser
->tab_strip_model()->SelectPreviousTab();
637 void MoveTabNext(Browser
* browser
) {
638 content::RecordAction(UserMetricsAction("MoveTabNext"));
639 browser
->tab_strip_model()->MoveTabNext();
642 void MoveTabPrevious(Browser
* browser
) {
643 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
644 browser
->tab_strip_model()->MoveTabPrevious();
647 void SelectNumberedTab(Browser
* browser
, int index
) {
648 if (index
< browser
->tab_strip_model()->count()) {
649 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
650 browser
->tab_strip_model()->ActivateTabAt(index
, true);
654 void SelectLastTab(Browser
* browser
) {
655 content::RecordAction(UserMetricsAction("SelectLastTab"));
656 browser
->tab_strip_model()->SelectLastTab();
659 void DuplicateTab(Browser
* browser
) {
660 content::RecordAction(UserMetricsAction("Duplicate"));
661 DuplicateTabAt(browser
, browser
->tab_strip_model()->active_index());
664 bool CanDuplicateTab(const Browser
* browser
) {
665 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
666 return contents
&& contents
->GetController().GetLastCommittedEntry();
669 WebContents
* DuplicateTabAt(Browser
* browser
, int index
) {
670 WebContents
* contents
= browser
->tab_strip_model()->GetWebContentsAt(index
);
672 WebContents
* contents_dupe
= contents
->Clone();
675 if (browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
676 // If this is a tabbed browser, just create a duplicate tab inside the same
677 // window next to the tab being duplicated.
678 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
679 pinned
= browser
->tab_strip_model()->IsTabPinned(index
);
680 int add_types
= TabStripModel::ADD_ACTIVE
|
681 TabStripModel::ADD_INHERIT_GROUP
|
682 (pinned
? TabStripModel::ADD_PINNED
: 0);
683 browser
->tab_strip_model()->InsertWebContentsAt(
684 index
+ 1, contents_dupe
, add_types
);
686 Browser
* new_browser
= NULL
;
687 if (browser
->is_app() && !browser
->is_type_popup()) {
688 new_browser
= new Browser(
689 Browser::CreateParams::CreateForApp(browser
->app_name(),
690 browser
->is_trusted_source(),
693 browser
->host_desktop_type()));
695 new_browser
= new Browser(
696 Browser::CreateParams(browser
->type(), browser
->profile(),
697 browser
->host_desktop_type()));
699 // Preserve the size of the original window. The new window has already
700 // been given an offset by the OS, so we shouldn't copy the old bounds.
701 BrowserWindow
* new_window
= new_browser
->window();
702 new_window
->SetBounds(gfx::Rect(new_window
->GetRestoredBounds().origin(),
703 browser
->window()->GetRestoredBounds().size()));
705 // We need to show the browser now. Otherwise ContainerWin assumes the
706 // WebContents is invisible and won't size it.
707 new_browser
->window()->Show();
709 // The page transition below is only for the purpose of inserting the tab.
710 new_browser
->tab_strip_model()->AddWebContents(
712 ui::PAGE_TRANSITION_LINK
,
713 TabStripModel::ADD_ACTIVE
);
716 SessionService
* session_service
=
717 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
719 session_service
->TabRestored(contents_dupe
, pinned
);
720 return contents_dupe
;
723 bool CanDuplicateTabAt(Browser
* browser
, int index
) {
724 content::NavigationController
& nc
=
725 browser
->tab_strip_model()->GetWebContentsAt(index
)->GetController();
726 return nc
.GetWebContents() && nc
.GetLastCommittedEntry();
729 void ConvertPopupToTabbedBrowser(Browser
* browser
) {
730 content::RecordAction(UserMetricsAction("ShowAsTab"));
731 TabStripModel
* tab_strip
= browser
->tab_strip_model();
732 WebContents
* contents
=
733 tab_strip
->DetachWebContentsAt(tab_strip
->active_index());
734 Browser
* b
= new Browser(Browser::CreateParams(browser
->profile(),
735 browser
->host_desktop_type()));
736 b
->tab_strip_model()->AppendWebContents(contents
, true);
741 content::RecordAction(UserMetricsAction("Exit"));
742 chrome::AttemptUserExit();
745 void BookmarkCurrentPage(Browser
* browser
) {
746 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser
->profile()));
748 #if defined(ENABLE_EXTENSIONS)
749 const extensions::Extension
* extension
= NULL
;
750 extensions::Command command
;
751 extensions::CommandService::ExtensionCommandType command_type
;
752 if (GetBookmarkOverrideCommand(browser
->profile(),
756 switch (command_type
) {
757 case extensions::CommandService::NAMED
:
758 browser
->window()->ExecuteExtensionCommand(extension
, command
);
760 case extensions::CommandService::BROWSER_ACTION
:
761 case extensions::CommandService::PAGE_ACTION
:
762 // BookmarkCurrentPage is called through a user gesture, so it is safe
763 // to grant the active tab permission.
764 extensions::ExtensionActionAPI::Get(browser
->profile())->
765 ShowExtensionActionPopup(extension
, browser
, true);
772 BookmarkCurrentPageInternal(browser
);
775 bool CanBookmarkCurrentPage(const Browser
* browser
) {
776 return CanBookmarkCurrentPageInternal(browser
, true);
779 void BookmarkAllTabs(Browser
* browser
) {
780 chrome::ShowBookmarkAllTabsDialog(browser
);
783 bool CanBookmarkAllTabs(const Browser
* browser
) {
784 return browser
->tab_strip_model()->count() > 1 &&
785 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser
->profile()) &&
786 CanBookmarkCurrentPageInternal(browser
, false);
789 void Translate(Browser
* browser
) {
790 if (!browser
->window()->IsActive())
793 WebContents
* web_contents
=
794 browser
->tab_strip_model()->GetActiveWebContents();
795 ChromeTranslateClient
* chrome_translate_client
=
796 ChromeTranslateClient::FromWebContents(web_contents
);
798 translate::TranslateStep step
= translate::TRANSLATE_STEP_BEFORE_TRANSLATE
;
799 if (chrome_translate_client
) {
800 if (chrome_translate_client
->GetLanguageState().translation_pending())
801 step
= translate::TRANSLATE_STEP_TRANSLATING
;
802 else if (chrome_translate_client
->GetLanguageState().IsPageTranslated())
803 step
= translate::TRANSLATE_STEP_AFTER_TRANSLATE
;
805 browser
->window()->ShowTranslateBubble(
806 web_contents
, step
, translate::TranslateErrors::NONE
, true);
809 void ManagePasswordsForPage(Browser
* browser
) {
810 if (!browser
->window()->IsActive())
813 WebContents
* web_contents
=
814 browser
->tab_strip_model()->GetActiveWebContents();
815 chrome::ShowManagePasswordsBubble(web_contents
);
818 void TogglePagePinnedToStartScreen(Browser
* browser
) {
820 MetroPinTabHelper::FromWebContents(
821 browser
->tab_strip_model()->GetActiveWebContents())->
822 TogglePinnedToStartScreen();
826 void SavePage(Browser
* browser
) {
827 content::RecordAction(UserMetricsAction("SavePage"));
828 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
829 if (current_tab
&& current_tab
->GetContentsMimeType() == "application/pdf")
830 content::RecordAction(UserMetricsAction("PDF.SavePage"));
831 current_tab
->OnSavePage();
834 bool CanSavePage(const Browser
* browser
) {
835 // LocalState can be NULL in tests.
836 if (g_browser_process
->local_state() &&
837 !g_browser_process
->local_state()->GetBoolean(
838 prefs::kAllowFileSelectionDialogs
)) {
841 return !browser
->is_devtools() &&
842 !(GetContentRestrictions(browser
) & CONTENT_RESTRICTION_SAVE
);
845 void ShowFindBar(Browser
* browser
) {
846 browser
->GetFindBarController()->Show();
849 void ShowWebsiteSettings(Browser
* browser
,
850 content::WebContents
* web_contents
,
852 const SSLStatus
& ssl
) {
853 browser
->window()->ShowWebsiteSettings(
854 Profile::FromBrowserContext(web_contents
->GetBrowserContext()),
855 web_contents
, url
, ssl
);
858 void Print(Browser
* browser
) {
859 #if defined(ENABLE_PRINTING)
860 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
862 #if defined(ENABLE_FULL_PRINTING)
863 printing::PrintViewManager
* print_view_manager
=
864 printing::PrintViewManager::FromWebContents(contents
);
865 if (!browser
->profile()->GetPrefs()->GetBoolean(
866 prefs::kPrintPreviewDisabled
)) {
867 print_view_manager
->PrintPreviewNow(false);
870 #else // ENABLE_FULL_PRINTING
871 printing::PrintViewManagerBasic
* print_view_manager
=
872 printing::PrintViewManagerBasic::FromWebContents(contents
);
873 #endif // ENABLE_FULL_PRINTING
875 #if !defined(DISABLE_BASIC_PRINTING)
876 print_view_manager
->PrintNow();
877 #endif // DISABLE_BASIC_PRINTING
879 #endif // defined(ENABLE_PRINTING)
882 bool CanPrint(Browser
* browser
) {
883 // Do not print when printing is disabled via pref or policy.
884 // Do not print when a constrained window is showing. It's confusing.
885 // TODO(gbillock): Need to re-assess the call to
886 // IsShowingWebContentsModalDialog after a popup management policy is
887 // refined -- we will probably want to just queue the print request, not
889 return browser
->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled
) &&
890 !(IsShowingWebContentsModalDialog(browser
) ||
891 GetContentRestrictions(browser
) & CONTENT_RESTRICTION_PRINT
);
894 #if !defined(DISABLE_BASIC_PRINTING)
895 void BasicPrint(Browser
* browser
) {
896 #if defined(ENABLE_FULL_PRINTING)
897 printing::PrintViewManager
* print_view_manager
=
898 printing::PrintViewManager::FromWebContents(
899 browser
->tab_strip_model()->GetActiveWebContents());
900 print_view_manager
->BasicPrint();
904 bool CanBasicPrint(Browser
* browser
) {
905 // If printing is not disabled via pref or policy, it is always possible to
906 // advanced print when the print preview is visible. The exception to this
907 // is under Win8 ash, since showing the advanced print dialog will open it
908 // modally on the Desktop and hang the browser.
910 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH
)
914 return browser
->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled
) &&
915 (PrintPreviewShowing(browser
) || CanPrint(browser
));
917 #endif // !DISABLE_BASIC_PRINTING
919 void EmailPageLocation(Browser
* browser
) {
920 content::RecordAction(UserMetricsAction("EmailPageLocation"));
921 WebContents
* wc
= browser
->tab_strip_model()->GetActiveWebContents();
924 std::string title
= net::EscapeQueryParamValue(
925 base::UTF16ToUTF8(wc
->GetTitle()), false);
926 std::string page_url
= net::EscapeQueryParamValue(wc
->GetURL().spec(), false);
927 std::string mailto
= std::string("mailto:?subject=Fwd:%20") +
928 title
+ "&body=%0A%0A" + page_url
;
929 platform_util::OpenExternal(browser
->profile(), GURL(mailto
));
932 bool CanEmailPageLocation(const Browser
* browser
) {
933 return browser
->toolbar_model()->ShouldDisplayURL() &&
934 browser
->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
937 void Cut(Browser
* browser
) {
938 content::RecordAction(UserMetricsAction("Cut"));
939 browser
->window()->Cut();
942 void Copy(Browser
* browser
) {
943 content::RecordAction(UserMetricsAction("Copy"));
944 browser
->window()->Copy();
947 void Paste(Browser
* browser
) {
948 content::RecordAction(UserMetricsAction("Paste"));
949 browser
->window()->Paste();
952 void Find(Browser
* browser
) {
953 content::RecordAction(UserMetricsAction("Find"));
954 FindInPage(browser
, false, false);
957 void FindNext(Browser
* browser
) {
958 content::RecordAction(UserMetricsAction("FindNext"));
959 FindInPage(browser
, true, true);
962 void FindPrevious(Browser
* browser
) {
963 content::RecordAction(UserMetricsAction("FindPrevious"));
964 FindInPage(browser
, true, false);
967 void FindInPage(Browser
* browser
, bool find_next
, bool forward_direction
) {
968 ShowFindBar(browser
);
970 base::string16 find_text
;
971 FindTabHelper
* find_helper
= FindTabHelper::FromWebContents(
972 browser
->tab_strip_model()->GetActiveWebContents());
973 #if defined(OS_MACOSX)
974 // We always want to search for the current contents of the find bar on
975 // OS X. For regular profile it's always the current find pboard. For
976 // Incognito window it's the newest value of the find pboard content and
978 FindBar
* find_bar
= browser
->GetFindBarController()->find_bar();
979 find_text
= find_bar
->GetFindText();
981 find_helper
->StartFinding(find_text
, forward_direction
, false);
985 void Zoom(Browser
* browser
, content::PageZoom zoom
) {
986 chrome_page_zoom::Zoom(browser
->tab_strip_model()->GetActiveWebContents(),
990 void FocusToolbar(Browser
* browser
) {
991 content::RecordAction(UserMetricsAction("FocusToolbar"));
992 browser
->window()->FocusToolbar();
995 void FocusLocationBar(Browser
* browser
) {
996 content::RecordAction(UserMetricsAction("FocusLocation"));
997 browser
->window()->SetFocusToLocationBar(true);
1000 void FocusSearch(Browser
* browser
) {
1001 // TODO(beng): replace this with FocusLocationBar
1002 content::RecordAction(UserMetricsAction("FocusSearch"));
1003 browser
->window()->GetLocationBar()->FocusSearch();
1006 void FocusAppMenu(Browser
* browser
) {
1007 content::RecordAction(UserMetricsAction("FocusAppMenu"));
1008 browser
->window()->FocusAppMenu();
1011 void FocusBookmarksToolbar(Browser
* browser
) {
1012 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
1013 browser
->window()->FocusBookmarksToolbar();
1016 void FocusInfobars(Browser
* browser
) {
1017 content::RecordAction(UserMetricsAction("FocusInfobars"));
1018 browser
->window()->FocusInfobars();
1021 void FocusNextPane(Browser
* browser
) {
1022 content::RecordAction(UserMetricsAction("FocusNextPane"));
1023 browser
->window()->RotatePaneFocus(true);
1026 void FocusPreviousPane(Browser
* browser
) {
1027 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1028 browser
->window()->RotatePaneFocus(false);
1031 void ToggleDevToolsWindow(Browser
* browser
, DevToolsToggleAction action
) {
1032 if (action
.type() == DevToolsToggleAction::kShowConsole
)
1033 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1035 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1036 DevToolsWindow::ToggleDevToolsWindow(browser
, action
);
1039 bool CanOpenTaskManager() {
1040 #if defined(ENABLE_TASK_MANAGER)
1047 void OpenTaskManager(Browser
* browser
) {
1048 #if defined(ENABLE_TASK_MANAGER)
1049 content::RecordAction(UserMetricsAction("TaskManager"));
1050 chrome::ShowTaskManager(browser
);
1056 void OpenFeedbackDialog(Browser
* browser
) {
1057 content::RecordAction(UserMetricsAction("Feedback"));
1058 chrome::ShowFeedbackPage(browser
, std::string(), std::string());
1061 void ToggleBookmarkBar(Browser
* browser
) {
1062 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1063 ToggleBookmarkBarWhenVisible(browser
->profile());
1066 void ShowAppMenu(Browser
* browser
) {
1067 // We record the user metric for this event in WrenchMenu::RunMenu.
1068 browser
->window()->ShowAppMenu();
1071 void ShowAvatarMenu(Browser
* browser
) {
1072 browser
->window()->ShowAvatarBubbleFromAvatarButton(
1073 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT
,
1074 signin::ManageAccountsParams());
1077 void OpenUpdateChromeDialog(Browser
* browser
) {
1078 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1079 content::NotificationService::current()->Notify(
1080 chrome::NOTIFICATION_OUTDATED_INSTALL
,
1081 content::NotificationService::AllSources(),
1082 content::NotificationService::NoDetails());
1083 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1084 content::NotificationService::current()->Notify(
1085 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU
,
1086 content::NotificationService::AllSources(),
1087 content::NotificationService::NoDetails());
1089 content::RecordAction(UserMetricsAction("UpdateChrome"));
1090 browser
->window()->ShowUpdateChromeDialog();
1094 void ToggleSpeechInput(Browser
* browser
) {
1095 SearchTabHelper
* search_tab_helper
=
1096 SearchTabHelper::FromWebContents(
1097 browser
->tab_strip_model()->GetActiveWebContents());
1098 // |search_tab_helper| can be null in unit tests.
1099 if (search_tab_helper
)
1100 search_tab_helper
->ToggleVoiceSearch();
1103 void DistillCurrentPage(Browser
* browser
) {
1104 DistillCurrentPageAndView(browser
->tab_strip_model()->GetActiveWebContents());
1107 bool CanRequestTabletSite(WebContents
* current_tab
) {
1108 return current_tab
&&
1109 current_tab
->GetController().GetLastCommittedEntry() != NULL
;
1112 bool IsRequestingTabletSite(Browser
* browser
) {
1113 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
1116 content::NavigationEntry
* entry
=
1117 current_tab
->GetController().GetLastCommittedEntry();
1120 return entry
->GetIsOverridingUserAgent();
1123 void ToggleRequestTabletSite(Browser
* browser
) {
1124 WebContents
* current_tab
= browser
->tab_strip_model()->GetActiveWebContents();
1127 NavigationController
& controller
= current_tab
->GetController();
1128 NavigationEntry
* entry
= controller
.GetLastCommittedEntry();
1131 if (entry
->GetIsOverridingUserAgent()) {
1132 entry
->SetIsOverridingUserAgent(false);
1134 entry
->SetIsOverridingUserAgent(true);
1135 chrome::VersionInfo version_info
;
1136 std::string product
= version_info
.ProductNameAndVersionForUserAgent();
1137 current_tab
->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1138 kOsOverrideForTabletSite
, product
));
1140 controller
.ReloadOriginalRequestURL(true);
1143 void ToggleFullscreenMode(Browser
* browser
) {
1145 browser
->fullscreen_controller()->ToggleBrowserFullscreenMode();
1148 void ClearCache(Browser
* browser
) {
1149 BrowsingDataRemover
* remover
=
1150 BrowsingDataRemover::CreateForUnboundedRange(browser
->profile());
1151 remover
->Remove(BrowsingDataRemover::REMOVE_CACHE
,
1152 BrowsingDataHelper::UNPROTECTED_WEB
);
1153 // BrowsingDataRemover takes care of deleting itself when done.
1156 bool IsDebuggerAttachedToCurrentTab(Browser
* browser
) {
1157 WebContents
* contents
= browser
->tab_strip_model()->GetActiveWebContents();
1159 content::DevToolsAgentHost::IsDebuggerAttached(contents
) : false;
1162 void ViewSource(Browser
* browser
, WebContents
* contents
) {
1165 // Use the last committed entry, since the pending entry hasn't loaded yet and
1166 // won't be copied into the cloned tab.
1167 NavigationEntry
* entry
= contents
->GetController().GetLastCommittedEntry();
1171 ViewSource(browser
, contents
, entry
->GetURL(), entry
->GetPageState());
1174 void ViewSource(Browser
* browser
,
1175 WebContents
* contents
,
1177 const content::PageState
& page_state
) {
1178 content::RecordAction(UserMetricsAction("ViewSource"));
1181 WebContents
* view_source_contents
= contents
->Clone();
1182 DCHECK(view_source_contents
->GetController().CanPruneAllButLastCommitted());
1183 view_source_contents
->GetController().PruneAllButLastCommitted();
1184 NavigationEntry
* last_committed_entry
=
1185 view_source_contents
->GetController().GetLastCommittedEntry();
1186 if (!last_committed_entry
)
1189 GURL view_source_url
=
1190 GURL(content::kViewSourceScheme
+ std::string(":") + url
.spec());
1191 last_committed_entry
->SetVirtualURL(view_source_url
);
1193 // Do not restore scroller position.
1194 last_committed_entry
->SetPageState(page_state
.RemoveScrollOffset());
1196 // Do not restore title, derive it from the url.
1197 last_committed_entry
->SetTitle(base::string16());
1199 // Now show view-source entry.
1200 if (browser
->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP
)) {
1201 // If this is a tabbed browser, just create a duplicate tab inside the same
1202 // window next to the tab being duplicated.
1203 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
1204 int add_types
= TabStripModel::ADD_ACTIVE
|
1205 TabStripModel::ADD_INHERIT_GROUP
;
1206 browser
->tab_strip_model()->InsertWebContentsAt(
1208 view_source_contents
,
1211 Browser
* b
= new Browser(
1212 Browser::CreateParams(Browser::TYPE_TABBED
, browser
->profile(),
1213 browser
->host_desktop_type()));
1215 // Preserve the size of the original window. The new window has already
1216 // been given an offset by the OS, so we shouldn't copy the old bounds.
1217 BrowserWindow
* new_window
= b
->window();
1218 new_window
->SetBounds(gfx::Rect(new_window
->GetRestoredBounds().origin(),
1219 browser
->window()->GetRestoredBounds().size()));
1221 // We need to show the browser now. Otherwise ContainerWin assumes the
1222 // WebContents is invisible and won't size it.
1223 b
->window()->Show();
1225 // The page transition below is only for the purpose of inserting the tab.
1226 b
->tab_strip_model()->AddWebContents(view_source_contents
, -1,
1227 ui::PAGE_TRANSITION_LINK
,
1228 TabStripModel::ADD_ACTIVE
);
1231 SessionService
* session_service
=
1232 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
1233 if (session_service
)
1234 session_service
->TabRestored(view_source_contents
, false);
1237 void ViewSelectedSource(Browser
* browser
) {
1238 ViewSource(browser
, browser
->tab_strip_model()->GetActiveWebContents());
1241 bool CanViewSource(const Browser
* browser
) {
1242 return !browser
->is_devtools() &&
1243 browser
->tab_strip_model()->GetActiveWebContents()->GetController().
1247 #if defined(ENABLE_EXTENSIONS)
1248 void CreateApplicationShortcuts(Browser
* browser
) {
1249 content::RecordAction(UserMetricsAction("CreateShortcut"));
1250 extensions::TabHelper::FromWebContents(
1251 browser
->tab_strip_model()->GetActiveWebContents())->
1252 CreateApplicationShortcuts();
1255 void CreateBookmarkAppFromCurrentWebContents(Browser
* browser
) {
1256 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1257 extensions::TabHelper::FromWebContents(
1258 browser
->tab_strip_model()->GetActiveWebContents())->
1259 CreateHostedAppFromWebContents();
1262 bool CanCreateApplicationShortcuts(const Browser
* browser
) {
1263 return extensions::TabHelper::FromWebContents(
1264 browser
->tab_strip_model()->GetActiveWebContents())->
1265 CanCreateApplicationShortcuts();
1268 bool CanCreateBookmarkApp(const Browser
* browser
) {
1269 return extensions::TabHelper::FromWebContents(
1270 browser
->tab_strip_model()->GetActiveWebContents())
1271 ->CanCreateBookmarkApp();
1274 void ConvertTabToAppWindow(Browser
* browser
,
1275 content::WebContents
* contents
) {
1276 const GURL
& url
= contents
->GetController().GetLastCommittedEntry()->GetURL();
1277 std::string app_name
= web_app::GenerateApplicationNameFromURL(url
);
1279 int index
= browser
->tab_strip_model()->GetIndexOfWebContents(contents
);
1281 browser
->tab_strip_model()->DetachWebContentsAt(index
);
1283 Browser
* app_browser
= new Browser(
1284 Browser::CreateParams::CreateForApp(app_name
,
1285 true /* trusted_source */,
1288 browser
->host_desktop_type()));
1289 app_browser
->tab_strip_model()->AppendWebContents(contents
, true);
1291 contents
->GetMutableRendererPrefs()->can_accept_load_drops
= false;
1292 contents
->GetRenderViewHost()->SyncRendererPrefs();
1293 app_browser
->window()->Show();
1295 #endif // defined(ENABLE_EXTENSIONS)
1297 } // namespace chrome