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