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