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/api/extension_action/extension_action_api.h"
22 #include "chrome/browser/extensions/tab_helper.h"
23 #include "chrome/browser/favicon/favicon_tab_helper.h"
24 #include "chrome/browser/lifetime/application_lifetime.h"
25 #include "chrome/browser/platform_util.h"
26 #include "chrome/browser/prefs/incognito_mode_prefs.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/rlz/rlz.h"
29 #include "chrome/browser/search/search.h"
30 #include "chrome/browser/sessions/session_service_factory.h"
31 #include "chrome/browser/sessions/tab_restore_service.h"
32 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
33 #include "chrome/browser/sessions/tab_restore_service_factory.h"
34 #include "chrome/browser/signin/signin_header_helper.h"
35 #include "chrome/browser/translate/chrome_translate_client.h"
36 #include "chrome/browser/ui/accelerator_utils.h"
37 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
38 #include "chrome/browser/ui/browser.h"
39 #include "chrome/browser/ui/browser_command_controller.h"
40 #include "chrome/browser/ui/browser_dialogs.h"
41 #include "chrome/browser/ui/browser_instant_controller.h"
42 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
43 #include "chrome/browser/ui/browser_tabstrip.h"
44 #include "chrome/browser/ui/browser_window.h"
45 #include "chrome/browser/ui/chrome_pages.h"
46 #include "chrome/browser/ui/find_bar/find_bar.h"
47 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
48 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
49 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
50 #include "chrome/browser/ui/location_bar/location_bar.h"
51 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
52 #include "chrome/browser/ui/search/search_tab_helper.h"
53 #include "chrome/browser/ui/status_bubble.h"
54 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
55 #include "chrome/browser/ui/tabs/tab_strip_model.h"
56 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
57 #include "chrome/browser/ui/zoom/zoom_controller.h"
58 #include "chrome/browser/upgrade_detector.h"
59 #include "chrome/browser/web_applications/web_app.h"
60 #include "chrome/common/chrome_switches.h"
61 #include "chrome/common/chrome_version_info.h"
62 #include "chrome/common/content_restriction.h"
63 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
64 #include "chrome/common/pref_names.h"
65 #include "components/bookmarks/browser/bookmark_model.h"
66 #include "components/bookmarks/browser/bookmark_utils.h"
67 #include "components/google/core/browser/google_util.h"
68 #include "components/translate/core/browser/language_state.h"
69 #include "components/web_modal/popup_manager.h"
70 #include "content/public/browser/devtools_agent_host.h"
71 #include "content/public/browser/navigation_controller.h"
72 #include "content/public/browser/navigation_entry.h"
73 #include "content/public/browser/notification_service.h"
74 #include "content/public/browser/page_navigator.h"
75 #include "content/public/browser/render_view_host.h"
76 #include "content/public/browser/render_widget_host_view.h"
77 #include "content/public/browser/user_metrics.h"
78 #include "content/public/browser/web_contents.h"
79 #include "content/public/common/renderer_preferences.h"
80 #include "content/public/common/url_constants.h"
81 #include "content/public/common/url_utils.h"
82 #include "content/public/common/user_agent.h"
83 #include "net/base/escape.h"
84 #include "ui/events/keycodes/keyboard_codes.h"
85
86 #if defined(OS_WIN)
87 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
88 #endif
89
90 #if defined(ENABLE_EXTENSIONS)
91 #include "extensions/browser/extension_registry.h"
92 #include "extensions/browser/extension_system.h"
93 #include "extensions/common/extension.h"
94 #include "extensions/common/extension_set.h"
95 #endif
96
97 #if defined(ENABLE_PRINTING)
98 #if defined(ENABLE_FULL_PRINTING)
99 #include "chrome/browser/printing/print_preview_dialog_controller.h"
100 #include "chrome/browser/printing/print_view_manager.h"
101 #else
102 #include "chrome/browser/printing/print_view_manager_basic.h"
103 #endif // defined(ENABLE_FULL_PRINTING)
104 #endif // defined(ENABLE_PRINTING)
105
106 namespace {
107 const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
108 }
109
110 using base::UserMetricsAction;
111 using content::NavigationController;
112 using content::NavigationEntry;
113 using content::OpenURLParams;
114 using content::Referrer;
115 using content::SSLStatus;
116 using content::WebContents;
117
118 namespace chrome {
119 namespace {
120
CanBookmarkCurrentPageInternal(const Browser * browser,bool check_remove_bookmark_ui)121 bool CanBookmarkCurrentPageInternal(const Browser* browser,
122 bool check_remove_bookmark_ui) {
123 BookmarkModel* model =
124 BookmarkModelFactory::GetForProfile(browser->profile());
125 return browser_defaults::bookmarks_enabled &&
126 browser->profile()->GetPrefs()->GetBoolean(
127 bookmarks::prefs::kEditBookmarksEnabled) &&
128 model && model->loaded() && browser->is_type_tabbed() &&
129 (!check_remove_bookmark_ui ||
130 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
131 }
132
GetBookmarkOverrideCommand(Profile * profile,const extensions::Extension ** extension,extensions::Command * command,extensions::CommandService::ExtensionCommandType * command_type)133 bool GetBookmarkOverrideCommand(
134 Profile* profile,
135 const extensions::Extension** extension,
136 extensions::Command* command,
137 extensions::CommandService::ExtensionCommandType* command_type) {
138 #if defined(ENABLE_EXTENSIONS)
139 DCHECK(extension);
140 DCHECK(command);
141 DCHECK(command_type);
142
143 ui::Accelerator bookmark_page_accelerator =
144 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
145 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
146 return false;
147
148 extensions::CommandService* command_service =
149 extensions::CommandService::Get(profile);
150 const extensions::ExtensionSet& extension_set =
151 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
152 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
153 i != extension_set.end();
154 ++i) {
155 extensions::Command prospective_command;
156 extensions::CommandService::ExtensionCommandType prospective_command_type;
157 if (command_service->GetBoundExtensionCommand((*i)->id(),
158 bookmark_page_accelerator,
159 &prospective_command,
160 &prospective_command_type)) {
161 *extension = i->get();
162 *command = prospective_command;
163 *command_type = prospective_command_type;
164 return true;
165 }
166 }
167 #endif
168
169 return false;
170 }
171
BookmarkCurrentPageInternal(Browser * browser)172 void BookmarkCurrentPageInternal(Browser* browser) {
173 content::RecordAction(UserMetricsAction("Star"));
174
175 BookmarkModel* model =
176 BookmarkModelFactory::GetForProfile(browser->profile());
177 if (!model || !model->loaded())
178 return; // Ignore requests until bookmarks are loaded.
179
180 GURL url;
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();
191 }
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);
201 }
202 }
203
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.
GetTabAndRevertIfNecessary(Browser * browser,WindowOpenDisposition disposition)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);
219 return new_tab;
220 }
221 case NEW_WINDOW: {
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();
229 return new_tab;
230 }
231 default:
232 browser->window()->GetLocationBar()->Revert();
233 return current_tab;
234 }
235 }
236
ReloadInternal(Browser * browser,WindowOpenDisposition disposition,bool ignore_cache)237 void ReloadInternal(Browser* browser,
238 WindowOpenDisposition disposition,
239 bool ignore_cache) {
240 // As this is caused by a user action, give the focus to the page.
241 //
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())
247 new_tab->Focus();
248 if (ignore_cache)
249 new_tab->GetController().ReloadIgnoringCache(true);
250 else
251 new_tab->GetController().Reload(true);
252 }
253
IsShowingWebContentsModalDialog(Browser * browser)254 bool IsShowingWebContentsModalDialog(Browser* browser) {
255 WebContents* web_contents =
256 browser->tab_strip_model()->GetActiveWebContents();
257 if (!web_contents)
258 return false;
259
260 // In test code we may not have a popup manager.
261 if (!browser->popup_manager())
262 return false;
263
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);
269 }
270
PrintPreviewShowing(const Browser * browser)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());
278 #else
279 return false;
280 #endif
281 }
282
283 } // namespace
284
IsCommandEnabled(Browser * browser,int command)285 bool IsCommandEnabled(Browser* browser, int command) {
286 return browser->command_controller()->command_updater()->IsCommandEnabled(
287 command);
288 }
289
SupportsCommand(Browser * browser,int command)290 bool SupportsCommand(Browser* browser, int command) {
291 return browser->command_controller()->command_updater()->SupportsCommand(
292 command);
293 }
294
ExecuteCommand(Browser * browser,int command)295 bool ExecuteCommand(Browser* browser, int command) {
296 return browser->command_controller()->command_updater()->ExecuteCommand(
297 command);
298 }
299
ExecuteCommandWithDisposition(Browser * browser,int command,WindowOpenDisposition disposition)300 bool ExecuteCommandWithDisposition(Browser* browser,
301 int command,
302 WindowOpenDisposition disposition) {
303 return browser->command_controller()->command_updater()->
304 ExecuteCommandWithDisposition(command, disposition);
305 }
306
UpdateCommandEnabled(Browser * browser,int command,bool enabled)307 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
308 browser->command_controller()->command_updater()->UpdateCommandEnabled(
309 command, enabled);
310 }
311
AddCommandObserver(Browser * browser,int command,CommandObserver * observer)312 void AddCommandObserver(Browser* browser,
313 int command,
314 CommandObserver* observer) {
315 browser->command_controller()->command_updater()->AddCommandObserver(
316 command, observer);
317 }
318
RemoveCommandObserver(Browser * browser,int command,CommandObserver * observer)319 void RemoveCommandObserver(Browser* browser,
320 int command,
321 CommandObserver* observer) {
322 browser->command_controller()->command_updater()->RemoveCommandObserver(
323 command, observer);
324 }
325
GetContentRestrictions(const Browser * browser)326 int GetContentRestrictions(const Browser* browser) {
327 int content_restrictions = 0;
328 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
329 if (current_tab) {
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;
341 }
342 return content_restrictions;
343 }
344
NewEmptyWindow(Profile * profile,HostDesktopType desktop_type)345 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
346 bool incognito = profile->IsOffTheRecord();
347 PrefService* prefs = profile->GetPrefs();
348 if (incognito) {
349 if (IncognitoModePrefs::GetAvailability(prefs) ==
350 IncognitoModePrefs::DISABLED) {
351 incognito = false;
352 }
353 } else if (profile->IsGuestSession() ||
354 (browser_defaults::kAlwaysOpenIncognitoWindow &&
355 IncognitoModePrefs::ShouldLaunchIncognito(
356 *CommandLine::ForCurrentProcess(), prefs))) {
357 incognito = true;
358 }
359
360 if (incognito) {
361 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
362 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
363 } else {
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);
371 }
372 }
373 }
374
OpenEmptyWindow(Profile * profile,HostDesktopType 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();
380 return browser;
381 }
382
OpenWindowWithRestoredTabs(Profile * profile,HostDesktopType host_desktop_type)383 void OpenWindowWithRestoredTabs(Profile* profile,
384 HostDesktopType host_desktop_type) {
385 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
386 if (service)
387 service->RestoreMostRecentEntry(NULL, host_desktop_type);
388 }
389
OpenURLOffTheRecord(Profile * profile,const GURL & url,chrome::HostDesktopType desktop_type)390 void OpenURLOffTheRecord(Profile* profile,
391 const GURL& url,
392 chrome::HostDesktopType desktop_type) {
393 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
394 desktop_type);
395 AddSelectedTabWithURL(displayer.browser(), url,
396 ui::PAGE_TRANSITION_LINK);
397 }
398
CanGoBack(const Browser * browser)399 bool CanGoBack(const Browser* browser) {
400 return browser->tab_strip_model()->GetActiveWebContents()->
401 GetController().CanGoBack();
402 }
403
GoBack(Browser * browser,WindowOpenDisposition disposition)404 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
405 content::RecordAction(UserMetricsAction("Back"));
406
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();
415 }
416 }
417
CanGoForward(const Browser * browser)418 bool CanGoForward(const Browser* browser) {
419 return browser->tab_strip_model()->GetActiveWebContents()->
420 GetController().CanGoForward();
421 }
422
GoForward(Browser * browser,WindowOpenDisposition disposition)423 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
424 content::RecordAction(UserMetricsAction("Forward"));
425 if (CanGoForward(browser)) {
426 GetTabAndRevertIfNecessary(browser, disposition)->
427 GetController().GoForward();
428 }
429 }
430
NavigateToIndexWithDisposition(Browser * browser,int index,WindowOpenDisposition disposition)431 bool NavigateToIndexWithDisposition(Browser* browser,
432 int index,
433 WindowOpenDisposition disposition) {
434 NavigationController* controller =
435 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
436 if (index < 0 || index >= controller->GetEntryCount())
437 return false;
438 controller->GoToIndex(index);
439 return true;
440 }
441
Reload(Browser * browser,WindowOpenDisposition disposition)442 void Reload(Browser* browser, WindowOpenDisposition disposition) {
443 content::RecordAction(UserMetricsAction("Reload"));
444 ReloadInternal(browser, disposition, false);
445 }
446
ReloadIgnoringCache(Browser * browser,WindowOpenDisposition disposition)447 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
448 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
449 ReloadInternal(browser, disposition, true);
450 }
451
CanReload(const Browser * browser)452 bool CanReload(const Browser* browser) {
453 return !browser->is_devtools();
454 }
455
Home(Browser * browser,WindowOpenDisposition disposition)456 void Home(Browser* browser, WindowOpenDisposition disposition) {
457 content::RecordAction(UserMetricsAction("Home"));
458
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();
463 if (pref_service) {
464 if (google_util::IsGoogleHomePageUrl(
465 GURL(pref_service->GetString(prefs::kHomePage)))) {
466 extra_headers = RLZTracker::GetAccessPointHttpHeader(
467 RLZTracker::ChromeHomePage());
468 }
469 }
470 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
471
472 GURL url = browser->profile()->GetHomePage();
473
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())
480 ->GetExtensionById(
481 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
482 extensions::ExtensionRegistry::EVERYTHING);
483 if (!extension)
484 return;
485
486 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
487 }
488 #endif
489
490 OpenURLParams params(
491 url, Referrer(), disposition,
492 ui::PageTransitionFromInt(
493 ui::PAGE_TRANSITION_AUTO_BOOKMARK |
494 ui::PAGE_TRANSITION_HOME_PAGE),
495 false);
496 params.extra_headers = extra_headers;
497 browser->OpenURL(params);
498 }
499
OpenCurrentURL(Browser * browser)500 void OpenCurrentURL(Browser* browser) {
501 content::RecordAction(UserMetricsAction("LoadURL"));
502 LocationBar* location_bar = browser->window()->GetLocationBar();
503 if (!location_bar)
504 return;
505
506 GURL url(location_bar->GetDestinationURL());
507
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))
524 return;
525
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
531 // opener.
532 params.tabstrip_add_types =
533 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
534 Navigate(¶ms);
535
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);
542 if (extension) {
543 CoreAppLauncherHandler::RecordAppLaunchType(
544 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
545 extension->GetType());
546 }
547 #endif
548 }
549
Stop(Browser * browser)550 void Stop(Browser* browser) {
551 content::RecordAction(UserMetricsAction("Stop"));
552 browser->tab_strip_model()->GetActiveWebContents()->Stop();
553 }
554
NewWindow(Browser * browser)555 void NewWindow(Browser* browser) {
556 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
557 browser->host_desktop_type());
558 }
559
NewIncognitoWindow(Browser * browser)560 void NewIncognitoWindow(Browser* browser) {
561 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
562 browser->host_desktop_type());
563 }
564
CloseWindow(Browser * browser)565 void CloseWindow(Browser* browser) {
566 content::RecordAction(UserMetricsAction("CloseWindow"));
567 browser->window()->Close();
568 }
569
NewTab(Browser * browser)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);
577
578 if (browser->is_type_tabbed()) {
579 AddTabAt(browser, GURL(), -1, true);
580 browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
581 } else {
582 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
583 browser->host_desktop_type());
584 Browser* b = displayer.browser();
585 AddTabAt(b, GURL(), -1, true);
586 b->window()->Show();
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();
591 }
592 }
593
CloseTab(Browser * browser)594 void CloseTab(Browser* browser) {
595 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
596 browser->tab_strip_model()->CloseSelectedTabs();
597 }
598
CanZoomIn(content::WebContents * contents)599 bool CanZoomIn(content::WebContents* contents) {
600 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
601 return zoom_controller->GetZoomPercent() !=
602 contents->GetMaximumZoomPercent() + 1;
603 }
604
CanZoomOut(content::WebContents * contents)605 bool CanZoomOut(content::WebContents* contents) {
606 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
607 return zoom_controller->GetZoomPercent() !=
608 contents->GetMinimumZoomPercent();
609 }
610
ActualSize(content::WebContents * contents)611 bool ActualSize(content::WebContents* contents) {
612 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
613 return zoom_controller->GetZoomPercent() != 100.0f;
614 }
615
GetRestoreTabType(const Browser * browser)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;
625 }
626
SelectNextTab(Browser * browser)627 void SelectNextTab(Browser* browser) {
628 content::RecordAction(UserMetricsAction("SelectNextTab"));
629 browser->tab_strip_model()->SelectNextTab();
630 }
631
SelectPreviousTab(Browser * browser)632 void SelectPreviousTab(Browser* browser) {
633 content::RecordAction(UserMetricsAction("SelectPrevTab"));
634 browser->tab_strip_model()->SelectPreviousTab();
635 }
636
MoveTabNext(Browser * browser)637 void MoveTabNext(Browser* browser) {
638 content::RecordAction(UserMetricsAction("MoveTabNext"));
639 browser->tab_strip_model()->MoveTabNext();
640 }
641
MoveTabPrevious(Browser * browser)642 void MoveTabPrevious(Browser* browser) {
643 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
644 browser->tab_strip_model()->MoveTabPrevious();
645 }
646
SelectNumberedTab(Browser * browser,int index)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);
651 }
652 }
653
SelectLastTab(Browser * browser)654 void SelectLastTab(Browser* browser) {
655 content::RecordAction(UserMetricsAction("SelectLastTab"));
656 browser->tab_strip_model()->SelectLastTab();
657 }
658
DuplicateTab(Browser * browser)659 void DuplicateTab(Browser* browser) {
660 content::RecordAction(UserMetricsAction("Duplicate"));
661 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
662 }
663
CanDuplicateTab(const Browser * browser)664 bool CanDuplicateTab(const Browser* browser) {
665 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
666 return contents && contents->GetController().GetLastCommittedEntry();
667 }
668
DuplicateTabAt(Browser * browser,int index)669 WebContents* DuplicateTabAt(Browser* browser, int index) {
670 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
671 CHECK(contents);
672 WebContents* contents_dupe = contents->Clone();
673
674 bool pinned = false;
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);
685 } else {
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(),
691 gfx::Rect(),
692 browser->profile(),
693 browser->host_desktop_type()));
694 } else {
695 new_browser = new Browser(
696 Browser::CreateParams(browser->type(), browser->profile(),
697 browser->host_desktop_type()));
698 }
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()));
704
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();
708
709 // The page transition below is only for the purpose of inserting the tab.
710 new_browser->tab_strip_model()->AddWebContents(
711 contents_dupe, -1,
712 ui::PAGE_TRANSITION_LINK,
713 TabStripModel::ADD_ACTIVE);
714 }
715
716 SessionService* session_service =
717 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
718 if (session_service)
719 session_service->TabRestored(contents_dupe, pinned);
720 return contents_dupe;
721 }
722
CanDuplicateTabAt(Browser * browser,int index)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();
727 }
728
ConvertPopupToTabbedBrowser(Browser * browser)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);
737 b->window()->Show();
738 }
739
Exit()740 void Exit() {
741 content::RecordAction(UserMetricsAction("Exit"));
742 chrome::AttemptUserExit();
743 }
744
BookmarkCurrentPage(Browser * browser)745 void BookmarkCurrentPage(Browser* browser) {
746 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
747
748 const extensions::Extension* extension = NULL;
749 extensions::Command command;
750 extensions::CommandService::ExtensionCommandType command_type;
751 if (GetBookmarkOverrideCommand(browser->profile(),
752 &extension,
753 &command,
754 &command_type)) {
755 switch (command_type) {
756 case extensions::CommandService::NAMED:
757 browser->window()->ExecuteExtensionCommand(extension, command);
758 break;
759 case extensions::CommandService::BROWSER_ACTION:
760 case extensions::CommandService::PAGE_ACTION:
761 // BookmarkCurrentPage is called through a user gesture, so it is safe
762 // to grant the active tab permission.
763 extensions::ExtensionActionAPI::Get(browser->profile())->
764 ShowExtensionActionPopup(extension, browser, true);
765 break;
766 }
767 return;
768 }
769
770 BookmarkCurrentPageInternal(browser);
771 }
772
CanBookmarkCurrentPage(const Browser * browser)773 bool CanBookmarkCurrentPage(const Browser* browser) {
774 return CanBookmarkCurrentPageInternal(browser, true);
775 }
776
BookmarkAllTabs(Browser * browser)777 void BookmarkAllTabs(Browser* browser) {
778 chrome::ShowBookmarkAllTabsDialog(browser);
779 }
780
CanBookmarkAllTabs(const Browser * browser)781 bool CanBookmarkAllTabs(const Browser* browser) {
782 return browser->tab_strip_model()->count() > 1 &&
783 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
784 CanBookmarkCurrentPageInternal(browser, false);
785 }
786
Translate(Browser * browser)787 void Translate(Browser* browser) {
788 if (!browser->window()->IsActive())
789 return;
790
791 WebContents* web_contents =
792 browser->tab_strip_model()->GetActiveWebContents();
793 ChromeTranslateClient* chrome_translate_client =
794 ChromeTranslateClient::FromWebContents(web_contents);
795
796 translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
797 if (chrome_translate_client) {
798 if (chrome_translate_client->GetLanguageState().translation_pending())
799 step = translate::TRANSLATE_STEP_TRANSLATING;
800 else if (chrome_translate_client->GetLanguageState().IsPageTranslated())
801 step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
802 }
803 browser->window()->ShowTranslateBubble(
804 web_contents, step, translate::TranslateErrors::NONE, true);
805 }
806
ManagePasswordsForPage(Browser * browser)807 void ManagePasswordsForPage(Browser* browser) {
808 if (!browser->window()->IsActive())
809 return;
810
811 WebContents* web_contents =
812 browser->tab_strip_model()->GetActiveWebContents();
813 chrome::ShowManagePasswordsBubble(web_contents);
814 }
815
TogglePagePinnedToStartScreen(Browser * browser)816 void TogglePagePinnedToStartScreen(Browser* browser) {
817 #if defined(OS_WIN)
818 MetroPinTabHelper::FromWebContents(
819 browser->tab_strip_model()->GetActiveWebContents())->
820 TogglePinnedToStartScreen();
821 #endif
822 }
823
SavePage(Browser * browser)824 void SavePage(Browser* browser) {
825 content::RecordAction(UserMetricsAction("SavePage"));
826 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
827 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
828 content::RecordAction(UserMetricsAction("PDF.SavePage"));
829 current_tab->OnSavePage();
830 }
831
CanSavePage(const Browser * browser)832 bool CanSavePage(const Browser* browser) {
833 // LocalState can be NULL in tests.
834 if (g_browser_process->local_state() &&
835 !g_browser_process->local_state()->GetBoolean(
836 prefs::kAllowFileSelectionDialogs)) {
837 return false;
838 }
839 return !browser->is_devtools() &&
840 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
841 }
842
ShowFindBar(Browser * browser)843 void ShowFindBar(Browser* browser) {
844 browser->GetFindBarController()->Show();
845 }
846
ShowWebsiteSettings(Browser * browser,content::WebContents * web_contents,const GURL & url,const SSLStatus & ssl)847 void ShowWebsiteSettings(Browser* browser,
848 content::WebContents* web_contents,
849 const GURL& url,
850 const SSLStatus& ssl) {
851 browser->window()->ShowWebsiteSettings(
852 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
853 web_contents, url, ssl);
854 }
855
Print(Browser * browser)856 void Print(Browser* browser) {
857 #if defined(ENABLE_PRINTING)
858 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
859
860 #if defined(ENABLE_FULL_PRINTING)
861 printing::PrintViewManager* print_view_manager =
862 printing::PrintViewManager::FromWebContents(contents);
863 if (!browser->profile()->GetPrefs()->GetBoolean(
864 prefs::kPrintPreviewDisabled)) {
865 print_view_manager->PrintPreviewNow(false);
866 return;
867 }
868 #else // ENABLE_FULL_PRINTING
869 printing::PrintViewManagerBasic* print_view_manager =
870 printing::PrintViewManagerBasic::FromWebContents(contents);
871 #endif // ENABLE_FULL_PRINTING
872
873 #if !defined(DISABLE_BASIC_PRINTING)
874 print_view_manager->PrintNow();
875 #endif // DISABLE_BASIC_PRINTING
876
877 #endif // defined(ENABLE_PRINTING)
878 }
879
CanPrint(Browser * browser)880 bool CanPrint(Browser* browser) {
881 // Do not print when printing is disabled via pref or policy.
882 // Do not print when a constrained window is showing. It's confusing.
883 // TODO(gbillock): Need to re-assess the call to
884 // IsShowingWebContentsModalDialog after a popup management policy is
885 // refined -- we will probably want to just queue the print request, not
886 // block it.
887 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
888 !(IsShowingWebContentsModalDialog(browser) ||
889 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
890 }
891
892 #if !defined(DISABLE_BASIC_PRINTING)
BasicPrint(Browser * browser)893 void BasicPrint(Browser* browser) {
894 #if defined(ENABLE_FULL_PRINTING)
895 printing::PrintViewManager* print_view_manager =
896 printing::PrintViewManager::FromWebContents(
897 browser->tab_strip_model()->GetActiveWebContents());
898 print_view_manager->BasicPrint();
899 #endif
900 }
901
CanBasicPrint(Browser * browser)902 bool CanBasicPrint(Browser* browser) {
903 // If printing is not disabled via pref or policy, it is always possible to
904 // advanced print when the print preview is visible. The exception to this
905 // is under Win8 ash, since showing the advanced print dialog will open it
906 // modally on the Desktop and hang the browser.
907 #if defined(OS_WIN)
908 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
909 return false;
910 #endif
911
912 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
913 (PrintPreviewShowing(browser) || CanPrint(browser));
914 }
915 #endif // !DISABLE_BASIC_PRINTING
916
EmailPageLocation(Browser * browser)917 void EmailPageLocation(Browser* browser) {
918 content::RecordAction(UserMetricsAction("EmailPageLocation"));
919 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
920 DCHECK(wc);
921
922 std::string title = net::EscapeQueryParamValue(
923 base::UTF16ToUTF8(wc->GetTitle()), false);
924 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
925 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
926 title + "&body=%0A%0A" + page_url;
927 platform_util::OpenExternal(browser->profile(), GURL(mailto));
928 }
929
CanEmailPageLocation(const Browser * browser)930 bool CanEmailPageLocation(const Browser* browser) {
931 return browser->toolbar_model()->ShouldDisplayURL() &&
932 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
933 }
934
Cut(Browser * browser)935 void Cut(Browser* browser) {
936 content::RecordAction(UserMetricsAction("Cut"));
937 browser->window()->Cut();
938 }
939
Copy(Browser * browser)940 void Copy(Browser* browser) {
941 content::RecordAction(UserMetricsAction("Copy"));
942 browser->window()->Copy();
943 }
944
Paste(Browser * browser)945 void Paste(Browser* browser) {
946 content::RecordAction(UserMetricsAction("Paste"));
947 browser->window()->Paste();
948 }
949
Find(Browser * browser)950 void Find(Browser* browser) {
951 content::RecordAction(UserMetricsAction("Find"));
952 FindInPage(browser, false, false);
953 }
954
FindNext(Browser * browser)955 void FindNext(Browser* browser) {
956 content::RecordAction(UserMetricsAction("FindNext"));
957 FindInPage(browser, true, true);
958 }
959
FindPrevious(Browser * browser)960 void FindPrevious(Browser* browser) {
961 content::RecordAction(UserMetricsAction("FindPrevious"));
962 FindInPage(browser, true, false);
963 }
964
FindInPage(Browser * browser,bool find_next,bool forward_direction)965 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
966 ShowFindBar(browser);
967 if (find_next) {
968 base::string16 find_text;
969 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
970 browser->tab_strip_model()->GetActiveWebContents());
971 #if defined(OS_MACOSX)
972 // We always want to search for the current contents of the find bar on
973 // OS X. For regular profile it's always the current find pboard. For
974 // Incognito window it's the newest value of the find pboard content and
975 // user-typed text.
976 FindBar* find_bar = browser->GetFindBarController()->find_bar();
977 find_text = find_bar->GetFindText();
978 #endif
979 find_helper->StartFinding(find_text, forward_direction, false);
980 }
981 }
982
Zoom(Browser * browser,content::PageZoom zoom)983 void Zoom(Browser* browser, content::PageZoom zoom) {
984 chrome_page_zoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
985 zoom);
986 }
987
FocusToolbar(Browser * browser)988 void FocusToolbar(Browser* browser) {
989 content::RecordAction(UserMetricsAction("FocusToolbar"));
990 browser->window()->FocusToolbar();
991 }
992
FocusLocationBar(Browser * browser)993 void FocusLocationBar(Browser* browser) {
994 content::RecordAction(UserMetricsAction("FocusLocation"));
995 browser->window()->SetFocusToLocationBar(true);
996 }
997
FocusSearch(Browser * browser)998 void FocusSearch(Browser* browser) {
999 // TODO(beng): replace this with FocusLocationBar
1000 content::RecordAction(UserMetricsAction("FocusSearch"));
1001 browser->window()->GetLocationBar()->FocusSearch();
1002 }
1003
FocusAppMenu(Browser * browser)1004 void FocusAppMenu(Browser* browser) {
1005 content::RecordAction(UserMetricsAction("FocusAppMenu"));
1006 browser->window()->FocusAppMenu();
1007 }
1008
FocusBookmarksToolbar(Browser * browser)1009 void FocusBookmarksToolbar(Browser* browser) {
1010 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
1011 browser->window()->FocusBookmarksToolbar();
1012 }
1013
FocusInfobars(Browser * browser)1014 void FocusInfobars(Browser* browser) {
1015 content::RecordAction(UserMetricsAction("FocusInfobars"));
1016 browser->window()->FocusInfobars();
1017 }
1018
FocusNextPane(Browser * browser)1019 void FocusNextPane(Browser* browser) {
1020 content::RecordAction(UserMetricsAction("FocusNextPane"));
1021 browser->window()->RotatePaneFocus(true);
1022 }
1023
FocusPreviousPane(Browser * browser)1024 void FocusPreviousPane(Browser* browser) {
1025 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1026 browser->window()->RotatePaneFocus(false);
1027 }
1028
ToggleDevToolsWindow(Browser * browser,DevToolsToggleAction action)1029 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1030 if (action.type() == DevToolsToggleAction::kShowConsole)
1031 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1032 else
1033 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1034 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1035 }
1036
CanOpenTaskManager()1037 bool CanOpenTaskManager() {
1038 #if defined(ENABLE_TASK_MANAGER)
1039 return true;
1040 #else
1041 return false;
1042 #endif
1043 }
1044
OpenTaskManager(Browser * browser)1045 void OpenTaskManager(Browser* browser) {
1046 #if defined(ENABLE_TASK_MANAGER)
1047 content::RecordAction(UserMetricsAction("TaskManager"));
1048 chrome::ShowTaskManager(browser);
1049 #else
1050 NOTREACHED();
1051 #endif
1052 }
1053
OpenFeedbackDialog(Browser * browser)1054 void OpenFeedbackDialog(Browser* browser) {
1055 content::RecordAction(UserMetricsAction("Feedback"));
1056 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1057 }
1058
ToggleBookmarkBar(Browser * browser)1059 void ToggleBookmarkBar(Browser* browser) {
1060 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1061 ToggleBookmarkBarWhenVisible(browser->profile());
1062 }
1063
ShowAppMenu(Browser * browser)1064 void ShowAppMenu(Browser* browser) {
1065 // We record the user metric for this event in WrenchMenu::RunMenu.
1066 browser->window()->ShowAppMenu();
1067 }
1068
ShowAvatarMenu(Browser * browser)1069 void ShowAvatarMenu(Browser* browser) {
1070 browser->window()->ShowAvatarBubbleFromAvatarButton(
1071 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1072 signin::ManageAccountsParams());
1073 }
1074
OpenUpdateChromeDialog(Browser * browser)1075 void OpenUpdateChromeDialog(Browser* browser) {
1076 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1077 content::NotificationService::current()->Notify(
1078 chrome::NOTIFICATION_OUTDATED_INSTALL,
1079 content::NotificationService::AllSources(),
1080 content::NotificationService::NoDetails());
1081 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1082 content::NotificationService::current()->Notify(
1083 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1084 content::NotificationService::AllSources(),
1085 content::NotificationService::NoDetails());
1086 } else {
1087 content::RecordAction(UserMetricsAction("UpdateChrome"));
1088 browser->window()->ShowUpdateChromeDialog();
1089 }
1090 }
1091
ToggleSpeechInput(Browser * browser)1092 void ToggleSpeechInput(Browser* browser) {
1093 SearchTabHelper* search_tab_helper =
1094 SearchTabHelper::FromWebContents(
1095 browser->tab_strip_model()->GetActiveWebContents());
1096 // |search_tab_helper| can be null in unit tests.
1097 if (search_tab_helper)
1098 search_tab_helper->ToggleVoiceSearch();
1099 }
1100
DistillCurrentPage(Browser * browser)1101 void DistillCurrentPage(Browser* browser) {
1102 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1103 }
1104
CanRequestTabletSite(WebContents * current_tab)1105 bool CanRequestTabletSite(WebContents* current_tab) {
1106 return current_tab &&
1107 current_tab->GetController().GetLastCommittedEntry() != NULL;
1108 }
1109
IsRequestingTabletSite(Browser * browser)1110 bool IsRequestingTabletSite(Browser* browser) {
1111 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1112 if (!current_tab)
1113 return false;
1114 content::NavigationEntry* entry =
1115 current_tab->GetController().GetLastCommittedEntry();
1116 if (!entry)
1117 return false;
1118 return entry->GetIsOverridingUserAgent();
1119 }
1120
ToggleRequestTabletSite(Browser * browser)1121 void ToggleRequestTabletSite(Browser* browser) {
1122 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1123 if (!current_tab)
1124 return;
1125 NavigationController& controller = current_tab->GetController();
1126 NavigationEntry* entry = controller.GetLastCommittedEntry();
1127 if (!entry)
1128 return;
1129 if (entry->GetIsOverridingUserAgent()) {
1130 entry->SetIsOverridingUserAgent(false);
1131 } else {
1132 entry->SetIsOverridingUserAgent(true);
1133 chrome::VersionInfo version_info;
1134 std::string product;
1135 if (version_info.is_valid())
1136 product = version_info.ProductNameAndVersionForUserAgent();
1137 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1138 kOsOverrideForTabletSite, product));
1139 }
1140 controller.ReloadOriginalRequestURL(true);
1141 }
1142
ToggleFullscreenMode(Browser * browser)1143 void ToggleFullscreenMode(Browser* browser) {
1144 DCHECK(browser);
1145 browser->fullscreen_controller()->ToggleBrowserFullscreenMode();
1146 }
1147
ClearCache(Browser * browser)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.
1154 }
1155
IsDebuggerAttachedToCurrentTab(Browser * browser)1156 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1157 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1158 return contents ?
1159 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1160 }
1161
ViewSource(Browser * browser,WebContents * contents)1162 void ViewSource(Browser* browser, WebContents* contents) {
1163 DCHECK(contents);
1164
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();
1168 if (!entry)
1169 return;
1170
1171 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1172 }
1173
ViewSource(Browser * browser,WebContents * contents,const GURL & url,const content::PageState & page_state)1174 void ViewSource(Browser* browser,
1175 WebContents* contents,
1176 const GURL& url,
1177 const content::PageState& page_state) {
1178 content::RecordAction(UserMetricsAction("ViewSource"));
1179 DCHECK(contents);
1180
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)
1187 return;
1188
1189 GURL view_source_url =
1190 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1191 last_committed_entry->SetVirtualURL(view_source_url);
1192
1193 // Do not restore scroller position.
1194 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1195
1196 // Do not restore title, derive it from the url.
1197 last_committed_entry->SetTitle(base::string16());
1198
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(
1207 index + 1,
1208 view_source_contents,
1209 add_types);
1210 } else {
1211 Browser* b = new Browser(
1212 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1213 browser->host_desktop_type()));
1214
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()));
1220
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();
1224
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);
1229 }
1230
1231 SessionService* session_service =
1232 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1233 if (session_service)
1234 session_service->TabRestored(view_source_contents, false);
1235 }
1236
ViewSelectedSource(Browser * browser)1237 void ViewSelectedSource(Browser* browser) {
1238 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1239 }
1240
CanViewSource(const Browser * browser)1241 bool CanViewSource(const Browser* browser) {
1242 return !browser->is_devtools() &&
1243 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1244 CanViewSource();
1245 }
1246
CreateApplicationShortcuts(Browser * browser)1247 void CreateApplicationShortcuts(Browser* browser) {
1248 content::RecordAction(UserMetricsAction("CreateShortcut"));
1249 extensions::TabHelper::FromWebContents(
1250 browser->tab_strip_model()->GetActiveWebContents())->
1251 CreateApplicationShortcuts();
1252 }
1253
CreateBookmarkAppFromCurrentWebContents(Browser * browser)1254 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1255 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1256 extensions::TabHelper::FromWebContents(
1257 browser->tab_strip_model()->GetActiveWebContents())->
1258 CreateHostedAppFromWebContents();
1259 }
1260
CanCreateApplicationShortcuts(const Browser * browser)1261 bool CanCreateApplicationShortcuts(const Browser* browser) {
1262 return extensions::TabHelper::FromWebContents(
1263 browser->tab_strip_model()->GetActiveWebContents())->
1264 CanCreateApplicationShortcuts();
1265 }
1266
CanCreateBookmarkApp(const Browser * browser)1267 bool CanCreateBookmarkApp(const Browser* browser) {
1268 return extensions::TabHelper::FromWebContents(
1269 browser->tab_strip_model()->GetActiveWebContents())
1270 ->CanCreateBookmarkApp();
1271 }
1272
ConvertTabToAppWindow(Browser * browser,content::WebContents * contents)1273 void ConvertTabToAppWindow(Browser* browser,
1274 content::WebContents* contents) {
1275 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1276 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1277
1278 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1279 if (index >= 0)
1280 browser->tab_strip_model()->DetachWebContentsAt(index);
1281
1282 Browser* app_browser = new Browser(
1283 Browser::CreateParams::CreateForApp(app_name,
1284 true /* trusted_source */,
1285 gfx::Rect(),
1286 browser->profile(),
1287 browser->host_desktop_type()));
1288 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1289
1290 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1291 contents->GetRenderViewHost()->SyncRendererPrefs();
1292 app_browser->window()->Show();
1293 }
1294
1295 } // namespace chrome
1296