1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/browser_commands.h"
7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/browsing_data/browsing_data_helper.h"
15 #include "chrome/browser/browsing_data/browsing_data_remover.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/chrome_page_zoom.h"
18 #include "chrome/browser/devtools/devtools_window.h"
19 #include "chrome/browser/dom_distiller/tab_utils.h"
20 #include "chrome/browser/favicon/favicon_tab_helper.h"
21 #include "chrome/browser/lifetime/application_lifetime.h"
22 #include "chrome/browser/platform_util.h"
23 #include "chrome/browser/prefs/incognito_mode_prefs.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/rlz/rlz.h"
26 #include "chrome/browser/search/search.h"
27 #include "chrome/browser/sessions/session_service_factory.h"
28 #include "chrome/browser/sessions/tab_restore_service.h"
29 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
30 #include "chrome/browser/sessions/tab_restore_service_factory.h"
31 #include "chrome/browser/signin/signin_header_helper.h"
32 #include "chrome/browser/translate/chrome_translate_client.h"
33 #include "chrome/browser/ui/accelerator_utils.h"
34 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/browser_command_controller.h"
37 #include "chrome/browser/ui/browser_dialogs.h"
38 #include "chrome/browser/ui/browser_instant_controller.h"
39 #include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
40 #include "chrome/browser/ui/browser_tabstrip.h"
41 #include "chrome/browser/ui/browser_window.h"
42 #include "chrome/browser/ui/chrome_pages.h"
43 #include "chrome/browser/ui/find_bar/find_bar.h"
44 #include "chrome/browser/ui/find_bar/find_bar_controller.h"
45 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
46 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
47 #include "chrome/browser/ui/location_bar/location_bar.h"
48 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
49 #include "chrome/browser/ui/search/search_tab_helper.h"
50 #include "chrome/browser/ui/status_bubble.h"
51 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
52 #include "chrome/browser/ui/tabs/tab_strip_model.h"
53 #include "chrome/browser/ui/zoom/zoom_controller.h"
54 #include "chrome/browser/upgrade_detector.h"
55 #include "chrome/common/chrome_switches.h"
56 #include "chrome/common/chrome_version_info.h"
57 #include "chrome/common/content_restriction.h"
58 #include "chrome/common/pref_names.h"
59 #include "components/bookmarks/browser/bookmark_model.h"
60 #include "components/bookmarks/browser/bookmark_utils.h"
61 #include "components/google/core/browser/google_util.h"
62 #include "components/translate/core/browser/language_state.h"
63 #include "components/web_modal/popup_manager.h"
64 #include "content/public/browser/devtools_agent_host.h"
65 #include "content/public/browser/navigation_controller.h"
66 #include "content/public/browser/navigation_entry.h"
67 #include "content/public/browser/notification_service.h"
68 #include "content/public/browser/page_navigator.h"
69 #include "content/public/browser/render_view_host.h"
70 #include "content/public/browser/render_widget_host_view.h"
71 #include "content/public/browser/user_metrics.h"
72 #include "content/public/browser/web_contents.h"
73 #include "content/public/common/page_state.h"
74 #include "content/public/common/renderer_preferences.h"
75 #include "content/public/common/url_constants.h"
76 #include "content/public/common/url_utils.h"
77 #include "content/public/common/user_agent.h"
78 #include "net/base/escape.h"
79 #include "ui/events/keycodes/keyboard_codes.h"
82 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
85 #if defined(ENABLE_EXTENSIONS)
86 #include "chrome/browser/extensions/api/commands/command_service.h"
87 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
88 #include "chrome/browser/extensions/tab_helper.h"
89 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
90 #include "chrome/browser/web_applications/web_app.h"
91 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
92 #include "extensions/browser/extension_registry.h"
93 #include "extensions/browser/extension_system.h"
94 #include "extensions/common/extension.h"
95 #include "extensions/common/extension_set.h"
98 #if defined(ENABLE_PRINTING)
99 #if defined(ENABLE_PRINT_PREVIEW)
100 #include "chrome/browser/printing/print_preview_dialog_controller.h"
101 #include "chrome/browser/printing/print_view_manager.h"
103 #include "chrome/browser/printing/print_view_manager_basic.h"
104 #endif // defined(ENABLE_PRINT_PREVIEW)
105 #endif // defined(ENABLE_PRINTING)
108 const char kOsOverrideForTabletSite[] = "Linux; Android 4.0.3";
111 using base::UserMetricsAction;
112 using content::NavigationController;
113 using content::NavigationEntry;
114 using content::OpenURLParams;
115 using content::Referrer;
116 using content::SSLStatus;
117 using content::WebContents;
122 bool CanBookmarkCurrentPageInternal(const Browser* browser,
123 bool check_remove_bookmark_ui) {
124 BookmarkModel* model =
125 BookmarkModelFactory::GetForProfile(browser->profile());
126 return browser_defaults::bookmarks_enabled &&
127 browser->profile()->GetPrefs()->GetBoolean(
128 bookmarks::prefs::kEditBookmarksEnabled) &&
129 model && model->loaded() && browser->is_type_tabbed() &&
130 (!check_remove_bookmark_ui ||
131 !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
134 #if defined(ENABLE_EXTENSIONS)
135 bool GetBookmarkOverrideCommand(
137 const extensions::Extension** extension,
138 extensions::Command* command,
139 extensions::CommandService::ExtensionCommandType* command_type) {
142 DCHECK(command_type);
144 ui::Accelerator bookmark_page_accelerator =
145 chrome::GetPrimaryChromeAcceleratorForCommandId(IDC_BOOKMARK_PAGE);
146 if (bookmark_page_accelerator.key_code() == ui::VKEY_UNKNOWN)
149 extensions::CommandService* command_service =
150 extensions::CommandService::Get(profile);
151 const extensions::ExtensionSet& extension_set =
152 extensions::ExtensionRegistry::Get(profile)->enabled_extensions();
153 for (extensions::ExtensionSet::const_iterator i = extension_set.begin();
154 i != extension_set.end();
156 extensions::Command prospective_command;
157 extensions::CommandService::ExtensionCommandType prospective_command_type;
158 if (command_service->GetBoundExtensionCommand((*i)->id(),
159 bookmark_page_accelerator,
160 &prospective_command,
161 &prospective_command_type)) {
162 *extension = i->get();
163 *command = prospective_command;
164 *command_type = prospective_command_type;
172 void BookmarkCurrentPageInternal(Browser* browser) {
173 content::RecordAction(UserMetricsAction("Star"));
175 BookmarkModel* model =
176 BookmarkModelFactory::GetForProfile(browser->profile());
177 if (!model || !model->loaded())
178 return; // Ignore requests until bookmarks are loaded.
181 base::string16 title;
182 WebContents* web_contents =
183 browser->tab_strip_model()->GetActiveWebContents();
184 GetURLAndTitleToBookmark(web_contents, &url, &title);
185 bool is_bookmarked_by_any = model->IsBookmarked(url);
186 if (!is_bookmarked_by_any &&
187 web_contents->GetBrowserContext()->IsOffTheRecord()) {
188 // If we're incognito the favicon may not have been saved. Save it now
189 // so that bookmarks have an icon for the page.
190 FaviconTabHelper::FromWebContents(web_contents)->SaveFavicon();
192 bool was_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
193 bookmarks::AddIfNotBookmarked(model, url, title);
194 bool is_bookmarked_by_user = bookmarks::IsBookmarkedByUser(model, url);
195 // Make sure the model actually added a bookmark before showing the star. A
196 // bookmark isn't created if the url is invalid.
197 if (browser->window()->IsActive() && is_bookmarked_by_user) {
198 // Only show the bubble if the window is active, otherwise we may get into
199 // weird situations where the bubble is deleted as soon as it is shown.
200 browser->window()->ShowBookmarkBubble(url, was_bookmarked_by_user);
204 // Based on |disposition|, creates a new tab as necessary, and returns the
205 // appropriate tab to navigate. If that tab is the current tab, reverts the
206 // location bar contents, since all browser-UI-triggered navigations should
207 // revert any omnibox edits in the current tab.
208 WebContents* GetTabAndRevertIfNecessary(Browser* browser,
209 WindowOpenDisposition disposition) {
210 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
211 switch (disposition) {
212 case NEW_FOREGROUND_TAB:
213 case NEW_BACKGROUND_TAB: {
214 WebContents* new_tab = current_tab->Clone();
215 browser->tab_strip_model()->AddWebContents(
216 new_tab, -1, ui::PAGE_TRANSITION_LINK,
217 (disposition == NEW_FOREGROUND_TAB) ?
218 TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE);
222 WebContents* new_tab = current_tab->Clone();
223 Browser* new_browser = new Browser(Browser::CreateParams(
224 browser->profile(), browser->host_desktop_type()));
225 new_browser->tab_strip_model()->AddWebContents(
226 new_tab, -1, ui::PAGE_TRANSITION_LINK,
227 TabStripModel::ADD_ACTIVE);
228 new_browser->window()->Show();
232 browser->window()->GetLocationBar()->Revert();
237 void ReloadInternal(Browser* browser,
238 WindowOpenDisposition disposition,
240 // As this is caused by a user action, give the focus to the page.
242 // Also notify RenderViewHostDelegate of the user gesture; this is
243 // normally done in Browser::Navigate, but a reload bypasses Navigate.
244 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
245 new_tab->UserGestureDone();
246 if (!new_tab->FocusLocationBarByDefault())
249 new_tab->GetController().ReloadIgnoringCache(true);
251 new_tab->GetController().Reload(true);
254 bool IsShowingWebContentsModalDialog(Browser* browser) {
255 WebContents* web_contents =
256 browser->tab_strip_model()->GetActiveWebContents();
260 // In test code we may not have a popup manager.
261 if (!browser->popup_manager())
264 // TODO(gbillock): This is currently called in production by the CanPrint
265 // method, and may be too restrictive if we allow print preview to overlap.
266 // Re-assess how to queue print preview after we know more about popup
267 // management policy.
268 return browser->popup_manager()->IsWebModalDialogActive(web_contents);
271 #if defined(ENABLE_BASIC_PRINTING)
272 bool PrintPreviewShowing(const Browser* browser) {
273 #if defined(ENABLE_PRINT_PREVIEW)
274 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
275 printing::PrintPreviewDialogController* controller =
276 printing::PrintPreviewDialogController::GetInstance();
277 return controller && (controller->GetPrintPreviewForContents(contents) ||
278 controller->is_creating_print_preview_dialog());
283 #endif // ENABLE_BASIC_PRINTING
287 bool IsCommandEnabled(Browser* browser, int command) {
288 return browser->command_controller()->command_updater()->IsCommandEnabled(
292 bool SupportsCommand(Browser* browser, int command) {
293 return browser->command_controller()->command_updater()->SupportsCommand(
297 bool ExecuteCommand(Browser* browser, int command) {
298 return browser->command_controller()->command_updater()->ExecuteCommand(
302 bool ExecuteCommandWithDisposition(Browser* browser,
304 WindowOpenDisposition disposition) {
305 return browser->command_controller()->command_updater()->
306 ExecuteCommandWithDisposition(command, disposition);
309 void UpdateCommandEnabled(Browser* browser, int command, bool enabled) {
310 browser->command_controller()->command_updater()->UpdateCommandEnabled(
314 void AddCommandObserver(Browser* browser,
316 CommandObserver* observer) {
317 browser->command_controller()->command_updater()->AddCommandObserver(
321 void RemoveCommandObserver(Browser* browser,
323 CommandObserver* observer) {
324 browser->command_controller()->command_updater()->RemoveCommandObserver(
328 int GetContentRestrictions(const Browser* browser) {
329 int content_restrictions = 0;
330 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
332 CoreTabHelper* core_tab_helper =
333 CoreTabHelper::FromWebContents(current_tab);
334 content_restrictions = core_tab_helper->content_restrictions();
335 NavigationEntry* last_committed_entry =
336 current_tab->GetController().GetLastCommittedEntry();
337 if (!content::IsSavableURL(
338 last_committed_entry ? last_committed_entry->GetURL() : GURL()) ||
339 current_tab->ShowingInterstitialPage())
340 content_restrictions |= CONTENT_RESTRICTION_SAVE;
341 if (current_tab->ShowingInterstitialPage())
342 content_restrictions |= CONTENT_RESTRICTION_PRINT;
344 return content_restrictions;
347 void NewEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
348 bool incognito = profile->IsOffTheRecord();
349 PrefService* prefs = profile->GetPrefs();
351 if (IncognitoModePrefs::GetAvailability(prefs) ==
352 IncognitoModePrefs::DISABLED) {
355 } else if (profile->IsGuestSession() ||
356 (browser_defaults::kAlwaysOpenIncognitoWindow &&
357 IncognitoModePrefs::ShouldLaunchIncognito(
358 *CommandLine::ForCurrentProcess(), prefs))) {
363 content::RecordAction(UserMetricsAction("NewIncognitoWindow"));
364 OpenEmptyWindow(profile->GetOffTheRecordProfile(), desktop_type);
366 content::RecordAction(UserMetricsAction("NewWindow"));
367 SessionService* session_service =
368 SessionServiceFactory::GetForProfileForSessionRestore(
369 profile->GetOriginalProfile());
370 if (!session_service ||
371 !session_service->RestoreIfNecessary(std::vector<GURL>())) {
372 OpenEmptyWindow(profile->GetOriginalProfile(), desktop_type);
377 Browser* OpenEmptyWindow(Profile* profile, HostDesktopType desktop_type) {
378 Browser* browser = new Browser(
379 Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
380 AddTabAt(browser, GURL(), -1, true);
381 browser->window()->Show();
385 void OpenWindowWithRestoredTabs(Profile* profile,
386 HostDesktopType host_desktop_type) {
387 TabRestoreService* service = TabRestoreServiceFactory::GetForProfile(profile);
389 service->RestoreMostRecentEntry(NULL, host_desktop_type);
392 void OpenURLOffTheRecord(Profile* profile,
394 chrome::HostDesktopType desktop_type) {
395 ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile(),
397 AddSelectedTabWithURL(displayer.browser(), url,
398 ui::PAGE_TRANSITION_LINK);
401 bool CanGoBack(const Browser* browser) {
402 return browser->tab_strip_model()->GetActiveWebContents()->
403 GetController().CanGoBack();
406 void GoBack(Browser* browser, WindowOpenDisposition disposition) {
407 content::RecordAction(UserMetricsAction("Back"));
409 if (CanGoBack(browser)) {
410 WebContents* current_tab =
411 browser->tab_strip_model()->GetActiveWebContents();
412 WebContents* new_tab = GetTabAndRevertIfNecessary(browser, disposition);
413 // If we are on an interstitial page and clone the tab, it won't be copied
414 // to the new tab, so we don't need to go back.
415 if ((new_tab == current_tab) || !current_tab->ShowingInterstitialPage())
416 new_tab->GetController().GoBack();
420 bool CanGoForward(const Browser* browser) {
421 return browser->tab_strip_model()->GetActiveWebContents()->
422 GetController().CanGoForward();
425 void GoForward(Browser* browser, WindowOpenDisposition disposition) {
426 content::RecordAction(UserMetricsAction("Forward"));
427 if (CanGoForward(browser)) {
428 GetTabAndRevertIfNecessary(browser, disposition)->
429 GetController().GoForward();
433 bool NavigateToIndexWithDisposition(Browser* browser,
435 WindowOpenDisposition disposition) {
436 NavigationController* controller =
437 &GetTabAndRevertIfNecessary(browser, disposition)->GetController();
438 if (index < 0 || index >= controller->GetEntryCount())
440 controller->GoToIndex(index);
444 void Reload(Browser* browser, WindowOpenDisposition disposition) {
445 content::RecordAction(UserMetricsAction("Reload"));
446 ReloadInternal(browser, disposition, false);
449 void ReloadIgnoringCache(Browser* browser, WindowOpenDisposition disposition) {
450 content::RecordAction(UserMetricsAction("ReloadIgnoringCache"));
451 ReloadInternal(browser, disposition, true);
454 bool CanReload(const Browser* browser) {
455 return !browser->is_devtools();
458 void Home(Browser* browser, WindowOpenDisposition disposition) {
459 content::RecordAction(UserMetricsAction("Home"));
461 std::string extra_headers;
462 #if defined(ENABLE_RLZ) && !defined(OS_IOS)
463 // If the home page is a Google home page, add the RLZ header to the request.
464 PrefService* pref_service = browser->profile()->GetPrefs();
466 if (google_util::IsGoogleHomePageUrl(
467 GURL(pref_service->GetString(prefs::kHomePage)))) {
468 extra_headers = RLZTracker::GetAccessPointHttpHeader(
469 RLZTracker::ChromeHomePage());
472 #endif // defined(ENABLE_RLZ) && !defined(OS_IOS)
474 GURL url = browser->profile()->GetHomePage();
476 #if defined(ENABLE_EXTENSIONS)
477 // Streamlined hosted apps should return to their launch page when the home
478 // button is pressed.
479 if (browser->is_app()) {
480 const extensions::Extension* extension =
481 extensions::ExtensionRegistry::Get(browser->profile())
483 web_app::GetExtensionIdFromApplicationName(browser->app_name()),
484 extensions::ExtensionRegistry::EVERYTHING);
488 url = extensions::AppLaunchInfo::GetLaunchWebURL(extension);
492 OpenURLParams params(
493 url, Referrer(), disposition,
494 ui::PageTransitionFromInt(
495 ui::PAGE_TRANSITION_AUTO_BOOKMARK |
496 ui::PAGE_TRANSITION_HOME_PAGE),
498 params.extra_headers = extra_headers;
499 browser->OpenURL(params);
502 void OpenCurrentURL(Browser* browser) {
503 content::RecordAction(UserMetricsAction("LoadURL"));
504 LocationBar* location_bar = browser->window()->GetLocationBar();
508 GURL url(location_bar->GetDestinationURL());
510 ui::PageTransition page_transition = location_bar->GetPageTransition();
511 ui::PageTransition page_transition_without_qualifier(
512 ui::PageTransitionStripQualifier(page_transition));
513 WindowOpenDisposition open_disposition =
514 location_bar->GetWindowOpenDisposition();
515 // A PAGE_TRANSITION_TYPED means the user has typed a URL. We do not want to
516 // open URLs with instant_controller since in some cases it disregards it
517 // and performs a search instead. For example, when using CTRL-Enter, the
518 // location_bar is aware of the URL but instant is not.
519 // Instant should also not handle PAGE_TRANSITION_RELOAD because its knowledge
520 // of the omnibox text may be stale if the user focuses in the omnibox and
521 // presses enter without typing anything.
522 if (page_transition_without_qualifier != ui::PAGE_TRANSITION_TYPED &&
523 page_transition_without_qualifier != ui::PAGE_TRANSITION_RELOAD &&
524 browser->instant_controller() &&
525 browser->instant_controller()->OpenInstant(open_disposition, url))
528 NavigateParams params(browser, url, page_transition);
529 params.disposition = open_disposition;
530 // Use ADD_INHERIT_OPENER so that all pages opened by the omnibox at least
531 // inherit the opener. In some cases the tabstrip will determine the group
532 // should be inherited, in which case the group is inherited instead of the
534 params.tabstrip_add_types =
535 TabStripModel::ADD_FORCE_INDEX | TabStripModel::ADD_INHERIT_OPENER;
538 #if defined(ENABLE_EXTENSIONS)
539 DCHECK(extensions::ExtensionSystem::Get(
540 browser->profile())->extension_service());
541 const extensions::Extension* extension =
542 extensions::ExtensionRegistry::Get(browser->profile())
543 ->enabled_extensions().GetAppByURL(url);
545 CoreAppLauncherHandler::RecordAppLaunchType(
546 extension_misc::APP_LAUNCH_OMNIBOX_LOCATION,
547 extension->GetType());
552 void Stop(Browser* browser) {
553 content::RecordAction(UserMetricsAction("Stop"));
554 browser->tab_strip_model()->GetActiveWebContents()->Stop();
557 void NewWindow(Browser* browser) {
558 NewEmptyWindow(browser->profile()->GetOriginalProfile(),
559 browser->host_desktop_type());
562 void NewIncognitoWindow(Browser* browser) {
563 NewEmptyWindow(browser->profile()->GetOffTheRecordProfile(),
564 browser->host_desktop_type());
567 void CloseWindow(Browser* browser) {
568 content::RecordAction(UserMetricsAction("CloseWindow"));
569 browser->window()->Close();
572 void NewTab(Browser* browser) {
573 content::RecordAction(UserMetricsAction("NewTab"));
574 // TODO(asvitkine): This is invoked programmatically from several places.
575 // Audit the code and change it so that the histogram only gets collected for
576 // user-initiated commands.
577 UMA_HISTOGRAM_ENUMERATION("Tab.NewTab", TabStripModel::NEW_TAB_COMMAND,
578 TabStripModel::NEW_TAB_ENUM_COUNT);
580 if (browser->is_type_tabbed()) {
581 AddTabAt(browser, GURL(), -1, true);
582 browser->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
584 ScopedTabbedBrowserDisplayer displayer(browser->profile(),
585 browser->host_desktop_type());
586 Browser* b = displayer.browser();
587 AddTabAt(b, GURL(), -1, true);
589 // The call to AddBlankTabAt above did not set the focus to the tab as its
590 // window was not active, so we have to do it explicitly.
591 // See http://crbug.com/6380.
592 b->tab_strip_model()->GetActiveWebContents()->RestoreFocus();
596 void CloseTab(Browser* browser) {
597 content::RecordAction(UserMetricsAction("CloseTab_Accelerator"));
598 browser->tab_strip_model()->CloseSelectedTabs();
601 bool CanZoomIn(content::WebContents* contents) {
602 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
603 return zoom_controller->GetZoomPercent() !=
604 contents->GetMaximumZoomPercent() + 1;
607 bool CanZoomOut(content::WebContents* contents) {
608 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
609 return zoom_controller->GetZoomPercent() !=
610 contents->GetMinimumZoomPercent();
613 bool ActualSize(content::WebContents* contents) {
614 ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
615 return zoom_controller->GetZoomPercent() != 100.0f;
618 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
619 const Browser* browser) {
620 TabRestoreService* service =
621 TabRestoreServiceFactory::GetForProfile(browser->profile());
622 if (!service || service->entries().empty())
623 return TabStripModelDelegate::RESTORE_NONE;
624 if (service->entries().front()->type == TabRestoreService::WINDOW)
625 return TabStripModelDelegate::RESTORE_WINDOW;
626 return TabStripModelDelegate::RESTORE_TAB;
629 void SelectNextTab(Browser* browser) {
630 content::RecordAction(UserMetricsAction("SelectNextTab"));
631 browser->tab_strip_model()->SelectNextTab();
634 void SelectPreviousTab(Browser* browser) {
635 content::RecordAction(UserMetricsAction("SelectPrevTab"));
636 browser->tab_strip_model()->SelectPreviousTab();
639 void MoveTabNext(Browser* browser) {
640 content::RecordAction(UserMetricsAction("MoveTabNext"));
641 browser->tab_strip_model()->MoveTabNext();
644 void MoveTabPrevious(Browser* browser) {
645 content::RecordAction(UserMetricsAction("MoveTabPrevious"));
646 browser->tab_strip_model()->MoveTabPrevious();
649 void SelectNumberedTab(Browser* browser, int index) {
650 if (index < browser->tab_strip_model()->count()) {
651 content::RecordAction(UserMetricsAction("SelectNumberedTab"));
652 browser->tab_strip_model()->ActivateTabAt(index, true);
656 void SelectLastTab(Browser* browser) {
657 content::RecordAction(UserMetricsAction("SelectLastTab"));
658 browser->tab_strip_model()->SelectLastTab();
661 void DuplicateTab(Browser* browser) {
662 content::RecordAction(UserMetricsAction("Duplicate"));
663 DuplicateTabAt(browser, browser->tab_strip_model()->active_index());
666 bool CanDuplicateTab(const Browser* browser) {
667 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
668 return contents && contents->GetController().GetLastCommittedEntry();
671 WebContents* DuplicateTabAt(Browser* browser, int index) {
672 WebContents* contents = browser->tab_strip_model()->GetWebContentsAt(index);
674 WebContents* contents_dupe = contents->Clone();
677 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
678 // If this is a tabbed browser, just create a duplicate tab inside the same
679 // window next to the tab being duplicated.
680 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
681 pinned = browser->tab_strip_model()->IsTabPinned(index);
682 int add_types = TabStripModel::ADD_ACTIVE |
683 TabStripModel::ADD_INHERIT_GROUP |
684 (pinned ? TabStripModel::ADD_PINNED : 0);
685 browser->tab_strip_model()->InsertWebContentsAt(
686 index + 1, contents_dupe, add_types);
688 Browser* new_browser = NULL;
689 if (browser->is_app() && !browser->is_type_popup()) {
690 new_browser = new Browser(
691 Browser::CreateParams::CreateForApp(browser->app_name(),
692 browser->is_trusted_source(),
695 browser->host_desktop_type()));
697 new_browser = new Browser(
698 Browser::CreateParams(browser->type(), browser->profile(),
699 browser->host_desktop_type()));
701 // Preserve the size of the original window. The new window has already
702 // been given an offset by the OS, so we shouldn't copy the old bounds.
703 BrowserWindow* new_window = new_browser->window();
704 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
705 browser->window()->GetRestoredBounds().size()));
707 // We need to show the browser now. Otherwise ContainerWin assumes the
708 // WebContents is invisible and won't size it.
709 new_browser->window()->Show();
711 // The page transition below is only for the purpose of inserting the tab.
712 new_browser->tab_strip_model()->AddWebContents(
714 ui::PAGE_TRANSITION_LINK,
715 TabStripModel::ADD_ACTIVE);
718 SessionService* session_service =
719 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
721 session_service->TabRestored(contents_dupe, pinned);
722 return contents_dupe;
725 bool CanDuplicateTabAt(Browser* browser, int index) {
726 content::NavigationController& nc =
727 browser->tab_strip_model()->GetWebContentsAt(index)->GetController();
728 return nc.GetWebContents() && nc.GetLastCommittedEntry();
731 void ConvertPopupToTabbedBrowser(Browser* browser) {
732 content::RecordAction(UserMetricsAction("ShowAsTab"));
733 TabStripModel* tab_strip = browser->tab_strip_model();
734 WebContents* contents =
735 tab_strip->DetachWebContentsAt(tab_strip->active_index());
736 Browser* b = new Browser(Browser::CreateParams(browser->profile(),
737 browser->host_desktop_type()));
738 b->tab_strip_model()->AppendWebContents(contents, true);
743 content::RecordAction(UserMetricsAction("Exit"));
744 chrome::AttemptUserExit();
747 void BookmarkCurrentPage(Browser* browser) {
748 DCHECK(!chrome::ShouldRemoveBookmarkThisPageUI(browser->profile()));
750 #if defined(ENABLE_EXTENSIONS)
751 const extensions::Extension* extension = NULL;
752 extensions::Command command;
753 extensions::CommandService::ExtensionCommandType command_type;
754 if (GetBookmarkOverrideCommand(browser->profile(),
758 switch (command_type) {
759 case extensions::CommandService::NAMED:
760 browser->window()->ExecuteExtensionCommand(extension, command);
762 case extensions::CommandService::BROWSER_ACTION:
763 case extensions::CommandService::PAGE_ACTION:
764 // BookmarkCurrentPage is called through a user gesture, so it is safe
765 // to grant the active tab permission.
766 extensions::ExtensionActionAPI::Get(browser->profile())->
767 ShowExtensionActionPopup(extension, browser, true);
774 BookmarkCurrentPageInternal(browser);
777 bool CanBookmarkCurrentPage(const Browser* browser) {
778 return CanBookmarkCurrentPageInternal(browser, true);
781 void BookmarkAllTabs(Browser* browser) {
782 chrome::ShowBookmarkAllTabsDialog(browser);
785 bool CanBookmarkAllTabs(const Browser* browser) {
786 return browser->tab_strip_model()->count() > 1 &&
787 !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) &&
788 CanBookmarkCurrentPageInternal(browser, false);
791 void Translate(Browser* browser) {
792 if (!browser->window()->IsActive())
795 WebContents* web_contents =
796 browser->tab_strip_model()->GetActiveWebContents();
797 ChromeTranslateClient* chrome_translate_client =
798 ChromeTranslateClient::FromWebContents(web_contents);
800 translate::TranslateStep step = translate::TRANSLATE_STEP_BEFORE_TRANSLATE;
801 if (chrome_translate_client) {
802 if (chrome_translate_client->GetLanguageState().translation_pending())
803 step = translate::TRANSLATE_STEP_TRANSLATING;
804 else if (chrome_translate_client->GetLanguageState().IsPageTranslated())
805 step = translate::TRANSLATE_STEP_AFTER_TRANSLATE;
807 browser->window()->ShowTranslateBubble(
808 web_contents, step, translate::TranslateErrors::NONE, true);
811 void ManagePasswordsForPage(Browser* browser) {
812 if (!browser->window()->IsActive())
815 WebContents* web_contents =
816 browser->tab_strip_model()->GetActiveWebContents();
817 chrome::ShowManagePasswordsBubble(web_contents);
821 void TogglePagePinnedToStartScreen(Browser* browser) {
822 MetroPinTabHelper::FromWebContents(
823 browser->tab_strip_model()->GetActiveWebContents())->
824 TogglePinnedToStartScreen();
828 void SavePage(Browser* browser) {
829 content::RecordAction(UserMetricsAction("SavePage"));
830 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
831 if (current_tab && current_tab->GetContentsMimeType() == "application/pdf")
832 content::RecordAction(UserMetricsAction("PDF.SavePage"));
833 current_tab->OnSavePage();
836 bool CanSavePage(const Browser* browser) {
837 // LocalState can be NULL in tests.
838 if (g_browser_process->local_state() &&
839 !g_browser_process->local_state()->GetBoolean(
840 prefs::kAllowFileSelectionDialogs)) {
843 return !browser->is_devtools() &&
844 !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE);
847 void ShowFindBar(Browser* browser) {
848 browser->GetFindBarController()->Show();
851 void ShowWebsiteSettings(Browser* browser,
852 content::WebContents* web_contents,
854 const SSLStatus& ssl) {
855 browser->window()->ShowWebsiteSettings(
856 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
857 web_contents, url, ssl);
860 void Print(Browser* browser) {
861 #if defined(ENABLE_PRINTING)
862 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
864 #if defined(ENABLE_PRINT_PREVIEW)
865 printing::PrintViewManager* print_view_manager =
866 printing::PrintViewManager::FromWebContents(contents);
867 if (!browser->profile()->GetPrefs()->GetBoolean(
868 prefs::kPrintPreviewDisabled)) {
869 print_view_manager->PrintPreviewNow(false);
872 #else // ENABLE_PRINT_PREVIEW
873 printing::PrintViewManagerBasic* print_view_manager =
874 printing::PrintViewManagerBasic::FromWebContents(contents);
875 #endif // ENABLE_PRINT_PREVIEW
877 #if defined(ENABLE_BASIC_PRINTING)
878 print_view_manager->PrintNow();
879 #endif // ENABLE_BASIC_PRINTING
881 #endif // defined(ENABLE_PRINTING)
884 bool CanPrint(Browser* browser) {
885 // Do not print when printing is disabled via pref or policy.
886 // Do not print when a constrained window is showing. It's confusing.
887 // TODO(gbillock): Need to re-assess the call to
888 // IsShowingWebContentsModalDialog after a popup management policy is
889 // refined -- we will probably want to just queue the print request, not
891 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
892 !(IsShowingWebContentsModalDialog(browser) ||
893 GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT);
896 #if defined(ENABLE_BASIC_PRINTING)
897 void BasicPrint(Browser* browser) {
898 #if defined(ENABLE_PRINT_PREVIEW)
899 printing::PrintViewManager* print_view_manager =
900 printing::PrintViewManager::FromWebContents(
901 browser->tab_strip_model()->GetActiveWebContents());
902 print_view_manager->BasicPrint();
906 bool CanBasicPrint(Browser* browser) {
907 // If printing is not disabled via pref or policy, it is always possible to
908 // advanced print when the print preview is visible. The exception to this
909 // is under Win8 ash, since showing the advanced print dialog will open it
910 // modally on the Desktop and hang the browser.
912 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH)
916 return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) &&
917 (PrintPreviewShowing(browser) || CanPrint(browser));
919 #endif // ENABLE_BASIC_PRINTING
921 void EmailPageLocation(Browser* browser) {
922 content::RecordAction(UserMetricsAction("EmailPageLocation"));
923 WebContents* wc = browser->tab_strip_model()->GetActiveWebContents();
926 std::string title = net::EscapeQueryParamValue(
927 base::UTF16ToUTF8(wc->GetTitle()), false);
928 std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false);
929 std::string mailto = std::string("mailto:?subject=Fwd:%20") +
930 title + "&body=%0A%0A" + page_url;
931 platform_util::OpenExternal(browser->profile(), GURL(mailto));
934 bool CanEmailPageLocation(const Browser* browser) {
935 return browser->toolbar_model()->ShouldDisplayURL() &&
936 browser->tab_strip_model()->GetActiveWebContents()->GetURL().is_valid();
939 void Cut(Browser* browser) {
940 content::RecordAction(UserMetricsAction("Cut"));
941 browser->window()->Cut();
944 void Copy(Browser* browser) {
945 content::RecordAction(UserMetricsAction("Copy"));
946 browser->window()->Copy();
949 void Paste(Browser* browser) {
950 content::RecordAction(UserMetricsAction("Paste"));
951 browser->window()->Paste();
954 void Find(Browser* browser) {
955 content::RecordAction(UserMetricsAction("Find"));
956 FindInPage(browser, false, false);
959 void FindNext(Browser* browser) {
960 content::RecordAction(UserMetricsAction("FindNext"));
961 FindInPage(browser, true, true);
964 void FindPrevious(Browser* browser) {
965 content::RecordAction(UserMetricsAction("FindPrevious"));
966 FindInPage(browser, true, false);
969 void FindInPage(Browser* browser, bool find_next, bool forward_direction) {
970 ShowFindBar(browser);
972 base::string16 find_text;
973 FindTabHelper* find_helper = FindTabHelper::FromWebContents(
974 browser->tab_strip_model()->GetActiveWebContents());
975 #if defined(OS_MACOSX)
976 // We always want to search for the current contents of the find bar on
977 // OS X. For regular profile it's always the current find pboard. For
978 // Incognito window it's the newest value of the find pboard content and
980 FindBar* find_bar = browser->GetFindBarController()->find_bar();
981 find_text = find_bar->GetFindText();
983 find_helper->StartFinding(find_text, forward_direction, false);
987 void Zoom(Browser* browser, content::PageZoom zoom) {
988 chrome_page_zoom::Zoom(browser->tab_strip_model()->GetActiveWebContents(),
992 void FocusToolbar(Browser* browser) {
993 content::RecordAction(UserMetricsAction("FocusToolbar"));
994 browser->window()->FocusToolbar();
997 void FocusLocationBar(Browser* browser) {
998 content::RecordAction(UserMetricsAction("FocusLocation"));
999 browser->window()->SetFocusToLocationBar(true);
1002 void FocusSearch(Browser* browser) {
1003 // TODO(beng): replace this with FocusLocationBar
1004 content::RecordAction(UserMetricsAction("FocusSearch"));
1005 browser->window()->GetLocationBar()->FocusSearch();
1008 void FocusAppMenu(Browser* browser) {
1009 content::RecordAction(UserMetricsAction("FocusAppMenu"));
1010 browser->window()->FocusAppMenu();
1013 void FocusBookmarksToolbar(Browser* browser) {
1014 content::RecordAction(UserMetricsAction("FocusBookmarksToolbar"));
1015 browser->window()->FocusBookmarksToolbar();
1018 void FocusInfobars(Browser* browser) {
1019 content::RecordAction(UserMetricsAction("FocusInfobars"));
1020 browser->window()->FocusInfobars();
1023 void FocusNextPane(Browser* browser) {
1024 content::RecordAction(UserMetricsAction("FocusNextPane"));
1025 browser->window()->RotatePaneFocus(true);
1028 void FocusPreviousPane(Browser* browser) {
1029 content::RecordAction(UserMetricsAction("FocusPreviousPane"));
1030 browser->window()->RotatePaneFocus(false);
1033 void ToggleDevToolsWindow(Browser* browser, DevToolsToggleAction action) {
1034 if (action.type() == DevToolsToggleAction::kShowConsole)
1035 content::RecordAction(UserMetricsAction("DevTools_ToggleConsole"));
1037 content::RecordAction(UserMetricsAction("DevTools_ToggleWindow"));
1038 DevToolsWindow::ToggleDevToolsWindow(browser, action);
1041 bool CanOpenTaskManager() {
1042 #if defined(ENABLE_TASK_MANAGER)
1049 void OpenTaskManager(Browser* browser) {
1050 #if defined(ENABLE_TASK_MANAGER)
1051 content::RecordAction(UserMetricsAction("TaskManager"));
1052 chrome::ShowTaskManager(browser);
1058 void OpenFeedbackDialog(Browser* browser) {
1059 content::RecordAction(UserMetricsAction("Feedback"));
1060 chrome::ShowFeedbackPage(browser, std::string(), std::string());
1063 void ToggleBookmarkBar(Browser* browser) {
1064 content::RecordAction(UserMetricsAction("ShowBookmarksBar"));
1065 ToggleBookmarkBarWhenVisible(browser->profile());
1068 void ShowAppMenu(Browser* browser) {
1069 // We record the user metric for this event in WrenchMenu::RunMenu.
1070 browser->window()->ShowAppMenu();
1073 void ShowAvatarMenu(Browser* browser) {
1074 browser->window()->ShowAvatarBubbleFromAvatarButton(
1075 BrowserWindow::AVATAR_BUBBLE_MODE_DEFAULT,
1076 signin::ManageAccountsParams());
1079 void OpenUpdateChromeDialog(Browser* browser) {
1080 if (UpgradeDetector::GetInstance()->is_outdated_install()) {
1081 content::NotificationService::current()->Notify(
1082 chrome::NOTIFICATION_OUTDATED_INSTALL,
1083 content::NotificationService::AllSources(),
1084 content::NotificationService::NoDetails());
1085 } else if (UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
1086 content::NotificationService::current()->Notify(
1087 chrome::NOTIFICATION_OUTDATED_INSTALL_NO_AU,
1088 content::NotificationService::AllSources(),
1089 content::NotificationService::NoDetails());
1091 content::RecordAction(UserMetricsAction("UpdateChrome"));
1092 browser->window()->ShowUpdateChromeDialog();
1096 void ToggleSpeechInput(Browser* browser) {
1097 SearchTabHelper* search_tab_helper =
1098 SearchTabHelper::FromWebContents(
1099 browser->tab_strip_model()->GetActiveWebContents());
1100 // |search_tab_helper| can be null in unit tests.
1101 if (search_tab_helper)
1102 search_tab_helper->ToggleVoiceSearch();
1105 void DistillCurrentPage(Browser* browser) {
1106 DistillCurrentPageAndView(browser->tab_strip_model()->GetActiveWebContents());
1109 bool CanRequestTabletSite(WebContents* current_tab) {
1110 return current_tab &&
1111 current_tab->GetController().GetLastCommittedEntry() != NULL;
1114 bool IsRequestingTabletSite(Browser* browser) {
1115 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1118 content::NavigationEntry* entry =
1119 current_tab->GetController().GetLastCommittedEntry();
1122 return entry->GetIsOverridingUserAgent();
1125 void ToggleRequestTabletSite(Browser* browser) {
1126 WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents();
1129 NavigationController& controller = current_tab->GetController();
1130 NavigationEntry* entry = controller.GetLastCommittedEntry();
1133 if (entry->GetIsOverridingUserAgent()) {
1134 entry->SetIsOverridingUserAgent(false);
1136 entry->SetIsOverridingUserAgent(true);
1137 chrome::VersionInfo version_info;
1138 std::string product = version_info.ProductNameAndVersionForUserAgent();
1139 current_tab->SetUserAgentOverride(content::BuildUserAgentFromOSAndProduct(
1140 kOsOverrideForTabletSite, product));
1142 controller.ReloadOriginalRequestURL(true);
1145 void ToggleFullscreenMode(Browser* browser) {
1147 browser->fullscreen_controller()->ToggleBrowserFullscreenMode();
1150 void ClearCache(Browser* browser) {
1151 BrowsingDataRemover* remover =
1152 BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
1153 remover->Remove(BrowsingDataRemover::REMOVE_CACHE,
1154 BrowsingDataHelper::UNPROTECTED_WEB);
1155 // BrowsingDataRemover takes care of deleting itself when done.
1158 bool IsDebuggerAttachedToCurrentTab(Browser* browser) {
1159 WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
1161 content::DevToolsAgentHost::IsDebuggerAttached(contents) : false;
1164 void ViewSource(Browser* browser, WebContents* contents) {
1167 // Use the last committed entry, since the pending entry hasn't loaded yet and
1168 // won't be copied into the cloned tab.
1169 NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
1173 ViewSource(browser, contents, entry->GetURL(), entry->GetPageState());
1176 void ViewSource(Browser* browser,
1177 WebContents* contents,
1179 const content::PageState& page_state) {
1180 content::RecordAction(UserMetricsAction("ViewSource"));
1183 WebContents* view_source_contents = contents->Clone();
1184 DCHECK(view_source_contents->GetController().CanPruneAllButLastCommitted());
1185 view_source_contents->GetController().PruneAllButLastCommitted();
1186 NavigationEntry* last_committed_entry =
1187 view_source_contents->GetController().GetLastCommittedEntry();
1188 if (!last_committed_entry)
1191 GURL view_source_url =
1192 GURL(content::kViewSourceScheme + std::string(":") + url.spec());
1193 last_committed_entry->SetVirtualURL(view_source_url);
1195 // Do not restore scroller position.
1196 last_committed_entry->SetPageState(page_state.RemoveScrollOffset());
1198 // Do not restore title, derive it from the url.
1199 last_committed_entry->SetTitle(base::string16());
1201 // Now show view-source entry.
1202 if (browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
1203 // If this is a tabbed browser, just create a duplicate tab inside the same
1204 // window next to the tab being duplicated.
1205 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1206 int add_types = TabStripModel::ADD_ACTIVE |
1207 TabStripModel::ADD_INHERIT_GROUP;
1208 browser->tab_strip_model()->InsertWebContentsAt(
1210 view_source_contents,
1213 Browser* b = new Browser(
1214 Browser::CreateParams(Browser::TYPE_TABBED, browser->profile(),
1215 browser->host_desktop_type()));
1217 // Preserve the size of the original window. The new window has already
1218 // been given an offset by the OS, so we shouldn't copy the old bounds.
1219 BrowserWindow* new_window = b->window();
1220 new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(),
1221 browser->window()->GetRestoredBounds().size()));
1223 // We need to show the browser now. Otherwise ContainerWin assumes the
1224 // WebContents is invisible and won't size it.
1225 b->window()->Show();
1227 // The page transition below is only for the purpose of inserting the tab.
1228 b->tab_strip_model()->AddWebContents(view_source_contents, -1,
1229 ui::PAGE_TRANSITION_LINK,
1230 TabStripModel::ADD_ACTIVE);
1233 SessionService* session_service =
1234 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
1235 if (session_service)
1236 session_service->TabRestored(view_source_contents, false);
1239 void ViewSelectedSource(Browser* browser) {
1240 ViewSource(browser, browser->tab_strip_model()->GetActiveWebContents());
1243 bool CanViewSource(const Browser* browser) {
1244 return !browser->is_devtools() &&
1245 browser->tab_strip_model()->GetActiveWebContents()->GetController().
1249 #if defined(ENABLE_EXTENSIONS)
1250 void CreateApplicationShortcuts(Browser* browser) {
1251 content::RecordAction(UserMetricsAction("CreateShortcut"));
1252 extensions::TabHelper::FromWebContents(
1253 browser->tab_strip_model()->GetActiveWebContents())->
1254 CreateApplicationShortcuts();
1257 void CreateBookmarkAppFromCurrentWebContents(Browser* browser) {
1258 content::RecordAction(UserMetricsAction("CreateHostedApp"));
1259 extensions::TabHelper::FromWebContents(
1260 browser->tab_strip_model()->GetActiveWebContents())->
1261 CreateHostedAppFromWebContents();
1264 bool CanCreateApplicationShortcuts(const Browser* browser) {
1265 return extensions::TabHelper::FromWebContents(
1266 browser->tab_strip_model()->GetActiveWebContents())->
1267 CanCreateApplicationShortcuts();
1270 bool CanCreateBookmarkApp(const Browser* browser) {
1271 return extensions::TabHelper::FromWebContents(
1272 browser->tab_strip_model()->GetActiveWebContents())
1273 ->CanCreateBookmarkApp();
1276 void ConvertTabToAppWindow(Browser* browser,
1277 content::WebContents* contents) {
1278 const GURL& url = contents->GetController().GetLastCommittedEntry()->GetURL();
1279 std::string app_name = web_app::GenerateApplicationNameFromURL(url);
1281 int index = browser->tab_strip_model()->GetIndexOfWebContents(contents);
1283 browser->tab_strip_model()->DetachWebContentsAt(index);
1285 Browser* app_browser = new Browser(
1286 Browser::CreateParams::CreateForApp(app_name,
1287 true /* trusted_source */,
1290 browser->host_desktop_type()));
1291 app_browser->tab_strip_model()->AppendWebContents(contents, true);
1293 contents->GetMutableRendererPrefs()->can_accept_load_drops = false;
1294 contents->GetRenderViewHost()->SyncRendererPrefs();
1295 app_browser->window()->Show();
1297 #endif // defined(ENABLE_EXTENSIONS)
1299 } // namespace chrome