Home | History | Annotate | Download | only in prerender
      1 // Copyright (c) 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 <deque>
      6 #include <vector>
      7 
      8 #include "base/bind.h"
      9 #include "base/command_line.h"
     10 #include "base/files/file_path.h"
     11 #include "base/memory/ref_counted_memory.h"
     12 #include "base/memory/scoped_vector.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/path_service.h"
     15 #include "base/prefs/pref_service.h"
     16 #include "base/run_loop.h"
     17 #include "base/strings/string_util.h"
     18 #include "base/strings/stringprintf.h"
     19 #include "base/strings/utf_string_conversions.h"
     20 #include "base/test/test_timeouts.h"
     21 #include "base/values.h"
     22 #include "chrome/browser/browsing_data/browsing_data_helper.h"
     23 #include "chrome/browser/browsing_data/browsing_data_remover.h"
     24 #include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
     25 #include "chrome/browser/chrome_content_browser_client.h"
     26 #include "chrome/browser/chrome_notification_types.h"
     27 #include "chrome/browser/content_settings/host_content_settings_map.h"
     28 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
     29 #include "chrome/browser/extensions/extension_apitest.h"
     30 #include "chrome/browser/external_protocol/external_protocol_handler.h"
     31 #include "chrome/browser/favicon/favicon_tab_helper.h"
     32 #include "chrome/browser/predictors/autocomplete_action_predictor.h"
     33 #include "chrome/browser/predictors/autocomplete_action_predictor_factory.h"
     34 #include "chrome/browser/prerender/prerender_contents.h"
     35 #include "chrome/browser/prerender/prerender_handle.h"
     36 #include "chrome/browser/prerender/prerender_link_manager.h"
     37 #include "chrome/browser/prerender/prerender_link_manager_factory.h"
     38 #include "chrome/browser/prerender/prerender_manager.h"
     39 #include "chrome/browser/prerender/prerender_manager_factory.h"
     40 #include "chrome/browser/profiles/profile.h"
     41 #include "chrome/browser/profiles/profile_io_data.h"
     42 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
     43 #include "chrome/browser/safe_browsing/database_manager.h"
     44 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
     45 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
     46 #include "chrome/browser/task_manager/task_manager.h"
     47 #include "chrome/browser/task_manager/task_manager_browsertest_util.h"
     48 #include "chrome/browser/ui/browser.h"
     49 #include "chrome/browser/ui/browser_commands.h"
     50 #include "chrome/browser/ui/browser_finder.h"
     51 #include "chrome/browser/ui/browser_navigator.h"
     52 #include "chrome/browser/ui/browser_window.h"
     53 #include "chrome/browser/ui/omnibox/location_bar.h"
     54 #include "chrome/browser/ui/omnibox/omnibox_edit_model.h"
     55 #include "chrome/browser/ui/omnibox/omnibox_popup_model.h"
     56 #include "chrome/browser/ui/omnibox/omnibox_view.h"
     57 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     58 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
     59 #include "chrome/common/chrome_paths.h"
     60 #include "chrome/common/chrome_switches.h"
     61 #include "chrome/common/extensions/extension_constants.h"
     62 #include "chrome/common/extensions/manifest_handlers/mime_types_handler.h"
     63 #include "chrome/common/pref_names.h"
     64 #include "chrome/test/base/in_process_browser_test.h"
     65 #include "chrome/test/base/test_switches.h"
     66 #include "chrome/test/base/ui_test_utils.h"
     67 #include "chrome/test/base/uma_histogram_helper.h"
     68 #include "content/public/browser/browser_message_filter.h"
     69 #include "content/public/browser/devtools_agent_host.h"
     70 #include "content/public/browser/devtools_client_host.h"
     71 #include "content/public/browser/devtools_manager.h"
     72 #include "content/public/browser/navigation_controller.h"
     73 #include "content/public/browser/navigation_entry.h"
     74 #include "content/public/browser/notification_service.h"
     75 #include "content/public/browser/render_frame_host.h"
     76 #include "content/public/browser/render_process_host.h"
     77 #include "content/public/browser/render_view_host.h"
     78 #include "content/public/browser/site_instance.h"
     79 #include "content/public/browser/web_contents.h"
     80 #include "content/public/browser/web_contents_observer.h"
     81 #include "content/public/common/url_constants.h"
     82 #include "content/public/test/browser_test_utils.h"
     83 #include "content/public/test/test_navigation_observer.h"
     84 #include "content/public/test/test_utils.h"
     85 #include "content/test/net/url_request_mock_http_job.h"
     86 #include "extensions/common/switches.h"
     87 #include "grit/generated_resources.h"
     88 #include "net/base/escape.h"
     89 #include "net/cert/x509_certificate.h"
     90 #include "net/dns/mock_host_resolver.h"
     91 #include "net/ssl/client_cert_store.h"
     92 #include "net/ssl/ssl_cert_request_info.h"
     93 #include "net/url_request/url_request_context.h"
     94 #include "net/url_request/url_request_context_getter.h"
     95 #include "net/url_request/url_request_filter.h"
     96 #include "net/url_request/url_request_interceptor.h"
     97 #include "net/url_request/url_request_job.h"
     98 #include "ui/base/l10n/l10n_util.h"
     99 #include "url/gurl.h"
    100 
    101 using content::BrowserThread;
    102 using content::DevToolsAgentHost;
    103 using content::DevToolsClientHost;
    104 using content::DevToolsManager;
    105 using content::NavigationController;
    106 using content::OpenURLParams;
    107 using content::Referrer;
    108 using content::RenderFrameHost;
    109 using content::RenderViewHost;
    110 using content::RenderWidgetHost;
    111 using content::TestNavigationObserver;
    112 using content::WebContents;
    113 using content::WebContentsObserver;
    114 using task_manager::browsertest_util::WaitForTaskManagerRows;
    115 
    116 // Prerender tests work as follows:
    117 //
    118 // A page with a prefetch link to the test page is loaded.  Once prerendered,
    119 // its Javascript function DidPrerenderPass() is called, which returns true if
    120 // the page behaves as expected when prerendered.
    121 //
    122 // The prerendered page is then displayed on a tab.  The Javascript function
    123 // DidDisplayPass() is called, and returns true if the page behaved as it
    124 // should while being displayed.
    125 
    126 namespace prerender {
    127 
    128 namespace {
    129 
    130 // Constants used in the test HTML files.
    131 const char* kReadyTitle = "READY";
    132 const char* kPassTitle = "PASS";
    133 
    134 std::string CreateClientRedirect(const std::string& dest_url) {
    135   const char* const kClientRedirectBase = "client-redirect?";
    136   return kClientRedirectBase + net::EscapeQueryParamValue(dest_url, false);
    137 }
    138 
    139 std::string CreateServerRedirect(const std::string& dest_url) {
    140   const char* const kServerRedirectBase = "server-redirect?";
    141   return kServerRedirectBase + net::EscapeQueryParamValue(dest_url, false);
    142 }
    143 
    144 // Clears the specified data using BrowsingDataRemover.
    145 void ClearBrowsingData(Browser* browser, int remove_mask) {
    146   BrowsingDataRemover* remover =
    147       BrowsingDataRemover::CreateForUnboundedRange(browser->profile());
    148   BrowsingDataRemoverCompletionObserver observer(remover);
    149   remover->Remove(remove_mask, BrowsingDataHelper::UNPROTECTED_WEB);
    150   observer.BlockUntilCompletion();
    151   // BrowsingDataRemover deletes itself.
    152 }
    153 
    154 // Returns true if the prerender is expected to abort on its own, before
    155 // attempting to swap it.
    156 bool ShouldAbortPrerenderBeforeSwap(FinalStatus status) {
    157   switch (status) {
    158     case FINAL_STATUS_USED:
    159     case FINAL_STATUS_WINDOW_OPENER:
    160     case FINAL_STATUS_APP_TERMINATING:
    161     case FINAL_STATUS_PROFILE_DESTROYED:
    162     case FINAL_STATUS_CACHE_OR_HISTORY_CLEARED:
    163     // We'll crash the renderer after it's loaded.
    164     case FINAL_STATUS_RENDERER_CRASHED:
    165     case FINAL_STATUS_CANCELLED:
    166     case FINAL_STATUS_DEVTOOLS_ATTACHED:
    167     case FINAL_STATUS_PAGE_BEING_CAPTURED:
    168     case FINAL_STATUS_NAVIGATION_UNCOMMITTED:
    169     case FINAL_STATUS_WOULD_HAVE_BEEN_USED:
    170     case FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE:
    171       return false;
    172     default:
    173       return true;
    174   }
    175 }
    176 
    177 // Convenience function to wait for a title. Handles the case when the
    178 // WebContents already has the expected title.
    179 void WaitForASCIITitle(WebContents* web_contents,
    180                        const char* expected_title_ascii) {
    181   base::string16 expected_title = base::ASCIIToUTF16(expected_title_ascii);
    182   if (web_contents->GetTitle() == expected_title)
    183     return;
    184   content::TitleWatcher title_watcher(web_contents, expected_title);
    185   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
    186 }
    187 
    188 // Waits for the destruction of a RenderProcessHost's IPC channel.
    189 // Used to make sure the PrerenderLinkManager's OnChannelClosed function has
    190 // been called, before checking its state.
    191 class ChannelDestructionWatcher {
    192  public:
    193   ChannelDestructionWatcher() : channel_destroyed_(false) {
    194   }
    195 
    196   ~ChannelDestructionWatcher() {
    197   }
    198 
    199   void WatchChannel(content::RenderProcessHost* host) {
    200     host->AddFilter(new DestructionMessageFilter(this));
    201   }
    202 
    203   void WaitForChannelClose() {
    204     run_loop_.Run();
    205     EXPECT_TRUE(channel_destroyed_);
    206   }
    207 
    208  private:
    209   // When destroyed, calls ChannelDestructionWatcher::OnChannelDestroyed.
    210   // Ignores all messages.
    211   class DestructionMessageFilter : public content::BrowserMessageFilter {
    212    public:
    213      explicit DestructionMessageFilter(ChannelDestructionWatcher* watcher)
    214          : BrowserMessageFilter(0),
    215            watcher_(watcher) {
    216     }
    217 
    218    private:
    219     virtual ~DestructionMessageFilter() {
    220       content::BrowserThread::PostTask(
    221           content::BrowserThread::UI, FROM_HERE,
    222           base::Bind(&ChannelDestructionWatcher::OnChannelDestroyed,
    223                      base::Unretained(watcher_)));
    224     }
    225 
    226     virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
    227       return false;
    228     }
    229 
    230     ChannelDestructionWatcher* watcher_;
    231 
    232     DISALLOW_COPY_AND_ASSIGN(DestructionMessageFilter);
    233   };
    234 
    235   void OnChannelDestroyed() {
    236     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    237 
    238     EXPECT_FALSE(channel_destroyed_);
    239     channel_destroyed_ = true;
    240     run_loop_.Quit();
    241   }
    242 
    243   bool channel_destroyed_;
    244   base::RunLoop run_loop_;
    245 
    246   DISALLOW_COPY_AND_ASSIGN(ChannelDestructionWatcher);
    247 };
    248 
    249 // A navigation observer to wait on either a new load or a swap of a
    250 // WebContents. On swap, if the new WebContents is still loading, wait for that
    251 // load to complete as well. Note that the load must begin after the observer is
    252 // attached.
    253 class NavigationOrSwapObserver : public WebContentsObserver,
    254                                  public TabStripModelObserver {
    255  public:
    256   // Waits for either a new load or a swap of |tab_strip_model|'s active
    257   // WebContents.
    258   NavigationOrSwapObserver(TabStripModel* tab_strip_model,
    259                            WebContents* web_contents)
    260       : WebContentsObserver(web_contents),
    261         tab_strip_model_(tab_strip_model),
    262         did_start_loading_(false),
    263         number_of_loads_(1) {
    264     CHECK_NE(TabStripModel::kNoTab,
    265              tab_strip_model->GetIndexOfWebContents(web_contents));
    266     tab_strip_model_->AddObserver(this);
    267   }
    268 
    269   // Waits for either |number_of_loads| loads or a swap of |tab_strip_model|'s
    270   // active WebContents.
    271   NavigationOrSwapObserver(TabStripModel* tab_strip_model,
    272                            WebContents* web_contents,
    273                            int number_of_loads)
    274       : WebContentsObserver(web_contents),
    275         tab_strip_model_(tab_strip_model),
    276         did_start_loading_(false),
    277         number_of_loads_(number_of_loads) {
    278     CHECK_NE(TabStripModel::kNoTab,
    279              tab_strip_model->GetIndexOfWebContents(web_contents));
    280     tab_strip_model_->AddObserver(this);
    281   }
    282 
    283   virtual ~NavigationOrSwapObserver() {
    284     tab_strip_model_->RemoveObserver(this);
    285   }
    286 
    287   void set_did_start_loading() {
    288     did_start_loading_ = true;
    289   }
    290 
    291   void Wait() {
    292     loop_.Run();
    293   }
    294 
    295   // WebContentsObserver implementation:
    296   virtual void DidStartLoading(RenderViewHost* render_view_host) OVERRIDE {
    297     did_start_loading_ = true;
    298   }
    299   virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE {
    300     if (!did_start_loading_)
    301       return;
    302     number_of_loads_--;
    303     if (number_of_loads_ == 0)
    304       loop_.Quit();
    305   }
    306 
    307   // TabStripModelObserver implementation:
    308   virtual void TabReplacedAt(TabStripModel* tab_strip_model,
    309                              WebContents* old_contents,
    310                              WebContents* new_contents,
    311                              int index) OVERRIDE {
    312     if (old_contents != web_contents())
    313       return;
    314     // Switch to observing the new WebContents.
    315     Observe(new_contents);
    316     if (new_contents->IsLoading()) {
    317       // If the new WebContents is still loading, wait for it to complete. Only
    318       // one load post-swap is supported.
    319       did_start_loading_ = true;
    320       number_of_loads_ = 1;
    321     } else {
    322       loop_.Quit();
    323     }
    324   }
    325 
    326  private:
    327   TabStripModel* tab_strip_model_;
    328   bool did_start_loading_;
    329   int number_of_loads_;
    330   base::RunLoop loop_;
    331 };
    332 
    333 // Waits for a new tab to open and a navigation or swap in it.
    334 class NewTabNavigationOrSwapObserver {
    335  public:
    336   NewTabNavigationOrSwapObserver()
    337       : new_tab_observer_(
    338             chrome::NOTIFICATION_TAB_ADDED,
    339             base::Bind(&NewTabNavigationOrSwapObserver::OnTabAdded,
    340                        base::Unretained(this))) {
    341     // Watch for NOTIFICATION_TAB_ADDED. Add a callback so that the
    342     // NavigationOrSwapObserver can be attached synchronously and no events are
    343     // missed.
    344   }
    345 
    346   void Wait() {
    347     new_tab_observer_.Wait();
    348     swap_observer_->Wait();
    349   }
    350 
    351   bool OnTabAdded(const content::NotificationSource& source,
    352                   const content::NotificationDetails& details) {
    353     if (swap_observer_)
    354       return true;
    355     WebContents* new_tab = content::Details<WebContents>(details).ptr();
    356     // Get the TabStripModel. Assume this is attached to a Browser.
    357     TabStripModel* tab_strip_model =
    358         static_cast<Browser*>(new_tab->GetDelegate())->tab_strip_model();
    359     swap_observer_.reset(new NavigationOrSwapObserver(tab_strip_model,
    360                                                       new_tab));
    361     swap_observer_->set_did_start_loading();
    362     return true;
    363   }
    364 
    365  private:
    366   content::WindowedNotificationObserver new_tab_observer_;
    367   scoped_ptr<NavigationOrSwapObserver> swap_observer_;
    368 };
    369 
    370 // PrerenderContents that stops the UI message loop on DidStopLoading().
    371 class TestPrerenderContents : public PrerenderContents {
    372  public:
    373   TestPrerenderContents(
    374       PrerenderManager* prerender_manager,
    375       Profile* profile,
    376       const GURL& url,
    377       const content::Referrer& referrer,
    378       Origin origin,
    379       FinalStatus expected_final_status)
    380       : PrerenderContents(prerender_manager, profile, url,
    381                           referrer, origin, PrerenderManager::kNoExperiment),
    382         expected_final_status_(expected_final_status),
    383         new_render_view_host_(NULL),
    384         was_hidden_(false),
    385         was_shown_(false),
    386         should_be_shown_(expected_final_status == FINAL_STATUS_USED),
    387         skip_final_checks_(false) {
    388   }
    389 
    390   virtual ~TestPrerenderContents() {
    391     if (skip_final_checks_)
    392       return;
    393 
    394     if (expected_final_status_ == FINAL_STATUS_MAX) {
    395       EXPECT_EQ(MATCH_COMPLETE_REPLACEMENT, match_complete_status());
    396     } else {
    397       EXPECT_EQ(expected_final_status_, final_status()) <<
    398           " when testing URL " << prerender_url().path() <<
    399           " (Expected: " << NameFromFinalStatus(expected_final_status_) <<
    400           ", Actual: " << NameFromFinalStatus(final_status()) << ")";
    401     }
    402     // Prerendering RenderViewHosts should be hidden before the first
    403     // navigation, so this should be happen for every PrerenderContents for
    404     // which a RenderViewHost is created, regardless of whether or not it's
    405     // used.
    406     if (new_render_view_host_)
    407       EXPECT_TRUE(was_hidden_);
    408 
    409     // A used PrerenderContents will only be destroyed when we swap out
    410     // WebContents, at the end of a navigation caused by a call to
    411     // NavigateToURLImpl().
    412     if (final_status() == FINAL_STATUS_USED)
    413       EXPECT_TRUE(new_render_view_host_);
    414 
    415     EXPECT_EQ(should_be_shown_, was_shown_);
    416   }
    417 
    418   virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
    419     // On quit, it's possible to end up here when render processes are closed
    420     // before the PrerenderManager is destroyed.  As a result, it's possible to
    421     // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
    422     // on quit.
    423     //
    424     // It's also possible for this to be called after we've been notified of
    425     // app termination, but before we've been deleted, which is why the second
    426     // check is needed.
    427     if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
    428         final_status() != expected_final_status_) {
    429       expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
    430     }
    431 
    432     PrerenderContents::RenderProcessGone(status);
    433   }
    434 
    435   virtual bool CheckURL(const GURL& url) OVERRIDE {
    436     // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
    437     // the PrerenderRendererCrash test.
    438     if (url.spec() != content::kChromeUICrashURL)
    439       return PrerenderContents::CheckURL(url);
    440     return true;
    441   }
    442 
    443   // For tests that open the prerender in a new background tab, the RenderView
    444   // will not have been made visible when the PrerenderContents is destroyed
    445   // even though it is used.
    446   void set_should_be_shown(bool value) { should_be_shown_ = value; }
    447 
    448   // For tests which do not know whether the prerender will be used.
    449   void set_skip_final_checks(bool value) { skip_final_checks_ = value; }
    450 
    451   FinalStatus expected_final_status() const { return expected_final_status_; }
    452 
    453  private:
    454   virtual void OnRenderViewHostCreated(
    455       RenderViewHost* new_render_view_host) OVERRIDE {
    456     // Used to make sure the RenderViewHost is hidden and, if used,
    457     // subsequently shown.
    458     notification_registrar().Add(
    459         this,
    460         content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
    461         content::Source<RenderWidgetHost>(new_render_view_host));
    462 
    463     new_render_view_host_ = new_render_view_host;
    464 
    465     PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
    466   }
    467 
    468   virtual void Observe(int type,
    469                        const content::NotificationSource& source,
    470                        const content::NotificationDetails& details) OVERRIDE {
    471     if (type ==
    472         content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
    473       EXPECT_EQ(new_render_view_host_,
    474                 content::Source<RenderWidgetHost>(source).ptr());
    475       bool is_visible = *content::Details<bool>(details).ptr();
    476 
    477       if (!is_visible) {
    478         was_hidden_ = true;
    479       } else if (is_visible && was_hidden_) {
    480         // Once hidden, a prerendered RenderViewHost should only be shown after
    481         // being removed from the PrerenderContents for display.
    482         EXPECT_FALSE(GetRenderViewHost());
    483         was_shown_ = true;
    484       }
    485       return;
    486     }
    487     PrerenderContents::Observe(type, source, details);
    488   }
    489 
    490   FinalStatus expected_final_status_;
    491 
    492   // The RenderViewHost created for the prerender, if any.
    493   RenderViewHost* new_render_view_host_;
    494   // Set to true when the prerendering RenderWidget is hidden.
    495   bool was_hidden_;
    496   // Set to true when the prerendering RenderWidget is shown, after having been
    497   // hidden.
    498   bool was_shown_;
    499   // Expected final value of was_shown_.  Defaults to true for
    500   // FINAL_STATUS_USED, and false otherwise.
    501   bool should_be_shown_;
    502   // If true, |expected_final_status_| and other shutdown checks are skipped.
    503   bool skip_final_checks_;
    504 };
    505 
    506 // A handle to a TestPrerenderContents whose lifetime is under the caller's
    507 // control. A PrerenderContents may be destroyed at any point. This allows
    508 // tracking the final status, etc.
    509 class TestPrerender : public PrerenderContents::Observer,
    510                       public base::SupportsWeakPtr<TestPrerender> {
    511  public:
    512   TestPrerender()
    513       : contents_(NULL),
    514         number_of_loads_(0),
    515         expected_number_of_loads_(0) {
    516   }
    517   virtual ~TestPrerender() {
    518     if (contents_)
    519       contents_->RemoveObserver(this);
    520   }
    521 
    522   TestPrerenderContents* contents() const { return contents_; }
    523   int number_of_loads() const { return number_of_loads_; }
    524 
    525   void WaitForCreate() { create_loop_.Run(); }
    526   void WaitForStart() { start_loop_.Run(); }
    527   void WaitForStop() { stop_loop_.Run(); }
    528 
    529   // Waits for |number_of_loads()| to be at least |expected_number_of_loads| OR
    530   // for the prerender to stop running (just to avoid a timeout if the prerender
    531   // dies). Note: this does not assert equality on the number of loads; the
    532   // caller must do it instead.
    533   void WaitForLoads(int expected_number_of_loads) {
    534     DCHECK(!load_waiter_);
    535     DCHECK(!expected_number_of_loads_);
    536     if (number_of_loads_ < expected_number_of_loads) {
    537       load_waiter_.reset(new base::RunLoop);
    538       expected_number_of_loads_ = expected_number_of_loads;
    539       load_waiter_->Run();
    540       load_waiter_.reset();
    541       expected_number_of_loads_ = 0;
    542     }
    543     EXPECT_LE(expected_number_of_loads, number_of_loads_);
    544   }
    545 
    546   void OnPrerenderCreated(TestPrerenderContents* contents) {
    547     DCHECK(!contents_);
    548     contents_ = contents;
    549     contents_->AddObserver(this);
    550     create_loop_.Quit();
    551   }
    552 
    553   // PrerenderContents::Observer implementation:
    554   virtual void OnPrerenderStart(PrerenderContents* contents) OVERRIDE {
    555     start_loop_.Quit();
    556   }
    557 
    558   virtual void OnPrerenderStopLoading(PrerenderContents* contents) OVERRIDE {
    559     number_of_loads_++;
    560     if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
    561       load_waiter_->Quit();
    562   }
    563 
    564   virtual void OnPrerenderStop(PrerenderContents* contents) OVERRIDE {
    565     DCHECK(contents_);
    566     contents_ = NULL;
    567     stop_loop_.Quit();
    568     // If there is a WaitForLoads call and it has yet to see the expected number
    569     // of loads, stop the loop so the test fails instead of timing out.
    570     if (load_waiter_)
    571       load_waiter_->Quit();
    572   }
    573 
    574   virtual void OnPrerenderCreatedMatchCompleteReplacement(
    575       PrerenderContents* contents, PrerenderContents* replacement) OVERRIDE {
    576   }
    577 
    578  private:
    579   TestPrerenderContents* contents_;
    580   int number_of_loads_;
    581 
    582   int expected_number_of_loads_;
    583   scoped_ptr<base::RunLoop> load_waiter_;
    584 
    585   base::RunLoop create_loop_;
    586   base::RunLoop start_loop_;
    587   base::RunLoop stop_loop_;
    588 
    589   DISALLOW_COPY_AND_ASSIGN(TestPrerender);
    590 };
    591 
    592 // PrerenderManager that uses TestPrerenderContents.
    593 class TestPrerenderContentsFactory : public PrerenderContents::Factory {
    594  public:
    595   TestPrerenderContentsFactory() {}
    596 
    597   virtual ~TestPrerenderContentsFactory() {
    598     EXPECT_TRUE(expected_contents_queue_.empty());
    599   }
    600 
    601   scoped_ptr<TestPrerender> ExpectPrerenderContents(FinalStatus final_status) {
    602     scoped_ptr<TestPrerender> handle(new TestPrerender());
    603     expected_contents_queue_.push_back(
    604         ExpectedContents(final_status, handle->AsWeakPtr()));
    605     return handle.Pass();
    606   }
    607 
    608   virtual PrerenderContents* CreatePrerenderContents(
    609       PrerenderManager* prerender_manager,
    610       Profile* profile,
    611       const GURL& url,
    612       const content::Referrer& referrer,
    613       Origin origin,
    614       uint8 experiment_id) OVERRIDE {
    615     ExpectedContents expected;
    616     if (!expected_contents_queue_.empty()) {
    617       expected = expected_contents_queue_.front();
    618       expected_contents_queue_.pop_front();
    619     }
    620     VLOG(1) << "Creating prerender contents for " << url.path() <<
    621                " with expected final status " << expected.final_status;
    622     VLOG(1) << expected_contents_queue_.size() << " left in the queue.";
    623     TestPrerenderContents* contents =
    624         new TestPrerenderContents(prerender_manager,
    625                                   profile, url, referrer, origin,
    626                                   expected.final_status);
    627     if (expected.handle)
    628       expected.handle->OnPrerenderCreated(contents);
    629     return contents;
    630   }
    631 
    632  private:
    633   struct ExpectedContents {
    634     ExpectedContents() : final_status(FINAL_STATUS_MAX) { }
    635     ExpectedContents(FinalStatus final_status,
    636                      const base::WeakPtr<TestPrerender>& handle)
    637         : final_status(final_status),
    638           handle(handle) {
    639     }
    640 
    641     FinalStatus final_status;
    642     base::WeakPtr<TestPrerender> handle;
    643   };
    644 
    645   std::deque<ExpectedContents> expected_contents_queue_;
    646 };
    647 
    648 #if defined(FULL_SAFE_BROWSING)
    649 // A SafeBrowsingDatabaseManager implementation that returns a fixed result for
    650 // a given URL.
    651 class FakeSafeBrowsingDatabaseManager :  public SafeBrowsingDatabaseManager {
    652  public:
    653   explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
    654       : SafeBrowsingDatabaseManager(service),
    655         threat_type_(SB_THREAT_TYPE_SAFE) { }
    656 
    657   // Called on the IO thread to check if the given url is safe or not.  If we
    658   // can synchronously determine that the url is safe, CheckUrl returns true.
    659   // Otherwise it returns false, and "client" is called asynchronously with the
    660   // result when it is ready.
    661   // Returns true, indicating a SAFE result, unless the URL is the fixed URL
    662   // specified by the user, and the user-specified result is not SAFE
    663   // (in which that result will be communicated back via a call into the
    664   // client, and false will be returned).
    665   // Overrides SafeBrowsingService::CheckBrowseUrl.
    666   virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE {
    667     if (gurl != url_ || threat_type_ == SB_THREAT_TYPE_SAFE)
    668       return true;
    669 
    670     BrowserThread::PostTask(
    671         BrowserThread::IO, FROM_HERE,
    672         base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
    673                    this, gurl, client));
    674     return false;
    675   }
    676 
    677   void SetThreatTypeForUrl(const GURL& url, SBThreatType threat_type) {
    678     url_ = url;
    679     threat_type_ = threat_type;
    680   }
    681 
    682  private:
    683   virtual ~FakeSafeBrowsingDatabaseManager() {}
    684 
    685   void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
    686     std::vector<SBThreatType> expected_threats;
    687     expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
    688     expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
    689     SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
    690         std::vector<GURL>(1, gurl),
    691         std::vector<SBFullHash>(),
    692         client,
    693         safe_browsing_util::MALWARE,
    694         expected_threats);
    695     sb_check.url_results[0] = threat_type_;
    696     client->OnSafeBrowsingResult(sb_check);
    697   }
    698 
    699   GURL url_;
    700   SBThreatType threat_type_;
    701   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
    702 };
    703 
    704 class FakeSafeBrowsingService : public SafeBrowsingService {
    705  public:
    706   FakeSafeBrowsingService() { }
    707 
    708   // Returned pointer has the same lifespan as the database_manager_ refcounted
    709   // object.
    710   FakeSafeBrowsingDatabaseManager* fake_database_manager() {
    711     return fake_database_manager_;
    712   }
    713 
    714  protected:
    715   virtual ~FakeSafeBrowsingService() { }
    716 
    717   virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
    718     fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
    719     return fake_database_manager_;
    720   }
    721 
    722  private:
    723   FakeSafeBrowsingDatabaseManager* fake_database_manager_;
    724 
    725   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
    726 };
    727 
    728 // Factory that creates FakeSafeBrowsingService instances.
    729 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
    730  public:
    731   TestSafeBrowsingServiceFactory() :
    732       most_recent_service_(NULL) { }
    733   virtual ~TestSafeBrowsingServiceFactory() { }
    734 
    735   virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
    736     most_recent_service_ =  new FakeSafeBrowsingService();
    737     return most_recent_service_;
    738   }
    739 
    740   FakeSafeBrowsingService* most_recent_service() const {
    741     return most_recent_service_;
    742   }
    743 
    744  private:
    745   FakeSafeBrowsingService* most_recent_service_;
    746 };
    747 #endif
    748 
    749 class FakeDevToolsClientHost : public DevToolsClientHost {
    750  public:
    751   FakeDevToolsClientHost() {}
    752   virtual ~FakeDevToolsClientHost() {}
    753   virtual void InspectedContentsClosing() OVERRIDE {}
    754   virtual void DispatchOnInspectorFrontend(const std::string& msg) OVERRIDE {}
    755   virtual void ReplacedWithAnotherClient() OVERRIDE {}
    756 };
    757 
    758 class RestorePrerenderMode {
    759  public:
    760   RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
    761   }
    762 
    763   ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
    764  private:
    765   PrerenderManager::PrerenderManagerMode prev_mode_;
    766 };
    767 
    768 // URLRequestJob (and associated handler) which hangs.
    769 class HangingURLRequestJob : public net::URLRequestJob {
    770  public:
    771   HangingURLRequestJob(net::URLRequest* request,
    772                           net::NetworkDelegate* network_delegate)
    773       : net::URLRequestJob(request, network_delegate) {
    774   }
    775 
    776   virtual void Start() OVERRIDE {}
    777 
    778  private:
    779   virtual ~HangingURLRequestJob() {}
    780 };
    781 
    782 class HangingFirstRequestInterceptor : public net::URLRequestInterceptor {
    783  public:
    784   HangingFirstRequestInterceptor(const base::FilePath& file,
    785                                  base::Closure callback)
    786       : file_(file),
    787         callback_(callback),
    788         first_run_(true) {
    789   }
    790   virtual ~HangingFirstRequestInterceptor() {}
    791 
    792   virtual net::URLRequestJob* MaybeInterceptRequest(
    793       net::URLRequest* request,
    794       net::NetworkDelegate* network_delegate) const OVERRIDE {
    795     if (first_run_) {
    796       first_run_ = false;
    797       if (!callback_.is_null()) {
    798         BrowserThread::PostTask(
    799             BrowserThread::UI, FROM_HERE, callback_);
    800       }
    801       return new HangingURLRequestJob(request, network_delegate);
    802     }
    803     return new content::URLRequestMockHTTPJob(request, network_delegate, file_);
    804   }
    805 
    806  private:
    807   base::FilePath file_;
    808   base::Closure callback_;
    809   mutable bool first_run_;
    810 };
    811 
    812 // Makes |url| never respond on the first load, and then with the contents of
    813 // |file| afterwards. When the first load has been scheduled, runs |callback| on
    814 // the UI thread.
    815 void CreateHangingFirstRequestInterceptorOnIO(
    816     const GURL& url, const base::FilePath& file, base::Closure callback) {
    817   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    818   scoped_ptr<net::URLRequestInterceptor> never_respond_handler(
    819       new HangingFirstRequestInterceptor(file, callback));
    820   net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
    821       url, never_respond_handler.Pass());
    822 }
    823 
    824 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks.
    825 class MockHTTPJob : public content::URLRequestMockHTTPJob {
    826  public:
    827   MockHTTPJob(net::URLRequest* request,
    828               net::NetworkDelegate* delegate,
    829               const base::FilePath& file)
    830       : content::URLRequestMockHTTPJob(request, delegate, file) {
    831   }
    832 
    833   void set_start_callback(const base::Closure& start_callback) {
    834     start_callback_ = start_callback;
    835   }
    836 
    837   virtual void Start() OVERRIDE {
    838     if (!start_callback_.is_null())
    839       start_callback_.Run();
    840     content::URLRequestMockHTTPJob::Start();
    841   }
    842 
    843  private:
    844   virtual ~MockHTTPJob() {}
    845 
    846   base::Closure start_callback_;
    847 };
    848 
    849 // Dummy counter class to live on the UI thread for counting requests.
    850 class RequestCounter : public base::SupportsWeakPtr<RequestCounter> {
    851  public:
    852   RequestCounter() : count_(0), expected_count_(-1) {}
    853   int count() const { return count_; }
    854 
    855   void RequestStarted() {
    856     count_++;
    857     if (loop_ && count_ == expected_count_)
    858       loop_->Quit();
    859   }
    860 
    861   void WaitForCount(int expected_count) {
    862     ASSERT_TRUE(!loop_);
    863     ASSERT_EQ(-1, expected_count_);
    864     if (count_ < expected_count) {
    865       expected_count_ = expected_count;
    866       loop_.reset(new base::RunLoop);
    867       loop_->Run();
    868       expected_count_ = -1;
    869       loop_.reset();
    870     }
    871 
    872     EXPECT_EQ(expected_count, count_);
    873   }
    874  private:
    875   int count_;
    876   int expected_count_;
    877   scoped_ptr<base::RunLoop> loop_;
    878 };
    879 
    880 // Protocol handler which counts the number of requests that start.
    881 class CountingInterceptor : public net::URLRequestInterceptor {
    882  public:
    883   CountingInterceptor(const base::FilePath& file,
    884                       const base::WeakPtr<RequestCounter>& counter)
    885       : file_(file),
    886         counter_(counter),
    887         weak_factory_(this) {
    888   }
    889   virtual ~CountingInterceptor() {}
    890 
    891   virtual net::URLRequestJob* MaybeInterceptRequest(
    892       net::URLRequest* request,
    893       net::NetworkDelegate* network_delegate) const OVERRIDE {
    894     MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
    895     job->set_start_callback(base::Bind(&CountingInterceptor::RequestStarted,
    896                                        weak_factory_.GetWeakPtr()));
    897     return job;
    898   }
    899 
    900   void RequestStarted() {
    901     BrowserThread::PostTask(
    902         BrowserThread::UI, FROM_HERE,
    903         base::Bind(&RequestCounter::RequestStarted, counter_));
    904   }
    905 
    906  private:
    907   base::FilePath file_;
    908   base::WeakPtr<RequestCounter> counter_;
    909   mutable base::WeakPtrFactory<CountingInterceptor> weak_factory_;
    910 };
    911 
    912 // Makes |url| respond to requests with the contents of |file|, counting the
    913 // number that start in |counter|.
    914 void CreateCountingInterceptorOnIO(
    915     const GURL& url,
    916     const base::FilePath& file,
    917     const base::WeakPtr<RequestCounter>& counter) {
    918   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    919   scoped_ptr<net::URLRequestInterceptor> request_interceptor(
    920       new CountingInterceptor(file, counter));
    921   net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
    922       url, request_interceptor.Pass());
    923 }
    924 
    925 // Makes |url| respond to requests with the contents of |file|.
    926 void CreateMockInterceptorOnIO(const GURL& url, const base::FilePath& file) {
    927   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    928   net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
    929       url,
    930       content::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(file));
    931 }
    932 
    933 // A ContentBrowserClient that cancels all prerenderers on OpenURL.
    934 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
    935  public:
    936   TestContentBrowserClient() {}
    937   virtual ~TestContentBrowserClient() {}
    938 
    939   // chrome::ChromeContentBrowserClient implementation.
    940   virtual bool ShouldAllowOpenURL(content::SiteInstance* site_instance,
    941                                   const GURL& url) OVERRIDE {
    942     PrerenderManagerFactory::GetForProfile(
    943         Profile::FromBrowserContext(site_instance->GetBrowserContext()))
    944         ->CancelAllPrerenders();
    945     return chrome::ChromeContentBrowserClient::ShouldAllowOpenURL(site_instance,
    946                                                                   url);
    947   }
    948 
    949  private:
    950   DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
    951 };
    952 
    953 // A ContentBrowserClient that forces cross-process navigations.
    954 class SwapProcessesContentBrowserClient
    955     : public chrome::ChromeContentBrowserClient {
    956  public:
    957   SwapProcessesContentBrowserClient() {}
    958   virtual ~SwapProcessesContentBrowserClient() {}
    959 
    960   // chrome::ChromeContentBrowserClient implementation.
    961   virtual bool ShouldSwapProcessesForRedirect(
    962       content::ResourceContext* resource_context,
    963       const GURL& current_url,
    964       const GURL& new_url) OVERRIDE {
    965     return true;
    966   }
    967 
    968  private:
    969   DISALLOW_COPY_AND_ASSIGN(SwapProcessesContentBrowserClient);
    970 };
    971 
    972 // An ExternalProtocolHandler that blocks everything and asserts it never is
    973 // called.
    974 class NeverRunsExternalProtocolHandlerDelegate
    975     : public ExternalProtocolHandler::Delegate {
    976  public:
    977   // ExternalProtocolHandler::Delegate implementation.
    978   virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
    979       ShellIntegration::DefaultWebClientObserver* observer,
    980       const std::string& protocol) OVERRIDE {
    981     NOTREACHED();
    982     // This will crash, but it shouldn't get this far with BlockState::BLOCK
    983     // anyway.
    984     return NULL;
    985   }
    986   virtual ExternalProtocolHandler::BlockState GetBlockState(
    987       const std::string& scheme) OVERRIDE {
    988     // Block everything and fail the test.
    989     ADD_FAILURE();
    990     return ExternalProtocolHandler::BLOCK;
    991   }
    992   virtual void BlockRequest() OVERRIDE { }
    993   virtual void RunExternalProtocolDialog(const GURL& url,
    994                                          int render_process_host_id,
    995                                          int routing_id) OVERRIDE {
    996     NOTREACHED();
    997   }
    998   virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE {
    999     NOTREACHED();
   1000   }
   1001   virtual void FinishedProcessingCheck() OVERRIDE {
   1002     NOTREACHED();
   1003   }
   1004 };
   1005 
   1006 base::FilePath GetTestPath(const std::string& file_name) {
   1007   return ui_test_utils::GetTestFilePath(
   1008       base::FilePath(FILE_PATH_LITERAL("prerender")),
   1009       base::FilePath().AppendASCII(file_name));
   1010 }
   1011 
   1012 }  // namespace
   1013 
   1014 // Many of these tests are flaky. See http://crbug.com/249179
   1015 class PrerenderBrowserTest : virtual public InProcessBrowserTest {
   1016  public:
   1017   PrerenderBrowserTest()
   1018       : autostart_test_server_(true),
   1019         prerender_contents_factory_(NULL),
   1020 #if defined(FULL_SAFE_BROWSING)
   1021         safe_browsing_factory_(new TestSafeBrowsingServiceFactory()),
   1022 #endif
   1023         call_javascript_(true),
   1024         check_load_events_(true),
   1025         loader_path_("files/prerender/prerender_loader.html"),
   1026         explicitly_set_browser_(NULL) {}
   1027 
   1028   virtual ~PrerenderBrowserTest() {}
   1029 
   1030   content::SessionStorageNamespace* GetSessionStorageNamespace() const {
   1031     WebContents* web_contents = GetActiveWebContents();
   1032     if (!web_contents)
   1033       return NULL;
   1034     return web_contents->GetController().GetDefaultSessionStorageNamespace();
   1035   }
   1036 
   1037   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
   1038 #if defined(FULL_SAFE_BROWSING)
   1039     SafeBrowsingService::RegisterFactory(safe_browsing_factory_.get());
   1040 #endif
   1041   }
   1042 
   1043   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
   1044 #if defined(FULL_SAFE_BROWSING)
   1045     SafeBrowsingService::RegisterFactory(NULL);
   1046 #endif
   1047   }
   1048 
   1049   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   1050     command_line->AppendSwitchASCII(switches::kPrerenderMode,
   1051                                     switches::kPrerenderModeSwitchValueEnabled);
   1052 #if defined(OS_MACOSX)
   1053     // The plugins directory isn't read by default on the Mac, so it needs to be
   1054     // explicitly registered.
   1055     base::FilePath app_dir;
   1056     PathService::Get(chrome::DIR_APP, &app_dir);
   1057     command_line->AppendSwitchPath(
   1058         switches::kExtraPluginDir,
   1059         app_dir.Append(FILE_PATH_LITERAL("plugins")));
   1060 #endif
   1061     command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
   1062   }
   1063 
   1064   virtual void SetUpOnMainThread() OVERRIDE {
   1065     current_browser()->profile()->GetPrefs()->SetBoolean(
   1066         prefs::kPromptForDownload, false);
   1067     IncreasePrerenderMemory();
   1068     if (autostart_test_server_)
   1069       ASSERT_TRUE(test_server()->Start());
   1070     ChromeResourceDispatcherHostDelegate::
   1071         SetExternalProtocolHandlerDelegateForTesting(
   1072             &external_protocol_handler_delegate_);
   1073 
   1074     PrerenderManager* prerender_manager = GetPrerenderManager();
   1075     ASSERT_TRUE(prerender_manager);
   1076     prerender_manager->mutable_config().rate_limit_enabled = false;
   1077     ASSERT_TRUE(prerender_contents_factory_ == NULL);
   1078     prerender_contents_factory_ = new TestPrerenderContentsFactory;
   1079     prerender_manager->SetPrerenderContentsFactory(prerender_contents_factory_);
   1080   }
   1081 
   1082   // Convenience function to get the currently active WebContents in
   1083   // current_browser().
   1084   WebContents* GetActiveWebContents() const {
   1085     return current_browser()->tab_strip_model()->GetActiveWebContents();
   1086   }
   1087 
   1088   // Overload for a single expected final status
   1089   scoped_ptr<TestPrerender> PrerenderTestURL(
   1090       const std::string& html_file,
   1091       FinalStatus expected_final_status,
   1092       int expected_number_of_loads) {
   1093     GURL url = test_server()->GetURL(html_file);
   1094     return PrerenderTestURL(url,
   1095                             expected_final_status,
   1096                             expected_number_of_loads);
   1097   }
   1098 
   1099   ScopedVector<TestPrerender> PrerenderTestURL(
   1100       const std::string& html_file,
   1101       const std::vector<FinalStatus>& expected_final_status_queue,
   1102       int expected_number_of_loads) {
   1103     GURL url = test_server()->GetURL(html_file);
   1104     return PrerenderTestURLImpl(url,
   1105                                 expected_final_status_queue,
   1106                                 expected_number_of_loads);
   1107   }
   1108 
   1109   scoped_ptr<TestPrerender> PrerenderTestURL(
   1110       const GURL& url,
   1111       FinalStatus expected_final_status,
   1112       int expected_number_of_loads) {
   1113     std::vector<FinalStatus> expected_final_status_queue(
   1114         1, expected_final_status);
   1115     std::vector<TestPrerender*> prerenders;
   1116     PrerenderTestURLImpl(url,
   1117                          expected_final_status_queue,
   1118                          expected_number_of_loads).release(&prerenders);
   1119     CHECK_EQ(1u, prerenders.size());
   1120     return scoped_ptr<TestPrerender>(prerenders[0]);
   1121   }
   1122 
   1123   // Navigates to a URL, unrelated to prerendering
   1124   void NavigateStraightToURL(const std::string dest_html_file) {
   1125     ui_test_utils::NavigateToURL(current_browser(),
   1126                                  test_server()->GetURL(dest_html_file));
   1127   }
   1128 
   1129   void NavigateToDestURL() const {
   1130     NavigateToDestURLWithDisposition(CURRENT_TAB, true);
   1131   }
   1132 
   1133   // Opens the url in a new tab, with no opener.
   1134   void NavigateToDestURLWithDisposition(
   1135       WindowOpenDisposition disposition,
   1136       bool expect_swap_to_succeed) const {
   1137     NavigateToURLWithParams(
   1138         content::OpenURLParams(dest_url_, Referrer(), disposition,
   1139                                content::PAGE_TRANSITION_TYPED, false),
   1140         expect_swap_to_succeed);
   1141   }
   1142 
   1143   void NavigateToURL(const std::string& dest_html_file) const {
   1144     NavigateToURLWithDisposition(dest_html_file, CURRENT_TAB, true);
   1145   }
   1146 
   1147   void NavigateToURLWithDisposition(const std::string& dest_html_file,
   1148                                     WindowOpenDisposition disposition,
   1149                                     bool expect_swap_to_succeed) const {
   1150     GURL dest_url = test_server()->GetURL(dest_html_file);
   1151     NavigateToURLWithDisposition(dest_url, disposition, expect_swap_to_succeed);
   1152   }
   1153 
   1154   void NavigateToURLWithDisposition(const GURL& dest_url,
   1155                                     WindowOpenDisposition disposition,
   1156                                     bool expect_swap_to_succeed) const {
   1157     NavigateToURLWithParams(
   1158         content::OpenURLParams(dest_url, Referrer(), disposition,
   1159                                content::PAGE_TRANSITION_TYPED, false),
   1160         expect_swap_to_succeed);
   1161   }
   1162 
   1163   void NavigateToURLWithParams(const content::OpenURLParams& params,
   1164                                bool expect_swap_to_succeed) const {
   1165     NavigateToURLImpl(params, expect_swap_to_succeed);
   1166   }
   1167 
   1168   void OpenDestURLViaClick() const {
   1169     OpenURLViaClick(dest_url_);
   1170   }
   1171 
   1172   void OpenURLViaClick(const GURL& url) const {
   1173     OpenURLWithJSImpl("Click", url, GURL(), false);
   1174   }
   1175 
   1176   void OpenDestURLViaClickTarget() const {
   1177     OpenURLWithJSImpl("ClickTarget", dest_url_, GURL(), true);
   1178   }
   1179 
   1180   void OpenDestURLViaClickPing(const GURL& ping_url) const {
   1181     OpenURLWithJSImpl("ClickPing", dest_url_, ping_url, false);
   1182   }
   1183 
   1184   void OpenDestURLViaClickNewWindow() const {
   1185     OpenURLWithJSImpl("ShiftClick", dest_url_, GURL(), true);
   1186   }
   1187 
   1188   void OpenDestURLViaClickNewForegroundTab() const {
   1189 #if defined(OS_MACOSX)
   1190     OpenURLWithJSImpl("MetaShiftClick", dest_url_, GURL(), true);
   1191 #else
   1192     OpenURLWithJSImpl("CtrlShiftClick", dest_url_, GURL(), true);
   1193 #endif
   1194   }
   1195 
   1196   void OpenDestURLViaClickNewBackgroundTab() const {
   1197 #if defined(OS_MACOSX)
   1198     OpenURLWithJSImpl("MetaClick", dest_url_, GURL(), true);
   1199 #else
   1200     OpenURLWithJSImpl("CtrlClick", dest_url_, GURL(), true);
   1201 #endif
   1202   }
   1203 
   1204   void OpenDestURLViaWindowOpen() const {
   1205     OpenURLViaWindowOpen(dest_url_);
   1206   }
   1207 
   1208   void OpenURLViaWindowOpen(const GURL& url) const {
   1209     OpenURLWithJSImpl("WindowOpen", url, GURL(), true);
   1210   }
   1211 
   1212   void RemoveLinkElement(int i) const {
   1213     GetActiveWebContents()->GetMainFrame()->ExecuteJavaScript(
   1214         base::ASCIIToUTF16(base::StringPrintf("RemoveLinkElement(%d)", i)));
   1215   }
   1216 
   1217   void ClickToNextPageAfterPrerender() {
   1218     TestNavigationObserver nav_observer(GetActiveWebContents());
   1219     RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame();
   1220     render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("ClickOpenLink()"));
   1221     nav_observer.Wait();
   1222   }
   1223 
   1224   void NavigateToNextPageAfterPrerender() const {
   1225     ui_test_utils::NavigateToURL(
   1226         current_browser(),
   1227         test_server()->GetURL("files/prerender/prerender_page.html"));
   1228   }
   1229 
   1230   // Called after the prerendered page has been navigated to and then away from.
   1231   // Navigates back through the history to the prerendered page.
   1232   void GoBackToPrerender() {
   1233     TestNavigationObserver back_nav_observer(GetActiveWebContents());
   1234     chrome::GoBack(current_browser(), CURRENT_TAB);
   1235     back_nav_observer.Wait();
   1236     bool original_prerender_page = false;
   1237     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
   1238         GetActiveWebContents(),
   1239         "window.domAutomationController.send(IsOriginalPrerenderPage())",
   1240         &original_prerender_page));
   1241     EXPECT_TRUE(original_prerender_page);
   1242   }
   1243 
   1244   // Goes back to the page that was active before the prerender was swapped
   1245   // in. This must be called when the prerendered page is the current page
   1246   // in the active tab.
   1247   void GoBackToPageBeforePrerender() {
   1248     WebContents* tab = GetActiveWebContents();
   1249     ASSERT_TRUE(tab);
   1250     EXPECT_FALSE(tab->IsLoading());
   1251     TestNavigationObserver back_nav_observer(tab);
   1252     chrome::GoBack(current_browser(), CURRENT_TAB);
   1253     back_nav_observer.Wait();
   1254     bool js_result;
   1255     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
   1256         tab,
   1257         "window.domAutomationController.send(DidBackToOriginalPagePass())",
   1258         &js_result));
   1259     EXPECT_TRUE(js_result);
   1260   }
   1261 
   1262   bool UrlIsInPrerenderManager(const std::string& html_file) const {
   1263     return UrlIsInPrerenderManager(test_server()->GetURL(html_file));
   1264   }
   1265 
   1266   bool UrlIsInPrerenderManager(const GURL& url) const {
   1267     return GetPrerenderManager()->FindPrerenderData(
   1268         url, GetSessionStorageNamespace()) != NULL;
   1269   }
   1270 
   1271   void UseHttpsSrcServer() {
   1272     if (https_src_server_)
   1273       return;
   1274     https_src_server_.reset(
   1275         new net::SpawnedTestServer(
   1276             net::SpawnedTestServer::TYPE_HTTPS,
   1277             net::SpawnedTestServer::kLocalhost,
   1278             base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))));
   1279     CHECK(https_src_server_->Start());
   1280   }
   1281 
   1282   void DisableJavascriptCalls() {
   1283     call_javascript_ = false;
   1284   }
   1285 
   1286   void DisableLoadEventCheck() {
   1287     check_load_events_ = false;
   1288   }
   1289 
   1290   TaskManagerModel* GetModel() const {
   1291     return TaskManager::GetInstance()->model();
   1292   }
   1293 
   1294   PrerenderManager* GetPrerenderManager() const {
   1295     PrerenderManager* prerender_manager =
   1296         PrerenderManagerFactory::GetForProfile(current_browser()->profile());
   1297     return prerender_manager;
   1298   }
   1299 
   1300   const PrerenderLinkManager* GetPrerenderLinkManager() const {
   1301     PrerenderLinkManager* prerender_link_manager =
   1302         PrerenderLinkManagerFactory::GetForProfile(
   1303             current_browser()->profile());
   1304     return prerender_link_manager;
   1305   }
   1306 
   1307   int GetPrerenderEventCount(int index, const std::string& type) const {
   1308     int event_count;
   1309     std::string expression = base::StringPrintf(
   1310         "window.domAutomationController.send("
   1311         "    GetPrerenderEventCount(%d, '%s'))", index, type.c_str());
   1312 
   1313     CHECK(content::ExecuteScriptAndExtractInt(
   1314         GetActiveWebContents(), expression, &event_count));
   1315     return event_count;
   1316   }
   1317 
   1318   bool DidReceivePrerenderStartEventForLinkNumber(int index) const {
   1319     return GetPrerenderEventCount(index, "webkitprerenderstart") > 0;
   1320   }
   1321 
   1322   int GetPrerenderLoadEventCountForLinkNumber(int index) const {
   1323     return GetPrerenderEventCount(index, "webkitprerenderload");
   1324   }
   1325 
   1326   int GetPrerenderDomContentLoadedEventCountForLinkNumber(int index) const {
   1327     return GetPrerenderEventCount(index, "webkitprerenderdomcontentloaded");
   1328   }
   1329 
   1330   bool DidReceivePrerenderStopEventForLinkNumber(int index) const {
   1331     return GetPrerenderEventCount(index, "webkitprerenderstop") > 0;
   1332   }
   1333 
   1334   void WaitForPrerenderEventCount(int index,
   1335                                   const std::string& type,
   1336                                   int count) const {
   1337     int dummy;
   1338     std::string expression = base::StringPrintf(
   1339         "WaitForPrerenderEventCount(%d, '%s', %d,"
   1340         "    window.domAutomationController.send.bind("
   1341         "        window.domAutomationController, 0))",
   1342         index, type.c_str(), count);
   1343 
   1344     CHECK(content::ExecuteScriptAndExtractInt(
   1345         GetActiveWebContents(), expression, &dummy));
   1346     CHECK_EQ(0, dummy);
   1347   }
   1348 
   1349   bool HadPrerenderEventErrors() const {
   1350     bool had_prerender_event_errors;
   1351     CHECK(content::ExecuteScriptAndExtractBool(
   1352         GetActiveWebContents(),
   1353         "window.domAutomationController.send(Boolean("
   1354         "    hadPrerenderEventErrors))",
   1355         &had_prerender_event_errors));
   1356     return had_prerender_event_errors;
   1357   }
   1358 
   1359   // Asserting on this can result in flaky tests.  PrerenderHandles are
   1360   // removed from the PrerenderLinkManager when the prerender is canceled from
   1361   // the browser, when the prerenders are cancelled from the renderer process,
   1362   // or the channel for the renderer process is closed on the IO thread.  In the
   1363   // last case, the code must be careful to wait for the channel to close, as it
   1364   // is done asynchronously after swapping out the old process.  See
   1365   // ChannelDestructionWatcher.
   1366   bool IsEmptyPrerenderLinkManager() const {
   1367     return GetPrerenderLinkManager()->IsEmpty();
   1368   }
   1369 
   1370   size_t GetLinkPrerenderCount() const {
   1371     return GetPrerenderLinkManager()->prerenders_.size();
   1372   }
   1373 
   1374   size_t GetRunningLinkPrerenderCount() const {
   1375     return GetPrerenderLinkManager()->CountRunningPrerenders();
   1376   }
   1377 
   1378   // Returns length of |prerender_manager_|'s history, or -1 on failure.
   1379   int GetHistoryLength() const {
   1380     scoped_ptr<base::DictionaryValue> prerender_dict(
   1381         static_cast<base::DictionaryValue*>(
   1382             GetPrerenderManager()->GetAsValue()));
   1383     if (!prerender_dict.get())
   1384       return -1;
   1385     base::ListValue* history_list;
   1386     if (!prerender_dict->GetList("history", &history_list))
   1387       return -1;
   1388     return static_cast<int>(history_list->GetSize());
   1389   }
   1390 
   1391 #if defined(FULL_SAFE_BROWSING)
   1392   FakeSafeBrowsingDatabaseManager* GetFakeSafeBrowsingDatabaseManager() {
   1393     return safe_browsing_factory_->most_recent_service()->
   1394         fake_database_manager();
   1395   }
   1396 #endif
   1397 
   1398   TestPrerenderContents* GetPrerenderContentsFor(const GURL& url) const {
   1399     PrerenderManager::PrerenderData* prerender_data =
   1400         GetPrerenderManager()->FindPrerenderData(url, NULL);
   1401     return static_cast<TestPrerenderContents*>(
   1402         prerender_data ? prerender_data->contents() : NULL);
   1403   }
   1404 
   1405   void SetLoaderHostOverride(const std::string& host) {
   1406     loader_host_override_ = host;
   1407     host_resolver()->AddRule(host, "127.0.0.1");
   1408   }
   1409 
   1410   void set_loader_path(const std::string& path) {
   1411     loader_path_ = path;
   1412   }
   1413 
   1414   void set_loader_query(const std::string& query) {
   1415     loader_query_ = query;
   1416   }
   1417 
   1418   GURL GetCrossDomainTestUrl(const std::string& path) {
   1419     static const std::string secondary_domain = "www.foo.com";
   1420     host_resolver()->AddRule(secondary_domain, "127.0.0.1");
   1421     std::string url_str(base::StringPrintf(
   1422         "http://%s:%d/%s",
   1423         secondary_domain.c_str(),
   1424         test_server()->host_port_pair().port(),
   1425         path.c_str()));
   1426     return GURL(url_str);
   1427   }
   1428 
   1429   void set_browser(Browser* browser) {
   1430     explicitly_set_browser_ = browser;
   1431   }
   1432 
   1433   Browser* current_browser() const {
   1434     return explicitly_set_browser_ ? explicitly_set_browser_ : browser();
   1435   }
   1436 
   1437   const GURL& dest_url() const {
   1438     return dest_url_;
   1439   }
   1440 
   1441   void IncreasePrerenderMemory() {
   1442     // Increase the memory allowed in a prerendered page above normal settings.
   1443     // Debug build bots occasionally run against the default limit, and tests
   1444     // were failing because the prerender was canceled due to memory exhaustion.
   1445     // http://crbug.com/93076
   1446     GetPrerenderManager()->mutable_config().max_bytes = 1000 * 1024 * 1024;
   1447   }
   1448 
   1449   bool DidPrerenderPass(WebContents* web_contents) const {
   1450     bool prerender_test_result = false;
   1451     if (!content::ExecuteScriptAndExtractBool(
   1452             web_contents,
   1453             "window.domAutomationController.send(DidPrerenderPass())",
   1454             &prerender_test_result))
   1455       return false;
   1456     return prerender_test_result;
   1457   }
   1458 
   1459   bool DidDisplayPass(WebContents* web_contents) const {
   1460     bool display_test_result = false;
   1461     if (!content::ExecuteScriptAndExtractBool(
   1462             web_contents,
   1463             "window.domAutomationController.send(DidDisplayPass())",
   1464             &display_test_result))
   1465       return false;
   1466     return display_test_result;
   1467   }
   1468 
   1469   scoped_ptr<TestPrerender> ExpectPrerender(FinalStatus expected_final_status) {
   1470     return prerender_contents_factory_->ExpectPrerenderContents(
   1471         expected_final_status);
   1472   }
   1473 
   1474   void AddPrerender(const GURL& url, int index) {
   1475     std::string javascript = base::StringPrintf(
   1476         "AddPrerender('%s', %d)", url.spec().c_str(), index);
   1477     RenderFrameHost* render_frame_host = GetActiveWebContents()->GetMainFrame();
   1478     render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
   1479   }
   1480 
   1481   // Returns a string for pattern-matching TaskManager tab entries.
   1482   base::string16 MatchTaskManagerTab(const char* page_title) {
   1483     return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_TAB_PREFIX,
   1484                                       base::ASCIIToUTF16(page_title));
   1485   }
   1486 
   1487   // Returns a string for pattern-matching TaskManager prerender entries.
   1488   base::string16 MatchTaskManagerPrerender(const char* page_title) {
   1489     return l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_PRERENDER_PREFIX,
   1490                                       base::ASCIIToUTF16(page_title));
   1491   }
   1492 
   1493   void RunJSReturningString(const char* js, std::string* result) {
   1494     ASSERT_TRUE(
   1495         content::ExecuteScriptAndExtractString(
   1496             GetActiveWebContents(),
   1497             base::StringPrintf("window.domAutomationController.send(%s)",
   1498                                js).c_str(),
   1499             result));
   1500   }
   1501 
   1502   void RunJS(const char* js) {
   1503     ASSERT_TRUE(content::ExecuteScript(
   1504         GetActiveWebContents(),
   1505         base::StringPrintf("window.domAutomationController.send(%s)",
   1506                            js).c_str()));
   1507   }
   1508 
   1509  protected:
   1510   bool autostart_test_server_;
   1511 
   1512  private:
   1513   // TODO(davidben): Remove this altogether so the tests don't globally assume
   1514   // only one prerender.
   1515   TestPrerenderContents* GetPrerenderContents() const {
   1516     return GetPrerenderContentsFor(dest_url_);
   1517   }
   1518 
   1519   ScopedVector<TestPrerender> PrerenderTestURLImpl(
   1520       const GURL& prerender_url,
   1521       const std::vector<FinalStatus>& expected_final_status_queue,
   1522       int expected_number_of_loads) {
   1523     dest_url_ = prerender_url;
   1524 
   1525     std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   1526     replacement_text.push_back(
   1527         make_pair("REPLACE_WITH_PRERENDER_URL", prerender_url.spec()));
   1528     std::string replacement_path;
   1529     CHECK(net::SpawnedTestServer::GetFilePathWithReplacements(
   1530         loader_path_,
   1531         replacement_text,
   1532         &replacement_path));
   1533 
   1534     const net::SpawnedTestServer* src_server = test_server();
   1535     if (https_src_server_)
   1536       src_server = https_src_server_.get();
   1537     GURL loader_url = src_server->GetURL(
   1538         replacement_path + "&" + loader_query_);
   1539 
   1540     GURL::Replacements loader_replacements;
   1541     if (!loader_host_override_.empty())
   1542       loader_replacements.SetHostStr(loader_host_override_);
   1543     loader_url = loader_url.ReplaceComponents(loader_replacements);
   1544 
   1545     VLOG(1) << "Running test with queue length " <<
   1546                expected_final_status_queue.size();
   1547     CHECK(!expected_final_status_queue.empty());
   1548     ScopedVector<TestPrerender> prerenders;
   1549     for (size_t i = 0; i < expected_final_status_queue.size(); i++) {
   1550       prerenders.push_back(
   1551           prerender_contents_factory_->ExpectPrerenderContents(
   1552               expected_final_status_queue[i]).release());
   1553     }
   1554 
   1555     FinalStatus expected_final_status = expected_final_status_queue.front();
   1556 
   1557     // Navigate to the loader URL and then wait for the first prerender to be
   1558     // created.
   1559     ui_test_utils::NavigateToURL(current_browser(), loader_url);
   1560     prerenders[0]->WaitForCreate();
   1561     prerenders[0]->WaitForLoads(expected_number_of_loads);
   1562 
   1563     if (ShouldAbortPrerenderBeforeSwap(expected_final_status)) {
   1564       // The prerender will abort on its own. Assert it does so correctly.
   1565       prerenders[0]->WaitForStop();
   1566       EXPECT_FALSE(prerenders[0]->contents());
   1567       EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
   1568     } else {
   1569       // Otherwise, check that it prerendered correctly.
   1570       TestPrerenderContents* prerender_contents = prerenders[0]->contents();
   1571 
   1572       CHECK_NE(static_cast<PrerenderContents*>(NULL), prerender_contents);
   1573       EXPECT_EQ(FINAL_STATUS_MAX, prerender_contents->final_status());
   1574       EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1575 
   1576       if (call_javascript_) {
   1577         // Check if page behaves as expected while in prerendered state.
   1578         EXPECT_TRUE(DidPrerenderPass(prerender_contents->prerender_contents()));
   1579       }
   1580     }
   1581 
   1582     // Test that the referring page received the right start and load events.
   1583     EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1584     if (check_load_events_) {
   1585       EXPECT_EQ(expected_number_of_loads, prerenders[0]->number_of_loads());
   1586       EXPECT_EQ(expected_number_of_loads,
   1587                 GetPrerenderLoadEventCountForLinkNumber(0));
   1588     }
   1589     EXPECT_FALSE(HadPrerenderEventErrors());
   1590 
   1591     return prerenders.Pass();
   1592   }
   1593 
   1594   void NavigateToURLImpl(const content::OpenURLParams& params,
   1595                          bool expect_swap_to_succeed) const {
   1596     ASSERT_NE(static_cast<PrerenderManager*>(NULL), GetPrerenderManager());
   1597     // Make sure in navigating we have a URL to use in the PrerenderManager.
   1598     ASSERT_NE(static_cast<PrerenderContents*>(NULL), GetPrerenderContents());
   1599 
   1600     WebContents* web_contents = GetPrerenderContents()->prerender_contents();
   1601 
   1602     // Navigate and wait for either the load to finish normally or for a swap to
   1603     // occur.
   1604     // TODO(davidben): The only handles CURRENT_TAB navigations, which is the
   1605     // only case tested or prerendered right now.
   1606     CHECK_EQ(CURRENT_TAB, params.disposition);
   1607     NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
   1608                                            GetActiveWebContents());
   1609     WebContents* target_web_contents = current_browser()->OpenURL(params);
   1610     swap_observer.Wait();
   1611 
   1612     if (web_contents && expect_swap_to_succeed) {
   1613       EXPECT_EQ(web_contents, target_web_contents);
   1614       if (call_javascript_)
   1615         EXPECT_TRUE(DidDisplayPass(web_contents));
   1616     }
   1617   }
   1618 
   1619   // Opens the prerendered page using javascript functions in the loader
   1620   // page. |javascript_function_name| should be a 0 argument function which is
   1621   // invoked. |new_web_contents| is true if the navigation is expected to
   1622   // happen in a new WebContents via OpenURL.
   1623   void OpenURLWithJSImpl(const std::string& javascript_function_name,
   1624                          const GURL& url,
   1625                          const GURL& ping_url,
   1626                          bool new_web_contents) const {
   1627     WebContents* web_contents = GetActiveWebContents();
   1628     RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
   1629     // Extra arguments in JS are ignored.
   1630     std::string javascript = base::StringPrintf(
   1631         "%s('%s', '%s')", javascript_function_name.c_str(),
   1632         url.spec().c_str(), ping_url.spec().c_str());
   1633 
   1634     if (new_web_contents) {
   1635       NewTabNavigationOrSwapObserver observer;
   1636       render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
   1637       observer.Wait();
   1638     } else {
   1639       NavigationOrSwapObserver observer(current_browser()->tab_strip_model(),
   1640                                         web_contents);
   1641       render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16(javascript));
   1642       observer.Wait();
   1643     }
   1644   }
   1645 
   1646   TestPrerenderContentsFactory* prerender_contents_factory_;
   1647 #if defined(FULL_SAFE_BROWSING)
   1648   scoped_ptr<TestSafeBrowsingServiceFactory> safe_browsing_factory_;
   1649 #endif
   1650   NeverRunsExternalProtocolHandlerDelegate external_protocol_handler_delegate_;
   1651   GURL dest_url_;
   1652   scoped_ptr<net::SpawnedTestServer> https_src_server_;
   1653   bool call_javascript_;
   1654   bool check_load_events_;
   1655   std::string loader_host_override_;
   1656   std::string loader_path_;
   1657   std::string loader_query_;
   1658   Browser* explicitly_set_browser_;
   1659 };
   1660 
   1661 // Checks that a page is correctly prerendered in the case of a
   1662 // <link rel=prerender> tag and then loaded into a tab in response to a
   1663 // navigation.
   1664 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPage) {
   1665   UMAHistogramHelper histograms;
   1666 
   1667   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   1668   EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
   1669   histograms.Fetch();
   1670   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   1671   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   1672   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   1673   histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
   1674 
   1675   ChannelDestructionWatcher channel_close_watcher;
   1676   channel_close_watcher.WatchChannel(
   1677       GetActiveWebContents()->GetRenderProcessHost());
   1678   NavigateToDestURL();
   1679   channel_close_watcher.WaitForChannelClose();
   1680 
   1681   histograms.Fetch();
   1682   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
   1683   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1);
   1684   histograms.ExpectTotalCount(
   1685       "Prerender.websame_PerceivedPLTMatchedComplete", 1);
   1686 
   1687   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   1688 }
   1689 
   1690 // Checks that cross-domain prerenders emit the correct histograms.
   1691 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageCrossDomain) {
   1692   UMAHistogramHelper histograms;
   1693 
   1694   PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
   1695                    FINAL_STATUS_USED, 1);
   1696   histograms.Fetch();
   1697   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   1698   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   1699   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   1700   histograms.ExpectTotalCount("Prerender.webcross_PrerenderNotSwappedInPLT", 1);
   1701 
   1702   NavigateToDestURL();
   1703   histograms.Fetch();
   1704   histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLT", 1);
   1705   histograms.ExpectTotalCount("Prerender.webcross_PerceivedPLTMatched", 1);
   1706   histograms.ExpectTotalCount(
   1707       "Prerender.webcross_PerceivedPLTMatchedComplete", 1);
   1708 }
   1709 
   1710 // Checks that pending prerenders launch and receive proper event treatment.
   1711 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPagePending) {
   1712   scoped_ptr<TestPrerender> prerender =
   1713       PrerenderTestURL("files/prerender/prerender_page_pending.html",
   1714                        FINAL_STATUS_USED, 1);
   1715 
   1716   // Navigate to the prerender.
   1717   scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
   1718   NavigateToDestURL();
   1719   // Abort early if the original prerender didn't swap, so as not to hang.
   1720   ASSERT_FALSE(prerender->contents());
   1721 
   1722   // Wait for the new prerender to be ready.
   1723   prerender2->WaitForStart();
   1724   prerender2->WaitForLoads(1);
   1725 
   1726   const GURL prerender_page_url =
   1727       test_server()->GetURL("files/prerender/prerender_page.html");
   1728   EXPECT_FALSE(IsEmptyPrerenderLinkManager());
   1729   EXPECT_NE(static_cast<TestPrerenderContents*>(NULL),
   1730             GetPrerenderContentsFor(prerender_page_url));
   1731 
   1732   // Now navigate to our target page.
   1733   NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
   1734                                          GetActiveWebContents());
   1735   ui_test_utils::NavigateToURLWithDisposition(
   1736       current_browser(), prerender_page_url, CURRENT_TAB,
   1737       ui_test_utils::BROWSER_TEST_NONE);
   1738   swap_observer.Wait();
   1739 
   1740   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   1741 }
   1742 
   1743 // Checks that pending prerenders which are canceled before they are launched
   1744 // never get started.
   1745 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovesPending) {
   1746   PrerenderTestURL("files/prerender/prerender_page_removes_pending.html",
   1747                    FINAL_STATUS_USED, 1);
   1748 
   1749   ChannelDestructionWatcher channel_close_watcher;
   1750   channel_close_watcher.WatchChannel(
   1751       GetActiveWebContents()->GetRenderProcessHost());
   1752   NavigateToDestURL();
   1753   channel_close_watcher.WaitForChannelClose();
   1754 
   1755   EXPECT_FALSE(DidReceivePrerenderStartEventForLinkNumber(1));
   1756   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1757   EXPECT_FALSE(HadPrerenderEventErrors());
   1758   // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
   1759   // calls did a thread/process hop to the renderer which insured pending
   1760   // renderer events have arrived.
   1761   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   1762 }
   1763 
   1764 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageRemovingLink) {
   1765   scoped_ptr<TestPrerender> prerender =
   1766       PrerenderTestURL("files/prerender/prerender_page.html",
   1767                        FINAL_STATUS_CANCELLED, 1);
   1768 
   1769   // No ChannelDestructionWatcher is needed here, since prerenders in the
   1770   // PrerenderLinkManager should be deleted by removing the links, rather than
   1771   // shutting down the renderer process.
   1772   RemoveLinkElement(0);
   1773   prerender->WaitForStop();
   1774 
   1775   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1776   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1777   EXPECT_FALSE(HadPrerenderEventErrors());
   1778   // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
   1779   // calls did a thread/process hop to the renderer which insured pending
   1780   // renderer events have arrived.
   1781   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   1782 }
   1783 
   1784 IN_PROC_BROWSER_TEST_F(
   1785     PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinks) {
   1786   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   1787   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   1788 
   1789   set_loader_query("links_to_insert=2");
   1790   scoped_ptr<TestPrerender> prerender =
   1791       PrerenderTestURL("files/prerender/prerender_page.html",
   1792                        FINAL_STATUS_CANCELLED, 1);
   1793   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1794   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1795   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1796   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1797 
   1798   RemoveLinkElement(0);
   1799   RemoveLinkElement(1);
   1800   prerender->WaitForStop();
   1801 
   1802   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1803   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1804   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1805   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1806   EXPECT_FALSE(HadPrerenderEventErrors());
   1807   // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
   1808   // calls did a thread/process hop to the renderer which insured pending
   1809   // renderer events have arrived.
   1810   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   1811 }
   1812 
   1813 IN_PROC_BROWSER_TEST_F(
   1814     PrerenderBrowserTest, PrerenderPageRemovingLinkWithTwoLinksOneLate) {
   1815   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   1816   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   1817 
   1818   GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
   1819   scoped_ptr<TestPrerender> prerender =
   1820       PrerenderTestURL(url, FINAL_STATUS_CANCELLED, 1);
   1821 
   1822   // Add a second prerender for the same link. It reuses the prerender, so only
   1823   // the start event fires here.
   1824   AddPrerender(url, 1);
   1825   WaitForPrerenderEventCount(1, "webkitprerenderstart", 1);
   1826   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1827   EXPECT_EQ(0, GetPrerenderLoadEventCountForLinkNumber(1));
   1828   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1829 
   1830   RemoveLinkElement(0);
   1831   RemoveLinkElement(1);
   1832   prerender->WaitForStop();
   1833 
   1834   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1835   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1836   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1837   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1838   EXPECT_FALSE(HadPrerenderEventErrors());
   1839   // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
   1840   // calls did a thread/process hop to the renderer which insured pending
   1841   // renderer events have arrived.
   1842   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   1843 }
   1844 
   1845 IN_PROC_BROWSER_TEST_F(
   1846     PrerenderBrowserTest,
   1847     PrerenderPageRemovingLinkWithTwoLinksRemovingOne) {
   1848   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   1849   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   1850   set_loader_query("links_to_insert=2");
   1851   PrerenderTestURL("files/prerender/prerender_page.html",
   1852                    FINAL_STATUS_USED, 1);
   1853   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1854   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1855   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1856   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1857 
   1858   RemoveLinkElement(0);
   1859   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   1860   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(0));
   1861   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(1));
   1862   EXPECT_FALSE(DidReceivePrerenderStopEventForLinkNumber(1));
   1863   EXPECT_FALSE(HadPrerenderEventErrors());
   1864   // IsEmptyPrerenderLinkManager() is not racy because the earlier DidReceive*
   1865   // calls did a thread/process hop to the renderer which insured pending
   1866   // renderer events have arrived.
   1867   EXPECT_FALSE(IsEmptyPrerenderLinkManager());
   1868 
   1869   ChannelDestructionWatcher channel_close_watcher;
   1870   channel_close_watcher.WatchChannel(
   1871       GetActiveWebContents()->GetRenderProcessHost());
   1872   NavigateToDestURL();
   1873   channel_close_watcher.WaitForChannelClose();
   1874 
   1875   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   1876 }
   1877 
   1878 // Checks that the visibility API works.
   1879 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderVisibility) {
   1880   PrerenderTestURL("files/prerender/prerender_visibility.html",
   1881                    FINAL_STATUS_USED,
   1882                    1);
   1883   NavigateToDestURL();
   1884 }
   1885 
   1886 // Checks that the prerendering of a page is canceled correctly if we try to
   1887 // swap it in before it commits.
   1888 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap) {
   1889   // Navigate to a page that triggers a prerender for a URL that never commits.
   1890   const GURL kNoCommitUrl("http://never-respond.example.com");
   1891   base::FilePath file(GetTestPath("prerender_page.html"));
   1892 
   1893   base::RunLoop prerender_start_loop;
   1894   BrowserThread::PostTask(
   1895       BrowserThread::IO, FROM_HERE,
   1896       base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl, file,
   1897                  prerender_start_loop.QuitClosure()));
   1898   DisableJavascriptCalls();
   1899   PrerenderTestURL(kNoCommitUrl,
   1900                    FINAL_STATUS_NAVIGATION_UNCOMMITTED,
   1901                    0);
   1902   // Wait for the hanging request to be scheduled.
   1903   prerender_start_loop.Run();
   1904 
   1905   // Navigate to the URL, but assume the contents won't be swapped in.
   1906   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   1907 }
   1908 
   1909 // Checks that client redirects don't add alias URLs until after they commit.
   1910 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNoCommitNoSwap2) {
   1911   // Navigate to a page that then navigates to a URL that never commits.
   1912   const GURL kNoCommitUrl("http://never-respond.example.com");
   1913   base::FilePath file(GetTestPath("prerender_page.html"));
   1914 
   1915   base::RunLoop prerender_start_loop;
   1916   BrowserThread::PostTask(
   1917       BrowserThread::IO, FROM_HERE,
   1918       base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl, file,
   1919                  prerender_start_loop.QuitClosure()));
   1920   DisableJavascriptCalls();
   1921   PrerenderTestURL(CreateClientRedirect(kNoCommitUrl.spec()),
   1922                    FINAL_STATUS_APP_TERMINATING, 1);
   1923   // Wait for the hanging request to be scheduled.
   1924   prerender_start_loop.Run();
   1925 
   1926   // Navigating to the second URL should not swap.
   1927   NavigateToURLWithDisposition(kNoCommitUrl, CURRENT_TAB, false);
   1928 }
   1929 
   1930 // Checks that the prerendering of a page is canceled correctly when a
   1931 // Javascript alert is called.
   1932 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertBeforeOnload) {
   1933   PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
   1934                    FINAL_STATUS_JAVASCRIPT_ALERT,
   1935                    0);
   1936 }
   1937 
   1938 // Checks that the prerendering of a page is canceled correctly when a
   1939 // Javascript alert is called.
   1940 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAlertAfterOnload) {
   1941   PrerenderTestURL("files/prerender/prerender_alert_after_onload.html",
   1942                    FINAL_STATUS_JAVASCRIPT_ALERT,
   1943                    1);
   1944 }
   1945 
   1946 // Checks that plugins are not loaded while a page is being preloaded, but
   1947 // are loaded when the page is displayed.
   1948 #if defined(USE_AURA) && !defined(OS_WIN)
   1949 // http://crbug.com/103496
   1950 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
   1951 #elif defined(OS_MACOSX)
   1952 // http://crbug.com/100514
   1953 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
   1954 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
   1955 // TODO(jschuh): Failing plugin tests. crbug.com/244653
   1956 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
   1957 #elif defined(OS_LINUX)
   1958 // http://crbug.com/306715
   1959 #define MAYBE_PrerenderDelayLoadPlugin DISABLED_PrerenderDelayLoadPlugin
   1960 #else
   1961 #define MAYBE_PrerenderDelayLoadPlugin PrerenderDelayLoadPlugin
   1962 #endif
   1963 // http://crbug.com/306715
   1964 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderDelayLoadPlugin) {
   1965   PrerenderTestURL("files/prerender/plugin_delay_load.html",
   1966                    FINAL_STATUS_USED,
   1967                    1);
   1968   NavigateToDestURL();
   1969 }
   1970 
   1971 // Checks that plugins are not loaded on prerendering pages when click-to-play
   1972 // is enabled.
   1973 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickToPlay) {
   1974   // Enable click-to-play.
   1975   HostContentSettingsMap* content_settings_map =
   1976       current_browser()->profile()->GetHostContentSettingsMap();
   1977   content_settings_map->SetDefaultContentSetting(
   1978       CONTENT_SETTINGS_TYPE_PLUGINS, CONTENT_SETTING_ASK);
   1979 
   1980   PrerenderTestURL("files/prerender/prerender_plugin_click_to_play.html",
   1981                    FINAL_STATUS_USED,
   1982                    1);
   1983   NavigateToDestURL();
   1984 }
   1985 
   1986 // Checks that we don't load a NaCl plugin when NaCl is disabled.
   1987 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNaClPluginDisabled) {
   1988   PrerenderTestURL("files/prerender/prerender_plugin_nacl_disabled.html",
   1989                    FINAL_STATUS_USED,
   1990                    1);
   1991   NavigateToDestURL();
   1992 
   1993 
   1994   // Run this check again.  When we try to load aa ppapi plugin, the
   1995   // "loadstart" event is asynchronously posted to a message loop.
   1996   // It's possible that earlier call could have been run before the
   1997   // the "loadstart" event was posted.
   1998   // TODO(mmenke):  While this should reliably fail on regressions, the
   1999   //                reliability depends on the specifics of ppapi plugin
   2000   //                loading.  It would be great if we could avoid that.
   2001   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   2002 }
   2003 
   2004 // Checks that plugins in an iframe are not loaded while a page is
   2005 // being preloaded, but are loaded when the page is displayed.
   2006 #if defined(USE_AURA) && !defined(OS_WIN)
   2007 // http://crbug.com/103496
   2008 #define MAYBE_PrerenderIframeDelayLoadPlugin \
   2009         DISABLED_PrerenderIframeDelayLoadPlugin
   2010 #elif defined(OS_MACOSX)
   2011 // http://crbug.com/100514
   2012 #define MAYBE_PrerenderIframeDelayLoadPlugin \
   2013         DISABLED_PrerenderIframeDelayLoadPlugin
   2014 #elif defined(OS_WIN) && defined(ARCH_CPU_X86_64)
   2015 // TODO(jschuh): Failing plugin tests. crbug.com/244653
   2016 #define MAYBE_PrerenderIframeDelayLoadPlugin \
   2017         DISABLED_PrerenderIframeDelayLoadPlugin
   2018 #else
   2019 #define MAYBE_PrerenderIframeDelayLoadPlugin PrerenderIframeDelayLoadPlugin
   2020 #endif
   2021 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2022                        MAYBE_PrerenderIframeDelayLoadPlugin) {
   2023   PrerenderTestURL("files/prerender/prerender_iframe_plugin_delay_load.html",
   2024                    FINAL_STATUS_USED,
   2025                    1);
   2026   NavigateToDestURL();
   2027 }
   2028 
   2029 // Renders a page that contains a prerender link to a page that contains an
   2030 // iframe with a source that requires http authentication. This should not
   2031 // prerender successfully.
   2032 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttpAuthentication) {
   2033   PrerenderTestURL("files/prerender/prerender_http_auth_container.html",
   2034                    FINAL_STATUS_AUTH_NEEDED,
   2035                    0);
   2036 }
   2037 
   2038 // Checks that client-issued redirects work with prerendering.
   2039 // This version navigates to the page which issues the redirection, rather
   2040 // than the final destination page.
   2041 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2042                        PrerenderClientRedirectNavigateToFirst) {
   2043   PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
   2044                    FINAL_STATUS_USED,
   2045                    2);
   2046   NavigateToDestURL();
   2047 }
   2048 
   2049 // Checks that client-issued redirects work with prerendering.
   2050 // This version navigates to the final destination page, rather than the
   2051 // page which does the redirection.
   2052 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2053                        PrerenderClientRedirectNavigateToSecond) {
   2054   PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
   2055                    FINAL_STATUS_USED,
   2056                    2);
   2057   NavigateToURL("files/prerender/prerender_page.html");
   2058 }
   2059 
   2060 // Checks that redirects with location.replace do not cancel a prerender and
   2061 // and swap when navigating to the first page.
   2062 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2063                        PrerenderLocationReplaceNavigateToFirst) {
   2064   PrerenderTestURL("files/prerender/prerender_location_replace.html",
   2065                    FINAL_STATUS_USED,
   2066                    2);
   2067   NavigateToDestURL();
   2068 }
   2069 
   2070 // Checks that redirects with location.replace do not cancel a prerender and
   2071 // and swap when navigating to the second.
   2072 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2073                        PrerenderLocationReplaceNavigateToSecond) {
   2074   PrerenderTestURL("files/prerender/prerender_location_replace.html",
   2075                    FINAL_STATUS_USED,
   2076                    2);
   2077   NavigateToURL("files/prerender/prerender_page.html");
   2078 }
   2079 
   2080 // Checks that we get the right PPLT histograms for client redirect prerenders
   2081 // and navigations when the referring page is Google.
   2082 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2083                        PrerenderLocationReplaceGWSHistograms) {
   2084   DisableJavascriptCalls();
   2085   UMAHistogramHelper histograms;
   2086 
   2087   // The loader page should look like Google.
   2088   const std::string kGoogleDotCom("www.google.com");
   2089   SetLoaderHostOverride(kGoogleDotCom);
   2090   set_loader_path("files/prerender/prerender_loader_with_replace_state.html");
   2091 
   2092   GURL dest_url = GetCrossDomainTestUrl(
   2093       "files/prerender/prerender_deferred_image.html");
   2094 
   2095   GURL prerender_url = test_server()->GetURL(
   2096       "files/prerender/prerender_location_replace.html?" +
   2097       net::EscapeQueryParamValue(dest_url.spec(), false) +
   2098       "#prerender");
   2099   GURL::Replacements replacements;
   2100   replacements.SetHostStr(kGoogleDotCom);
   2101   prerender_url = prerender_url.ReplaceComponents(replacements);
   2102 
   2103   // The prerender will not completely load until after the swap, so wait for a
   2104   // title change before calling DidPrerenderPass.
   2105   scoped_ptr<TestPrerender> prerender =
   2106       PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
   2107   WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
   2108   EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
   2109   EXPECT_EQ(1, prerender->number_of_loads());
   2110 
   2111   histograms.Fetch();
   2112   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   2113   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   2114   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   2115   // Although there is a client redirect, it is dropped from histograms because
   2116   // it is a Google URL. The target page itself does not load until after the
   2117   // swap.
   2118   histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0);
   2119 
   2120   GURL navigate_url = test_server()->GetURL(
   2121       "files/prerender/prerender_location_replace.html?" +
   2122       net::EscapeQueryParamValue(dest_url.spec(), false) +
   2123       "#navigate");
   2124   navigate_url = navigate_url.ReplaceComponents(replacements);
   2125 
   2126   NavigationOrSwapObserver swap_observer(
   2127       current_browser()->tab_strip_model(),
   2128       GetActiveWebContents(), 2);
   2129   current_browser()->OpenURL(OpenURLParams(
   2130       navigate_url, Referrer(), CURRENT_TAB,
   2131       content::PAGE_TRANSITION_TYPED, false));
   2132   swap_observer.Wait();
   2133 
   2134   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   2135 
   2136   histograms.Fetch();
   2137   histograms.ExpectTotalCount("Prerender.gws_PrerenderNotSwappedInPLT", 0);
   2138   histograms.ExpectTotalCount("Prerender.gws_PerceivedPLT", 1);
   2139   histograms.ExpectTotalCount("Prerender.gws_PerceivedPLTMatched", 1);
   2140   histograms.ExpectTotalCount(
   2141       "Prerender.gws_PerceivedPLTMatchedComplete", 1);
   2142 
   2143   // The client redirect does /not/ count as a miss because it's a Google URL.
   2144   histograms.ExpectTotalCount("Prerender.PerceivedPLTFirstAfterMiss", 0);
   2145 }
   2146 
   2147 // Checks that client-issued redirects work with prerendering.
   2148 // This version navigates to the final destination page, rather than the
   2149 // page which does the redirection via a mouse click.
   2150 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2151                        PrerenderClientRedirectNavigateToSecondViaClick) {
   2152   GURL prerender_url = test_server()->GetURL(
   2153       CreateClientRedirect("files/prerender/prerender_page.html"));
   2154   GURL destination_url = test_server()->GetURL(
   2155       "files/prerender/prerender_page.html");
   2156   PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 2);
   2157   OpenURLViaClick(destination_url);
   2158 }
   2159 
   2160 // Checks that a page served over HTTPS is correctly prerendered.
   2161 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHttps) {
   2162   net::SpawnedTestServer https_server(
   2163       net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
   2164       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2165   ASSERT_TRUE(https_server.Start());
   2166   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
   2167   PrerenderTestURL(https_url,
   2168                    FINAL_STATUS_USED,
   2169                    1);
   2170   NavigateToDestURL();
   2171 }
   2172 
   2173 // Checks that client-issued redirects within an iframe in a prerendered
   2174 // page will not count as an "alias" for the prerendered page.
   2175 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2176                        PrerenderClientRedirectInIframe) {
   2177   std::string redirect_path = CreateClientRedirect(
   2178       "/files/prerender/prerender_embedded_content.html");
   2179   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2180   replacement_text.push_back(
   2181       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
   2182   std::string replacement_path;
   2183   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2184       "files/prerender/prerender_with_iframe.html",
   2185       replacement_text,
   2186       &replacement_path));
   2187   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 2);
   2188   EXPECT_FALSE(UrlIsInPrerenderManager(
   2189       "files/prerender/prerender_embedded_content.html"));
   2190   NavigateToDestURL();
   2191 }
   2192 
   2193 // Checks that server-issued redirects work with prerendering.
   2194 // This version navigates to the page which issues the redirection, rather
   2195 // than the final destination page.
   2196 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2197                        PrerenderServerRedirectNavigateToFirst) {
   2198   PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
   2199                    FINAL_STATUS_USED,
   2200                    1);
   2201   NavigateToDestURL();
   2202 }
   2203 
   2204 // Checks that server-issued redirects work with prerendering.
   2205 // This version navigates to the final destination page, rather than the
   2206 // page which does the redirection.
   2207 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2208                        PrerenderServerRedirectNavigateToSecond) {
   2209   PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
   2210                    FINAL_STATUS_USED,
   2211                    1);
   2212   NavigateToURL("files/prerender/prerender_page.html");
   2213 }
   2214 
   2215 // Checks that server-issued redirects work with prerendering.
   2216 // This version navigates to the final destination page, rather than the
   2217 // page which does the redirection via a mouse click.
   2218 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2219                        PrerenderServerRedirectNavigateToSecondViaClick) {
   2220   GURL prerender_url = test_server()->GetURL(
   2221       CreateServerRedirect("files/prerender/prerender_page.html"));
   2222   GURL destination_url = test_server()->GetURL(
   2223       "files/prerender/prerender_page.html");
   2224   PrerenderTestURL(prerender_url, FINAL_STATUS_USED, 1);
   2225   OpenURLViaClick(destination_url);
   2226 }
   2227 
   2228 // Checks that server-issued redirects within an iframe in a prerendered
   2229 // page will not count as an "alias" for the prerendered page.
   2230 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderServerRedirectInIframe) {
   2231   std::string redirect_path = CreateServerRedirect(
   2232       "/files/prerender/prerender_embedded_content.html");
   2233   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2234   replacement_text.push_back(
   2235       std::make_pair("REPLACE_WITH_URL", "/" + redirect_path));
   2236   std::string replacement_path;
   2237   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2238       "files/prerender/prerender_with_iframe.html",
   2239       replacement_text,
   2240       &replacement_path));
   2241   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   2242   EXPECT_FALSE(UrlIsInPrerenderManager(
   2243       "files/prerender/prerender_embedded_content.html"));
   2244   NavigateToDestURL();
   2245 }
   2246 
   2247 // Prerenders a page that contains an automatic download triggered through an
   2248 // iframe. This should not prerender successfully.
   2249 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadIframe) {
   2250   PrerenderTestURL("files/prerender/prerender_download_iframe.html",
   2251                    FINAL_STATUS_DOWNLOAD,
   2252                    0);
   2253 }
   2254 
   2255 // Prerenders a page that contains an automatic download triggered through
   2256 // Javascript changing the window.location. This should not prerender
   2257 // successfully
   2258 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadLocation) {
   2259   PrerenderTestURL(CreateClientRedirect("files/download-test1.lib"),
   2260                    FINAL_STATUS_DOWNLOAD,
   2261                    1);
   2262 }
   2263 
   2264 // Prerenders a page that contains an automatic download triggered through a
   2265 // client-issued redirect. This should not prerender successfully.
   2266 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDownloadClientRedirect) {
   2267   PrerenderTestURL("files/prerender/prerender_download_refresh.html",
   2268                    FINAL_STATUS_DOWNLOAD,
   2269                    1);
   2270 }
   2271 
   2272 // Checks that the referrer is set when prerendering.
   2273 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrer) {
   2274   PrerenderTestURL("files/prerender/prerender_referrer.html",
   2275                    FINAL_STATUS_USED,
   2276                    1);
   2277   NavigateToDestURL();
   2278 }
   2279 
   2280 // Checks that the referrer is not set when prerendering and the source page is
   2281 // HTTPS.
   2282 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2283                        PrerenderNoSSLReferrer) {
   2284   UseHttpsSrcServer();
   2285   PrerenderTestURL("files/prerender/prerender_no_referrer.html",
   2286                    FINAL_STATUS_USED,
   2287                    1);
   2288   NavigateToDestURL();
   2289 }
   2290 
   2291 // Checks that the referrer is set when prerendering is cancelled.
   2292 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrer) {
   2293   scoped_ptr<TestContentBrowserClient> test_content_browser_client(
   2294       new TestContentBrowserClient);
   2295   content::ContentBrowserClient* original_browser_client =
   2296       content::SetBrowserClientForTesting(test_content_browser_client.get());
   2297 
   2298   PrerenderTestURL("files/prerender/prerender_referrer.html",
   2299                    FINAL_STATUS_CANCELLED,
   2300                    1);
   2301   OpenDestURLViaClick();
   2302 
   2303   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   2304 
   2305   content::SetBrowserClientForTesting(original_browser_client);
   2306 }
   2307 
   2308 // Checks that popups on a prerendered page cause cancellation.
   2309 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPopup) {
   2310   PrerenderTestURL("files/prerender/prerender_popup.html",
   2311                    FINAL_STATUS_CREATE_NEW_WINDOW,
   2312                    0);
   2313 }
   2314 
   2315 // Checks that registering a protocol handler causes cancellation.
   2316 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRegisterProtocolHandler) {
   2317   PrerenderTestURL("files/prerender/prerender_register_protocol_handler.html",
   2318                    FINAL_STATUS_REGISTER_PROTOCOL_HANDLER,
   2319                    0);
   2320 }
   2321 
   2322 // Checks that renderers using excessive memory will be terminated.
   2323 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExcessiveMemory) {
   2324   ASSERT_TRUE(GetPrerenderManager());
   2325   GetPrerenderManager()->mutable_config().max_bytes = 30 * 1024 * 1024;
   2326   // The excessive memory kill may happen before or after the load event as it
   2327   // happens asynchronously with IPC calls. Even if the test does not start
   2328   // allocating until after load, the browser process might notice before the
   2329   // message gets through. This happens on XP debug bots because they're so
   2330   // slow. Instead, don't bother checking the load event count.
   2331   DisableLoadEventCheck();
   2332   PrerenderTestURL("files/prerender/prerender_excessive_memory.html",
   2333                    FINAL_STATUS_MEMORY_LIMIT_EXCEEDED, 0);
   2334 }
   2335 
   2336 // Checks shutdown code while a prerender is active.
   2337 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderQuickQuit) {
   2338   DisableJavascriptCalls();
   2339   DisableLoadEventCheck();
   2340   PrerenderTestURL("files/prerender/prerender_page.html",
   2341                    FINAL_STATUS_APP_TERMINATING,
   2342                    0);
   2343 }
   2344 
   2345 // Checks that we don't prerender in an infinite loop.
   2346 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderInfiniteLoop) {
   2347   const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
   2348   const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
   2349 
   2350   std::vector<FinalStatus> expected_final_status_queue;
   2351   expected_final_status_queue.push_back(FINAL_STATUS_USED);
   2352   expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
   2353 
   2354   ScopedVector<TestPrerender> prerenders =
   2355       PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
   2356   ASSERT_TRUE(prerenders[0]->contents());
   2357   // Assert that the pending prerender is in there already. This relies on the
   2358   // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
   2359   // the page load one.
   2360   EXPECT_EQ(2U, GetLinkPrerenderCount());
   2361   EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
   2362 
   2363   // Next url should be in pending list but not an active entry.
   2364   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
   2365 
   2366   NavigateToDestURL();
   2367 
   2368   // Make sure the PrerenderContents for the next url is now in the manager and
   2369   // not pending. This relies on pending prerenders being resolved in the same
   2370   // event loop iteration as OnPrerenderStop.
   2371   EXPECT_TRUE(UrlIsInPrerenderManager(kHtmlFileB));
   2372   EXPECT_EQ(1U, GetLinkPrerenderCount());
   2373   EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
   2374 }
   2375 
   2376 // Checks that we don't prerender in an infinite loop and multiple links are
   2377 // handled correctly.
   2378 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2379                        PrerenderInfiniteLoopMultiple) {
   2380   const char* const kHtmlFileA =
   2381       "files/prerender/prerender_infinite_a_multiple.html";
   2382   const char* const kHtmlFileB =
   2383       "files/prerender/prerender_infinite_b_multiple.html";
   2384   const char* const kHtmlFileC =
   2385       "files/prerender/prerender_infinite_c_multiple.html";
   2386 
   2387   // This test is conceptually simplest if concurrency is at two, since we
   2388   // don't have to worry about which of kHtmlFileB or kHtmlFileC gets evicted.
   2389   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   2390   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   2391 
   2392   std::vector<FinalStatus> expected_final_status_queue;
   2393   expected_final_status_queue.push_back(FINAL_STATUS_USED);
   2394   expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
   2395   expected_final_status_queue.push_back(FINAL_STATUS_APP_TERMINATING);
   2396 
   2397   ScopedVector<TestPrerender> prerenders =
   2398       PrerenderTestURL(kHtmlFileA, expected_final_status_queue, 1);
   2399   ASSERT_TRUE(prerenders[0]->contents());
   2400 
   2401   // Next url should be in pending list but not an active entry. This relies on
   2402   // the fact that the renderer sends out the AddLinkRelPrerender IPC before
   2403   // sending the page load one.
   2404   EXPECT_EQ(3U, GetLinkPrerenderCount());
   2405   EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
   2406   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
   2407   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileC));
   2408 
   2409   NavigateToDestURL();
   2410 
   2411   // Make sure the PrerenderContents for the next urls are now in the manager
   2412   // and not pending. One and only one of the URLs (the last seen) should be the
   2413   // active entry. This relies on pending prerenders being resolved in the same
   2414   // event loop iteration as OnPrerenderStop.
   2415   bool url_b_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileB);
   2416   bool url_c_is_active_prerender = UrlIsInPrerenderManager(kHtmlFileC);
   2417   EXPECT_TRUE(url_b_is_active_prerender && url_c_is_active_prerender);
   2418   EXPECT_EQ(2U, GetLinkPrerenderCount());
   2419   EXPECT_EQ(2U, GetRunningLinkPrerenderCount());
   2420 }
   2421 
   2422 // Checks that pending prerenders are aborted (and never launched) when launched
   2423 // by a prerender that itself gets aborted.
   2424 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderAbortPendingOnCancel) {
   2425   const char* const kHtmlFileA = "files/prerender/prerender_infinite_a.html";
   2426   const char* const kHtmlFileB = "files/prerender/prerender_infinite_b.html";
   2427 
   2428   scoped_ptr<TestPrerender> prerender =
   2429       PrerenderTestURL(kHtmlFileA, FINAL_STATUS_CANCELLED, 1);
   2430   ASSERT_TRUE(prerender->contents());
   2431   // Assert that the pending prerender is in there already. This relies on the
   2432   // fact that the renderer sends out the AddLinkRelPrerender IPC before sending
   2433   // the page load one.
   2434   EXPECT_EQ(2U, GetLinkPrerenderCount());
   2435   EXPECT_EQ(1U, GetRunningLinkPrerenderCount());
   2436 
   2437   // Next url should be in pending list but not an active entry.
   2438   EXPECT_FALSE(UrlIsInPrerenderManager(kHtmlFileB));
   2439 
   2440   // Cancel the prerender.
   2441   GetPrerenderManager()->CancelAllPrerenders();
   2442   prerender->WaitForStop();
   2443 
   2444   // All prerenders are now gone.
   2445   EXPECT_TRUE(IsEmptyPrerenderLinkManager());
   2446 }
   2447 
   2448 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerBeforePrerender) {
   2449   const base::string16 any_prerender = MatchTaskManagerPrerender("*");
   2450   const base::string16 any_tab = MatchTaskManagerTab("*");
   2451   const base::string16 original = MatchTaskManagerTab("Preloader");
   2452   const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page");
   2453   const base::string16 final = MatchTaskManagerTab("Prerender Page");
   2454 
   2455   // Show the task manager. This populates the model.
   2456   chrome::OpenTaskManager(current_browser());
   2457   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2458   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
   2459 
   2460   // Prerender a page in addition to the original tab.
   2461   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   2462 
   2463   // A TaskManager entry should appear like "Prerender: Prerender Page"
   2464   // alongside the original tab entry. There should be just these two entries.
   2465   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender));
   2466   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original));
   2467   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final));
   2468   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender));
   2469   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2470 
   2471   // Swap in the prerendered content.
   2472   NavigateToDestURL();
   2473 
   2474   // The "Prerender: " TaskManager entry should disappear, being replaced by a
   2475   // "Tab: Prerender Page" entry, and nothing else.
   2476   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender));
   2477   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original));
   2478   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
   2479   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2480   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
   2481 }
   2482 
   2483 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterPrerender) {
   2484   const base::string16 any_prerender = MatchTaskManagerPrerender("*");
   2485   const base::string16 any_tab = MatchTaskManagerTab("*");
   2486   const base::string16 original = MatchTaskManagerTab("Preloader");
   2487   const base::string16 prerender = MatchTaskManagerPrerender("Prerender Page");
   2488   const base::string16 final = MatchTaskManagerTab("Prerender Page");
   2489 
   2490   // Start with two resources.
   2491   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   2492 
   2493   // Show the task manager. This populates the model. Importantly, we're doing
   2494   // this after the prerender WebContents already exists - the task manager
   2495   // needs to find it, it can't just listen for creation.
   2496   chrome::OpenTaskManager(current_browser());
   2497 
   2498   // A TaskManager entry should appear like "Prerender: Prerender Page"
   2499   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, prerender));
   2500   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, original));
   2501   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, final));
   2502   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_prerender));
   2503   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2504 
   2505   // Swap in the tab.
   2506   NavigateToDestURL();
   2507 
   2508   // The "Prerender: Prerender Page" TaskManager row should disappear, being
   2509   // replaced by "Tab: Prerender Page"
   2510   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, prerender));
   2511   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, original));
   2512   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
   2513   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2514   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
   2515 }
   2516 
   2517 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, OpenTaskManagerAfterSwapIn) {
   2518   const base::string16 any_prerender = MatchTaskManagerPrerender("*");
   2519   const base::string16 any_tab = MatchTaskManagerTab("*");
   2520   const base::string16 final = MatchTaskManagerTab("Prerender Page");
   2521 
   2522   // Prerender, and swap it in.
   2523   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   2524   NavigateToDestURL();
   2525 
   2526   // Show the task manager. This populates the model. Importantly, we're doing
   2527   // this after the prerender has been swapped in.
   2528   chrome::OpenTaskManager(current_browser());
   2529 
   2530   // We should not see a prerender resource in the task manager, just a normal
   2531   // page.
   2532   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, final));
   2533   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, any_tab));
   2534   ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, any_prerender));
   2535 }
   2536 
   2537 // Checks that audio loads are deferred on prerendering.
   2538 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Audio) {
   2539   PrerenderTestURL("files/prerender/prerender_html5_audio.html",
   2540                    FINAL_STATUS_USED,
   2541                    1);
   2542   NavigateToDestURL();
   2543   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2544 }
   2545 
   2546 // Checks that audio loads are deferred on prerendering and played back when
   2547 // the prerender is swapped in if autoplay is set.
   2548 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioAutoplay) {
   2549   PrerenderTestURL("files/prerender/prerender_html5_audio_autoplay.html",
   2550                    FINAL_STATUS_USED,
   2551                    1);
   2552   NavigateToDestURL();
   2553   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2554 }
   2555 
   2556 // Checks that audio loads are deferred on prerendering and played back when
   2557 // the prerender is swapped in if js starts playing.
   2558 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5AudioJsplay) {
   2559   PrerenderTestURL("files/prerender/prerender_html5_audio_jsplay.html",
   2560                    FINAL_STATUS_USED,
   2561                    1);
   2562   NavigateToDestURL();
   2563   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2564 }
   2565 
   2566 // Checks that video loads are deferred on prerendering.
   2567 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5Video) {
   2568   PrerenderTestURL("files/prerender/prerender_html5_video.html",
   2569                    FINAL_STATUS_USED,
   2570                    1);
   2571   NavigateToDestURL();
   2572   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2573 }
   2574 
   2575 // Checks that video tags inserted by javascript are deferred and played
   2576 // correctly on swap in.
   2577 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoJs) {
   2578   PrerenderTestURL("files/prerender/prerender_html5_video_script.html",
   2579                    FINAL_STATUS_USED,
   2580                    1);
   2581   NavigateToDestURL();
   2582   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2583 }
   2584 
   2585 // Checks for correct network events by using a busy sleep the javascript.
   2586 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5VideoNetwork) {
   2587   DisableJavascriptCalls();
   2588   scoped_ptr<TestPrerender> prerender =
   2589       PrerenderTestURL("files/prerender/prerender_html5_video_network.html",
   2590                        FINAL_STATUS_USED,
   2591                        1);
   2592   WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
   2593   EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
   2594   NavigateToDestURL();
   2595   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   2596 }
   2597 
   2598 // Checks that scripts can retrieve the correct window size while prerendering.
   2599 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
   2600   PrerenderTestURL("files/prerender/prerender_size.html",
   2601                    FINAL_STATUS_USED,
   2602                    1);
   2603   NavigateToDestURL();
   2604 }
   2605 
   2606 // TODO(jam): http://crbug.com/350550
   2607 #if !(defined(OS_CHROMEOS) && defined(ADDRESS_SANITIZER))
   2608 
   2609 // Checks that prerenderers will terminate when the RenderView crashes.
   2610 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderRendererCrash) {
   2611   scoped_ptr<TestPrerender> prerender =
   2612       PrerenderTestURL("files/prerender/prerender_page.html",
   2613                        FINAL_STATUS_RENDERER_CRASHED,
   2614                        1);
   2615 
   2616   // Navigate to about:crash and then wait for the renderer to crash.
   2617   ASSERT_TRUE(prerender->contents());
   2618   ASSERT_TRUE(prerender->contents()->prerender_contents());
   2619   prerender->contents()->prerender_contents()->GetController().
   2620       LoadURL(
   2621           GURL(content::kChromeUICrashURL),
   2622           content::Referrer(),
   2623           content::PAGE_TRANSITION_TYPED,
   2624           std::string());
   2625   prerender->WaitForStop();
   2626 }
   2627 #endif
   2628 
   2629 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2630                        PrerenderPageWithFragment) {
   2631   PrerenderTestURL("files/prerender/prerender_page.html#fragment",
   2632                    FINAL_STATUS_USED,
   2633                    1);
   2634 
   2635   ChannelDestructionWatcher channel_close_watcher;
   2636   channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
   2637       GetActiveWebContents()->GetRenderProcessHost());
   2638   NavigateToDestURL();
   2639   channel_close_watcher.WaitForChannelClose();
   2640 
   2641   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   2642 }
   2643 
   2644 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2645                        PrerenderPageWithRedirectedFragment) {
   2646   PrerenderTestURL(
   2647       CreateClientRedirect("files/prerender/prerender_page.html#fragment"),
   2648       FINAL_STATUS_USED,
   2649       2);
   2650 
   2651   ChannelDestructionWatcher channel_close_watcher;
   2652   channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
   2653       GetActiveWebContents()->GetRenderProcessHost());
   2654   NavigateToDestURL();
   2655   channel_close_watcher.WaitForChannelClose();
   2656 
   2657   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   2658 }
   2659 
   2660 // Checks that we do not use a prerendered page when navigating from
   2661 // the main page to a fragment.
   2662 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2663                        PrerenderPageNavigateFragment) {
   2664   PrerenderTestURL("files/prerender/no_prerender_page.html",
   2665                    FINAL_STATUS_APP_TERMINATING,
   2666                    1);
   2667   NavigateToURLWithDisposition(
   2668       "files/prerender/no_prerender_page.html#fragment",
   2669       CURRENT_TAB, false);
   2670 }
   2671 
   2672 // Checks that we do not use a prerendered page when we prerender a fragment
   2673 // but navigate to the main page.
   2674 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2675                        PrerenderFragmentNavigatePage) {
   2676   PrerenderTestURL("files/prerender/no_prerender_page.html#fragment",
   2677                    FINAL_STATUS_APP_TERMINATING,
   2678                    1);
   2679   NavigateToURLWithDisposition(
   2680       "files/prerender/no_prerender_page.html",
   2681       CURRENT_TAB, false);
   2682 }
   2683 
   2684 // Checks that we do not use a prerendered page when we prerender a fragment
   2685 // but navigate to a different fragment on the same page.
   2686 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2687                        PrerenderFragmentNavigateFragment) {
   2688   PrerenderTestURL("files/prerender/no_prerender_page.html#other_fragment",
   2689                    FINAL_STATUS_APP_TERMINATING,
   2690                    1);
   2691   NavigateToURLWithDisposition(
   2692       "files/prerender/no_prerender_page.html#fragment",
   2693       CURRENT_TAB, false);
   2694 }
   2695 
   2696 // Checks that we do not use a prerendered page when the page uses a client
   2697 // redirect to refresh from a fragment on the same page.
   2698 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2699                        PrerenderClientRedirectFromFragment) {
   2700   PrerenderTestURL(
   2701       CreateClientRedirect("files/prerender/no_prerender_page.html#fragment"),
   2702       FINAL_STATUS_APP_TERMINATING,
   2703       2);
   2704   NavigateToURLWithDisposition(
   2705       "files/prerender/no_prerender_page.html",
   2706       CURRENT_TAB, false);
   2707 }
   2708 
   2709 // Checks that we do not use a prerendered page when the page uses a client
   2710 // redirect to refresh to a fragment on the same page.
   2711 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2712                        PrerenderClientRedirectToFragment) {
   2713   PrerenderTestURL(
   2714       CreateClientRedirect("files/prerender/no_prerender_page.html"),
   2715       FINAL_STATUS_APP_TERMINATING,
   2716       2);
   2717   NavigateToURLWithDisposition(
   2718       "files/prerender/no_prerender_page.html#fragment",
   2719       CURRENT_TAB, false);
   2720 }
   2721 
   2722 // Checks that we correctly use a prerendered page when the page uses JS to set
   2723 // the window.location.hash to a fragment on the same page.
   2724 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2725                        PrerenderPageChangeFragmentLocationHash) {
   2726   PrerenderTestURL("files/prerender/prerender_fragment_location_hash.html",
   2727                    FINAL_STATUS_USED,
   2728                    1);
   2729   NavigateToURL("files/prerender/prerender_fragment_location_hash.html");
   2730 }
   2731 
   2732 // Checks that prerendering a PNG works correctly.
   2733 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImagePng) {
   2734   DisableJavascriptCalls();
   2735   PrerenderTestURL("files/prerender/image.png", FINAL_STATUS_USED, 1);
   2736   NavigateToDestURL();
   2737 }
   2738 
   2739 // Checks that prerendering a JPG works correctly.
   2740 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderImageJpeg) {
   2741   DisableJavascriptCalls();
   2742   PrerenderTestURL("files/prerender/image.jpeg", FINAL_STATUS_USED, 1);
   2743   NavigateToDestURL();
   2744 }
   2745 
   2746 // Checks that a prerender of a CRX will result in a cancellation due to
   2747 // download.
   2748 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCrx) {
   2749   PrerenderTestURL("files/prerender/extension.crx", FINAL_STATUS_DOWNLOAD, 0);
   2750 }
   2751 
   2752 // Checks that xhr GET requests allow prerenders.
   2753 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrGet) {
   2754   PrerenderTestURL("files/prerender/prerender_xhr_get.html",
   2755                    FINAL_STATUS_USED,
   2756                    1);
   2757   NavigateToDestURL();
   2758 }
   2759 
   2760 // Checks that xhr HEAD requests allow prerenders.
   2761 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrHead) {
   2762   PrerenderTestURL("files/prerender/prerender_xhr_head.html",
   2763                    FINAL_STATUS_USED,
   2764                    1);
   2765   NavigateToDestURL();
   2766 }
   2767 
   2768 // Checks that xhr OPTIONS requests allow prerenders.
   2769 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrOptions) {
   2770   PrerenderTestURL("files/prerender/prerender_xhr_options.html",
   2771                    FINAL_STATUS_USED,
   2772                    1);
   2773   NavigateToDestURL();
   2774 }
   2775 
   2776 // Checks that xhr TRACE requests allow prerenders.
   2777 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrTrace) {
   2778   PrerenderTestURL("files/prerender/prerender_xhr_trace.html",
   2779                    FINAL_STATUS_USED,
   2780                    1);
   2781   NavigateToDestURL();
   2782 }
   2783 
   2784 // Checks that xhr POST requests allow prerenders.
   2785 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPost) {
   2786   PrerenderTestURL("files/prerender/prerender_xhr_post.html",
   2787                    FINAL_STATUS_USED,
   2788                    1);
   2789   NavigateToDestURL();
   2790 }
   2791 
   2792 // Checks that xhr PUT cancels prerenders.
   2793 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrPut) {
   2794   PrerenderTestURL("files/prerender/prerender_xhr_put.html",
   2795                    FINAL_STATUS_INVALID_HTTP_METHOD,
   2796                    1);
   2797 }
   2798 
   2799 // Checks that xhr DELETE cancels prerenders.
   2800 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderXhrDelete) {
   2801   PrerenderTestURL("files/prerender/prerender_xhr_delete.html",
   2802                    FINAL_STATUS_INVALID_HTTP_METHOD,
   2803                    1);
   2804 }
   2805 
   2806 // Checks that a top-level page which would trigger an SSL error is canceled.
   2807 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorTopLevel) {
   2808   net::SpawnedTestServer::SSLOptions ssl_options;
   2809   ssl_options.server_certificate =
   2810       net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
   2811   net::SpawnedTestServer https_server(
   2812       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2813       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2814   ASSERT_TRUE(https_server.Start());
   2815   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
   2816   PrerenderTestURL(https_url,
   2817                    FINAL_STATUS_SSL_ERROR,
   2818                    0);
   2819 }
   2820 
   2821 // Checks that an SSL error that comes from a subresource does not cancel
   2822 // the page. Non-main-frame requests are simply cancelled if they run into
   2823 // an SSL problem.
   2824 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorSubresource) {
   2825   net::SpawnedTestServer::SSLOptions ssl_options;
   2826   ssl_options.server_certificate =
   2827       net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
   2828   net::SpawnedTestServer https_server(
   2829       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2830       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2831   ASSERT_TRUE(https_server.Start());
   2832   GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
   2833   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2834   replacement_text.push_back(
   2835       std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
   2836   std::string replacement_path;
   2837   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2838       "files/prerender/prerender_with_image.html",
   2839       replacement_text,
   2840       &replacement_path));
   2841   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   2842   NavigateToDestURL();
   2843 }
   2844 
   2845 // Checks that an SSL error that comes from an iframe does not cancel
   2846 // the page. Non-main-frame requests are simply cancelled if they run into
   2847 // an SSL problem.
   2848 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLErrorIframe) {
   2849   net::SpawnedTestServer::SSLOptions ssl_options;
   2850   ssl_options.server_certificate =
   2851       net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
   2852   net::SpawnedTestServer https_server(
   2853       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2854       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2855   ASSERT_TRUE(https_server.Start());
   2856   GURL https_url = https_server.GetURL(
   2857       "files/prerender/prerender_embedded_content.html");
   2858   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2859   replacement_text.push_back(
   2860       std::make_pair("REPLACE_WITH_URL", https_url.spec()));
   2861   std::string replacement_path;
   2862   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2863       "files/prerender/prerender_with_iframe.html",
   2864       replacement_text,
   2865       &replacement_path));
   2866   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   2867   NavigateToDestURL();
   2868 }
   2869 
   2870 // Checks that we cancel correctly when window.print() is called.
   2871 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPrint) {
   2872   DisableLoadEventCheck();
   2873   PrerenderTestURL("files/prerender/prerender_print.html",
   2874                    FINAL_STATUS_WINDOW_PRINT,
   2875                    0);
   2876 }
   2877 
   2878 // Checks that if a page is opened in a new window by javascript and both the
   2879 // pages are in the same domain, the prerendered page is not used, due to
   2880 // there being other tabs in the same browsing instance.
   2881 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2882                        PrerenderSameDomainWindowOpenerWindowOpen) {
   2883   PrerenderTestURL("files/prerender/prerender_page.html",
   2884                    FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
   2885                    1);
   2886   OpenDestURLViaWindowOpen();
   2887 }
   2888 
   2889 // Checks that if a page is opened due to click on a href with target="_blank"
   2890 // and both pages are in the same domain the prerendered page is not used, due
   2891 // there being other tabs in the same browsing instance.
   2892 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2893                        PrerenderSameDomainWindowOpenerClickTarget) {
   2894   PrerenderTestURL("files/prerender/prerender_page.html",
   2895                    FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
   2896                    1);
   2897   OpenDestURLViaClickTarget();
   2898 }
   2899 
   2900 // Checks that prerenders do not get swapped into target pages that have opened
   2901 // a popup, even if the target page itself does not have an opener.
   2902 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderTargetHasPopup) {
   2903   PrerenderTestURL("files/prerender/prerender_page.html",
   2904                    FINAL_STATUS_NON_EMPTY_BROWSING_INSTANCE,
   2905                    1);
   2906   OpenURLViaWindowOpen(GURL(url::kAboutBlankURL));
   2907   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   2908 }
   2909 
   2910 class TestClientCertStore : public net::ClientCertStore {
   2911  public:
   2912   TestClientCertStore() {}
   2913   virtual ~TestClientCertStore() {}
   2914 
   2915   // net::ClientCertStore:
   2916   virtual void GetClientCerts(const net::SSLCertRequestInfo& cert_request_info,
   2917                               net::CertificateList* selected_certs,
   2918                               const base::Closure& callback) OVERRIDE {
   2919     *selected_certs = net::CertificateList(
   2920         1, scoped_refptr<net::X509Certificate>(
   2921         new net::X509Certificate("test", "test", base::Time(), base::Time())));
   2922     callback.Run();
   2923   }
   2924 };
   2925 
   2926 scoped_ptr<net::ClientCertStore> CreateCertStore() {
   2927   return scoped_ptr<net::ClientCertStore>(new TestClientCertStore);
   2928 }
   2929 
   2930 // Checks that a top-level page which would normally request an SSL client
   2931 // certificate will never be seen since it's an https top-level resource.
   2932 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2933                        PrerenderSSLClientCertTopLevel) {
   2934   ProfileIOData::FromResourceContext(
   2935       current_browser()->profile()->GetResourceContext())->
   2936           set_client_cert_store_factory_for_testing(
   2937               base::Bind(&CreateCertStore));
   2938   net::SpawnedTestServer::SSLOptions ssl_options;
   2939   ssl_options.request_client_certificate = true;
   2940   net::SpawnedTestServer https_server(
   2941       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2942       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2943   ASSERT_TRUE(https_server.Start());
   2944   GURL https_url = https_server.GetURL("files/prerender/prerender_page.html");
   2945   PrerenderTestURL(https_url, FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED, 0);
   2946 }
   2947 
   2948 // Checks that an SSL Client Certificate request that originates from a
   2949 // subresource will cancel the prerendered page.
   2950 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   2951                        PrerenderSSLClientCertSubresource) {
   2952   ProfileIOData::FromResourceContext(
   2953       current_browser()->profile()->GetResourceContext())->
   2954           set_client_cert_store_factory_for_testing(
   2955               base::Bind(&CreateCertStore));
   2956   net::SpawnedTestServer::SSLOptions ssl_options;
   2957   ssl_options.request_client_certificate = true;
   2958   net::SpawnedTestServer https_server(
   2959       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2960       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2961   ASSERT_TRUE(https_server.Start());
   2962   GURL https_url = https_server.GetURL("files/prerender/image.jpeg");
   2963   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2964   replacement_text.push_back(
   2965       std::make_pair("REPLACE_WITH_IMAGE_URL", https_url.spec()));
   2966   std::string replacement_path;
   2967   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2968       "files/prerender/prerender_with_image.html",
   2969       replacement_text,
   2970       &replacement_path));
   2971   PrerenderTestURL(replacement_path,
   2972                    FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
   2973                    0);
   2974 }
   2975 
   2976 // Checks that an SSL Client Certificate request that originates from an
   2977 // iframe will cancel the prerendered page.
   2978 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSSLClientCertIframe) {
   2979   ProfileIOData::FromResourceContext(
   2980       current_browser()->profile()->GetResourceContext())->
   2981           set_client_cert_store_factory_for_testing(
   2982               base::Bind(&CreateCertStore));
   2983   net::SpawnedTestServer::SSLOptions ssl_options;
   2984   ssl_options.request_client_certificate = true;
   2985   net::SpawnedTestServer https_server(
   2986       net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
   2987       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
   2988   ASSERT_TRUE(https_server.Start());
   2989   GURL https_url = https_server.GetURL(
   2990       "files/prerender/prerender_embedded_content.html");
   2991   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   2992   replacement_text.push_back(
   2993       std::make_pair("REPLACE_WITH_URL", https_url.spec()));
   2994   std::string replacement_path;
   2995   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   2996       "files/prerender/prerender_with_iframe.html",
   2997       replacement_text,
   2998       &replacement_path));
   2999   PrerenderTestURL(replacement_path,
   3000                    FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED,
   3001                    0);
   3002 }
   3003 
   3004 #if defined(FULL_SAFE_BROWSING)
   3005 // Ensures that we do not prerender pages with a safe browsing
   3006 // interstitial.
   3007 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingTopLevel) {
   3008   GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
   3009   GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
   3010       url, SB_THREAT_TYPE_URL_MALWARE);
   3011   PrerenderTestURL("files/prerender/prerender_page.html",
   3012                    FINAL_STATUS_SAFE_BROWSING, 0);
   3013 }
   3014 
   3015 // Ensures that server redirects to a malware page will cancel prerenders.
   3016 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3017                        PrerenderSafeBrowsingServerRedirect) {
   3018   GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
   3019   GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
   3020       url, SB_THREAT_TYPE_URL_MALWARE);
   3021   PrerenderTestURL(CreateServerRedirect("files/prerender/prerender_page.html"),
   3022                    FINAL_STATUS_SAFE_BROWSING,
   3023                    0);
   3024 }
   3025 
   3026 // Ensures that client redirects to a malware page will cancel prerenders.
   3027 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3028                        PrerenderSafeBrowsingClientRedirect) {
   3029   GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
   3030   GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
   3031       url, SB_THREAT_TYPE_URL_MALWARE);
   3032   PrerenderTestURL(CreateClientRedirect("files/prerender/prerender_page.html"),
   3033                    FINAL_STATUS_SAFE_BROWSING,
   3034                    1);
   3035 }
   3036 
   3037 // Ensures that we do not prerender pages which have a malware subresource.
   3038 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingSubresource) {
   3039   GURL image_url = test_server()->GetURL("files/prerender/image.jpeg");
   3040   GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
   3041       image_url, SB_THREAT_TYPE_URL_MALWARE);
   3042   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3043   replacement_text.push_back(
   3044       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3045   std::string replacement_path;
   3046   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3047       "files/prerender/prerender_with_image.html",
   3048       replacement_text,
   3049       &replacement_path));
   3050   PrerenderTestURL(replacement_path,
   3051                    FINAL_STATUS_SAFE_BROWSING,
   3052                    0);
   3053 }
   3054 
   3055 // Ensures that we do not prerender pages which have a malware iframe.
   3056 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSafeBrowsingIframe) {
   3057   GURL iframe_url = test_server()->GetURL(
   3058       "files/prerender/prerender_embedded_content.html");
   3059   GetFakeSafeBrowsingDatabaseManager()->SetThreatTypeForUrl(
   3060       iframe_url, SB_THREAT_TYPE_URL_MALWARE);
   3061   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3062   replacement_text.push_back(
   3063       std::make_pair("REPLACE_WITH_URL", iframe_url.spec()));
   3064   std::string replacement_path;
   3065   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3066       "files/prerender/prerender_with_iframe.html",
   3067       replacement_text,
   3068       &replacement_path));
   3069   PrerenderTestURL(replacement_path,
   3070                    FINAL_STATUS_SAFE_BROWSING,
   3071                    0);
   3072 }
   3073 
   3074 #endif
   3075 
   3076 // Checks that a local storage read will not cause prerender to fail.
   3077 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageRead) {
   3078   PrerenderTestURL("files/prerender/prerender_localstorage_read.html",
   3079                    FINAL_STATUS_USED,
   3080                    1);
   3081   NavigateToDestURL();
   3082 }
   3083 
   3084 // Checks that a local storage write will not cause prerender to fail.
   3085 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderLocalStorageWrite) {
   3086   PrerenderTestURL("files/prerender/prerender_localstorage_write.html",
   3087                    FINAL_STATUS_USED,
   3088                    1);
   3089   NavigateToDestURL();
   3090 }
   3091 
   3092 // Checks that the favicon is properly loaded on prerender.
   3093 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderFavicon) {
   3094   scoped_ptr<TestPrerender> prerender =
   3095       PrerenderTestURL("files/prerender/prerender_favicon.html",
   3096                        FINAL_STATUS_USED,
   3097                        1);
   3098   NavigateToDestURL();
   3099 
   3100   if (!FaviconTabHelper::FromWebContents(
   3101           GetActiveWebContents())->FaviconIsValid()) {
   3102     // If the favicon has not been set yet, wait for it to be.
   3103     content::WindowedNotificationObserver favicon_update_watcher(
   3104         chrome::NOTIFICATION_FAVICON_UPDATED,
   3105         content::Source<WebContents>(GetActiveWebContents()));
   3106     favicon_update_watcher.Wait();
   3107   }
   3108   EXPECT_TRUE(FaviconTabHelper::FromWebContents(
   3109       GetActiveWebContents())->FaviconIsValid());
   3110 }
   3111 
   3112 // Checks that when a prerendered page is swapped in to a referring page, the
   3113 // unload handlers on the referring page are executed.
   3114 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderUnload) {
   3115   // Matches URL in prerender_loader_with_unload.html.
   3116   const GURL unload_url("http://unload-url.test");
   3117   base::FilePath empty_file = ui_test_utils::GetTestFilePath(
   3118       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
   3119   RequestCounter unload_counter;
   3120   BrowserThread::PostTask(
   3121       BrowserThread::IO, FROM_HERE,
   3122       base::Bind(&CreateCountingInterceptorOnIO,
   3123                  unload_url, empty_file, unload_counter.AsWeakPtr()));
   3124 
   3125   set_loader_path("files/prerender/prerender_loader_with_unload.html");
   3126   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   3127   NavigateToDestURL();
   3128   unload_counter.WaitForCount(1);
   3129 }
   3130 
   3131 // Checks that a hanging unload on the referring page of a prerender swap does
   3132 // not crash the browser on exit.
   3133 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHangingUnload) {
   3134   // Matches URL in prerender_loader_with_unload.html.
   3135   const GURL hang_url("http://unload-url.test");
   3136   base::FilePath empty_file = ui_test_utils::GetTestFilePath(
   3137       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
   3138   BrowserThread::PostTask(
   3139       BrowserThread::IO, FROM_HERE,
   3140       base::Bind(&CreateHangingFirstRequestInterceptorOnIO,
   3141                  hang_url, empty_file,
   3142                  base::Closure()));
   3143 
   3144   set_loader_path("files/prerender/prerender_loader_with_unload.html");
   3145   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   3146   NavigateToDestURL();
   3147 }
   3148 
   3149 
   3150 // Checks that when the history is cleared, prerendering is cancelled and
   3151 // prerendering history is cleared.
   3152 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearHistory) {
   3153   scoped_ptr<TestPrerender> prerender =
   3154       PrerenderTestURL("files/prerender/prerender_page.html",
   3155                        FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
   3156                        1);
   3157 
   3158   ClearBrowsingData(current_browser(), BrowsingDataRemover::REMOVE_HISTORY);
   3159   prerender->WaitForStop();
   3160 
   3161   // Make sure prerender history was cleared.
   3162   EXPECT_EQ(0, GetHistoryLength());
   3163 }
   3164 
   3165 // Checks that when the cache is cleared, prerenders are cancelled but
   3166 // prerendering history is not cleared.
   3167 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClearCache) {
   3168   scoped_ptr<TestPrerender> prerender =
   3169       PrerenderTestURL("files/prerender/prerender_page.html",
   3170                        FINAL_STATUS_CACHE_OR_HISTORY_CLEARED,
   3171                        1);
   3172 
   3173   ClearBrowsingData(current_browser(), BrowsingDataRemover::REMOVE_CACHE);
   3174   prerender->WaitForStop();
   3175 
   3176   // Make sure prerender history was not cleared.  Not a vital behavior, but
   3177   // used to compare with PrerenderClearHistory test.
   3178   EXPECT_EQ(1, GetHistoryLength());
   3179 }
   3180 
   3181 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelAll) {
   3182   scoped_ptr<TestPrerender> prerender =
   3183       PrerenderTestURL("files/prerender/prerender_page.html",
   3184                        FINAL_STATUS_CANCELLED,
   3185                        1);
   3186 
   3187   GetPrerenderManager()->CancelAllPrerenders();
   3188   prerender->WaitForStop();
   3189 
   3190   EXPECT_FALSE(prerender->contents());
   3191 }
   3192 
   3193 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderEvents) {
   3194   scoped_ptr<TestPrerender> prerender =
   3195       PrerenderTestURL("files/prerender/prerender_page.html",
   3196                        FINAL_STATUS_CANCELLED, 1);
   3197 
   3198   GetPrerenderManager()->CancelAllPrerenders();
   3199   prerender->WaitForStop();
   3200 
   3201   EXPECT_TRUE(DidReceivePrerenderStartEventForLinkNumber(0));
   3202   EXPECT_TRUE(DidReceivePrerenderStopEventForLinkNumber(0));
   3203   EXPECT_FALSE(HadPrerenderEventErrors());
   3204 }
   3205 
   3206 // Cancels the prerender of a page with its own prerender.  The second prerender
   3207 // should never be started.
   3208 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3209                        PrerenderCancelPrerenderWithPrerender) {
   3210   scoped_ptr<TestPrerender> prerender =
   3211       PrerenderTestURL("files/prerender/prerender_infinite_a.html",
   3212                        FINAL_STATUS_CANCELLED,
   3213                        1);
   3214 
   3215   GetPrerenderManager()->CancelAllPrerenders();
   3216   prerender->WaitForStop();
   3217 
   3218   EXPECT_FALSE(prerender->contents());
   3219 }
   3220 
   3221 // Prerendering and history tests.
   3222 // The prerendered page is navigated to in several ways [navigate via
   3223 // omnibox, click on link, key-modified click to open in background tab, etc],
   3224 // followed by a navigation to another page from the prerendered page, followed
   3225 // by a back navigation.
   3226 
   3227 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateClickGoBack) {
   3228   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3229                    FINAL_STATUS_USED,
   3230                    1);
   3231   NavigateToDestURL();
   3232   ClickToNextPageAfterPrerender();
   3233   GoBackToPrerender();
   3234 }
   3235 
   3236 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNavigateNavigateGoBack) {
   3237   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3238                    FINAL_STATUS_USED,
   3239                    1);
   3240   NavigateToDestURL();
   3241   NavigateToNextPageAfterPrerender();
   3242   GoBackToPrerender();
   3243 }
   3244 
   3245 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickClickGoBack) {
   3246   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3247                    FINAL_STATUS_USED,
   3248                    1);
   3249   OpenDestURLViaClick();
   3250   ClickToNextPageAfterPrerender();
   3251   GoBackToPrerender();
   3252 }
   3253 
   3254 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNavigateGoBack) {
   3255   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3256                    FINAL_STATUS_USED,
   3257                    1);
   3258   OpenDestURLViaClick();
   3259   NavigateToNextPageAfterPrerender();
   3260   GoBackToPrerender();
   3261 }
   3262 
   3263 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewWindow) {
   3264   // Prerender currently doesn't interpose on this navigation.
   3265   // http://crbug.com/345474.
   3266   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3267                    FINAL_STATUS_USED,
   3268                    1);
   3269   OpenDestURLViaClickNewWindow();
   3270 }
   3271 
   3272 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewForegroundTab) {
   3273   // Prerender currently doesn't interpose on this navigation.
   3274   // http://crbug.com/345474.
   3275   PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3276                    FINAL_STATUS_USED,
   3277                    1);
   3278   OpenDestURLViaClickNewForegroundTab();
   3279 }
   3280 
   3281 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderClickNewBackgroundTab) {
   3282   // Prerender currently doesn't interpose on this navigation.
   3283   // http://crbug.com/345474.
   3284   scoped_ptr<TestPrerender> prerender =
   3285       PrerenderTestURL("files/prerender/prerender_page_with_link.html",
   3286                        FINAL_STATUS_USED,
   3287                        1);
   3288   ASSERT_TRUE(prerender->contents());
   3289   prerender->contents()->set_should_be_shown(false);
   3290   OpenDestURLViaClickNewBackgroundTab();
   3291 }
   3292 
   3293 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3294                        NavigateToPrerenderedPageWhenDevToolsAttached) {
   3295   DisableJavascriptCalls();
   3296   WebContents* web_contents =
   3297       current_browser()->tab_strip_model()->GetActiveWebContents();
   3298   scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
   3299       web_contents->GetRenderViewHost()));
   3300   DevToolsManager* manager = DevToolsManager::GetInstance();
   3301   FakeDevToolsClientHost client_host;
   3302   manager->RegisterDevToolsClientHostFor(agent.get(), &client_host);
   3303   const char* url = "files/prerender/prerender_page.html";
   3304   PrerenderTestURL(url, FINAL_STATUS_DEVTOOLS_ATTACHED, 1);
   3305   NavigateToURLWithDisposition(url, CURRENT_TAB, false);
   3306   manager->ClientHostClosing(&client_host);
   3307 }
   3308 
   3309 // Validate that the sessionStorage namespace remains the same when swapping
   3310 // in a prerendered page.
   3311 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorage) {
   3312   set_loader_path("files/prerender/prerender_loader_with_session_storage.html");
   3313   PrerenderTestURL(GetCrossDomainTestUrl("files/prerender/prerender_page.html"),
   3314                    FINAL_STATUS_USED,
   3315                    1);
   3316   NavigateToDestURL();
   3317   GoBackToPageBeforePrerender();
   3318 }
   3319 
   3320 // Checks that the control group works.  An XHR PUT cannot be detected in the
   3321 // control group.
   3322 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroup) {
   3323   RestorePrerenderMode restore_prerender_mode;
   3324   PrerenderManager::SetMode(
   3325       PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
   3326   DisableJavascriptCalls();
   3327   PrerenderTestURL("files/prerender/prerender_xhr_put.html",
   3328                    FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
   3329   NavigateToDestURL();
   3330 }
   3331 
   3332 // Checks that the control group correctly hits WOULD_HAVE_BEEN_USED
   3333 // renderer-initiated navigations. (This verifies that the ShouldFork logic
   3334 // behaves correctly.)
   3335 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, ControlGroupRendererInitiated) {
   3336   RestorePrerenderMode restore_prerender_mode;
   3337   PrerenderManager::SetMode(
   3338       PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
   3339   DisableJavascriptCalls();
   3340   PrerenderTestURL("files/prerender/prerender_xhr_put.html",
   3341                    FINAL_STATUS_WOULD_HAVE_BEEN_USED, 0);
   3342   OpenDestURLViaClick();
   3343 }
   3344 
   3345 // Make sure that the MatchComplete dummy works in the normal case.  Once
   3346 // a prerender is cancelled because of a script, a dummy must be created to
   3347 // account for the MatchComplete case, and it must have a final status of
   3348 // FINAL_STATUS_WOULD_HAVE_BEEN_USED.
   3349 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MatchCompleteDummy) {
   3350   UMAHistogramHelper histograms;
   3351 
   3352   std::vector<FinalStatus> expected_final_status_queue;
   3353   expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
   3354   expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
   3355   PrerenderTestURL("files/prerender/prerender_xhr_put.html",
   3356                    expected_final_status_queue, 1);
   3357   histograms.Fetch();
   3358   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   3359   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   3360   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   3361   histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
   3362 
   3363   NavigateToDestURL();
   3364   histograms.Fetch();
   3365   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
   3366   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0);
   3367   histograms.ExpectTotalCount(
   3368       "Prerender.websame_PerceivedPLTMatchedComplete", 1);
   3369 }
   3370 
   3371 // Verify that a navigation that hits a MatchComplete dummy while another is in
   3372 // progress does not also classify the previous navigation as a MatchComplete.
   3373 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3374                        MatchCompleteDummyCancelNavigation) {
   3375   UMAHistogramHelper histograms;
   3376 
   3377   // Arrange for a URL to hang.
   3378   const GURL kNoCommitUrl("http://never-respond.example.com");
   3379   base::FilePath file(FILE_PATH_LITERAL(
   3380       "chrome/test/data/prerender/prerender_page.html"));
   3381   base::RunLoop hang_loop;
   3382   BrowserThread::PostTask(
   3383       BrowserThread::IO, FROM_HERE,
   3384       base::Bind(&CreateHangingFirstRequestInterceptorOnIO, kNoCommitUrl,
   3385                  file, hang_loop.QuitClosure()));
   3386 
   3387   // First, fire a prerender that aborts after it completes its load.
   3388   std::vector<FinalStatus> expected_final_status_queue;
   3389   expected_final_status_queue.push_back(FINAL_STATUS_INVALID_HTTP_METHOD);
   3390   expected_final_status_queue.push_back(FINAL_STATUS_WOULD_HAVE_BEEN_USED);
   3391   PrerenderTestURL("files/prerender/prerender_xhr_put.html",
   3392                    expected_final_status_queue, 1);
   3393   histograms.Fetch();
   3394   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   3395   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   3396   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   3397   histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 1);
   3398 
   3399   // Open the hanging URL in a new tab. Wait for both the new tab to open and
   3400   // the hanging request to be scheduled.
   3401   ui_test_utils::NavigateToURLWithDisposition(
   3402       current_browser(), kNoCommitUrl, NEW_FOREGROUND_TAB,
   3403       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   3404   hang_loop.Run();
   3405 
   3406   // Now interrupt that navigation and navigate to the destination URL. This
   3407   // should forcibly complete the previous navigation and also complete a
   3408   // WOULD_HAVE_BEEN_PRERENDERED navigation.
   3409   NavigateToDestURL();
   3410   histograms.Fetch();
   3411   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 2);
   3412   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   3413   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   3414   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
   3415   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 0);
   3416   histograms.ExpectTotalCount(
   3417       "Prerender.websame_PerceivedPLTMatchedComplete", 1);
   3418 }
   3419 
   3420 class PrerenderBrowserTestWithNaCl : public PrerenderBrowserTest {
   3421  public:
   3422   PrerenderBrowserTestWithNaCl() {}
   3423   virtual ~PrerenderBrowserTestWithNaCl() {}
   3424 
   3425   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   3426     PrerenderBrowserTest::SetUpCommandLine(command_line);
   3427     command_line->AppendSwitch(switches::kEnableNaCl);
   3428   }
   3429 };
   3430 
   3431 // Check that NaCl plugins work when enabled, with prerendering.
   3432 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithNaCl,
   3433                        PrerenderNaClPluginEnabled) {
   3434 #if defined(OS_WIN) && defined(USE_ASH)
   3435   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
   3436   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
   3437     return;
   3438 #endif
   3439 
   3440   PrerenderTestURL("files/prerender/prerender_plugin_nacl_enabled.html",
   3441                    FINAL_STATUS_USED,
   3442                    1);
   3443   NavigateToDestURL();
   3444 
   3445   // To avoid any chance of a race, we have to let the script send its response
   3446   // asynchronously.
   3447   WebContents* web_contents =
   3448       browser()->tab_strip_model()->GetActiveWebContents();
   3449   bool display_test_result = false;
   3450   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(web_contents,
   3451                                                    "DidDisplayReallyPass()",
   3452                                                    &display_test_result));
   3453   ASSERT_TRUE(display_test_result);
   3454 }
   3455 
   3456 // Checks that the referrer policy is used when prerendering.
   3457 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReferrerPolicy) {
   3458   set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
   3459   PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
   3460                    FINAL_STATUS_USED,
   3461                    1);
   3462   NavigateToDestURL();
   3463 }
   3464 
   3465 // Checks that the referrer policy is used when prerendering on HTTPS.
   3466 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3467                        PrerenderSSLReferrerPolicy) {
   3468   UseHttpsSrcServer();
   3469   set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
   3470   PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
   3471                    FINAL_STATUS_USED,
   3472                    1);
   3473   NavigateToDestURL();
   3474 }
   3475 
   3476 // Checks that the referrer policy is used when prerendering is cancelled.
   3477 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCancelReferrerPolicy) {
   3478   scoped_ptr<TestContentBrowserClient> test_content_browser_client(
   3479       new TestContentBrowserClient);
   3480   content::ContentBrowserClient* original_browser_client =
   3481       content::SetBrowserClientForTesting(test_content_browser_client.get());
   3482 
   3483   set_loader_path("files/prerender/prerender_loader_with_referrer_policy.html");
   3484   PrerenderTestURL("files/prerender/prerender_referrer_policy.html",
   3485                    FINAL_STATUS_CANCELLED,
   3486                    1);
   3487   OpenDestURLViaClick();
   3488 
   3489   bool display_test_result = false;
   3490   WebContents* web_contents =
   3491       browser()->tab_strip_model()->GetActiveWebContents();
   3492   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
   3493       web_contents,
   3494       "window.domAutomationController.send(DidDisplayPass())",
   3495       &display_test_result));
   3496   EXPECT_TRUE(display_test_result);
   3497 
   3498   content::SetBrowserClientForTesting(original_browser_client);
   3499 }
   3500 
   3501 // Test interaction of the webNavigation and tabs API with prerender.
   3502 class PrerenderBrowserTestWithExtensions : public PrerenderBrowserTest,
   3503                                            public ExtensionApiTest {
   3504  public:
   3505   PrerenderBrowserTestWithExtensions() {
   3506     // The individual tests start the test server through ExtensionApiTest, so
   3507     // the port number can be passed through to the extension.
   3508     autostart_test_server_ = false;
   3509   }
   3510 
   3511   virtual void SetUp() OVERRIDE {
   3512     PrerenderBrowserTest::SetUp();
   3513   }
   3514 
   3515   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
   3516     PrerenderBrowserTest::SetUpCommandLine(command_line);
   3517     ExtensionApiTest::SetUpCommandLine(command_line);
   3518   }
   3519 
   3520   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
   3521     PrerenderBrowserTest::SetUpInProcessBrowserTestFixture();
   3522     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
   3523   }
   3524 
   3525   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
   3526     PrerenderBrowserTest::TearDownInProcessBrowserTestFixture();
   3527     ExtensionApiTest::TearDownInProcessBrowserTestFixture();
   3528   }
   3529 
   3530   virtual void SetUpOnMainThread() OVERRIDE {
   3531     PrerenderBrowserTest::SetUpOnMainThread();
   3532   }
   3533 };
   3534 
   3535 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, WebNavigation) {
   3536   ASSERT_TRUE(StartSpawnedTestServer());
   3537   extensions::FrameNavigationState::set_allow_extension_scheme(true);
   3538 
   3539   // Wait for the extension to set itself up and return control to us.
   3540   ASSERT_TRUE(RunExtensionTest("webnavigation/prerender")) << message_;
   3541 
   3542   ResultCatcher catcher;
   3543 
   3544   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   3545 
   3546   ChannelDestructionWatcher channel_close_watcher;
   3547   channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
   3548       GetActiveWebContents()->GetRenderProcessHost());
   3549   NavigateToDestURL();
   3550   channel_close_watcher.WaitForChannelClose();
   3551 
   3552   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   3553   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
   3554 }
   3555 
   3556 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, TabsApi) {
   3557   ASSERT_TRUE(StartSpawnedTestServer());
   3558   extensions::FrameNavigationState::set_allow_extension_scheme(true);
   3559 
   3560   // Wait for the extension to set itself up and return control to us.
   3561   ASSERT_TRUE(RunExtensionTest("tabs/on_replaced")) << message_;
   3562 
   3563   ResultCatcher catcher;
   3564 
   3565   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   3566 
   3567   ChannelDestructionWatcher channel_close_watcher;
   3568   channel_close_watcher.WatchChannel(browser()->tab_strip_model()->
   3569       GetActiveWebContents()->GetRenderProcessHost());
   3570   NavigateToDestURL();
   3571   channel_close_watcher.WaitForChannelClose();
   3572 
   3573   ASSERT_TRUE(IsEmptyPrerenderLinkManager());
   3574   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
   3575 }
   3576 
   3577 // Test that prerenders abort when navigating to a stream.
   3578 // See chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
   3579 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTestWithExtensions, StreamsTest) {
   3580   ASSERT_TRUE(StartSpawnedTestServer());
   3581 
   3582   const extensions::Extension* extension = LoadExtension(
   3583       test_data_dir_.AppendASCII("streams_private/handle_mime_type"));
   3584   ASSERT_TRUE(extension);
   3585   EXPECT_EQ(std::string(extension_misc::kStreamsPrivateTestExtensionId),
   3586             extension->id());
   3587   MimeTypesHandler* handler = MimeTypesHandler::GetHandler(extension);
   3588   ASSERT_TRUE(handler);
   3589   EXPECT_TRUE(handler->CanHandleMIMEType("application/msword"));
   3590 
   3591   PrerenderTestURL("files/prerender/document.doc", FINAL_STATUS_DOWNLOAD, 0);
   3592 
   3593   // Sanity-check that the extension would have picked up the stream in a normal
   3594   // navigation had prerender not intercepted it.
   3595   // streams_private/handle_mime_type reports success if it has handled the
   3596   // application/msword type.
   3597   ResultCatcher catcher;
   3598   NavigateToDestURL();
   3599   EXPECT_TRUE(catcher.GetNextResult());
   3600 }
   3601 
   3602 // Checks that non-http/https/chrome-extension subresource cancels the
   3603 // prerender.
   3604 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3605                        PrerenderCancelSubresourceUnsupportedScheme) {
   3606   GURL image_url = GURL("invalidscheme://www.google.com/test.jpg");
   3607   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3608   replacement_text.push_back(
   3609       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3610   std::string replacement_path;
   3611   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3612       "files/prerender/prerender_with_image.html",
   3613       replacement_text,
   3614       &replacement_path));
   3615   PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
   3616 }
   3617 
   3618 // Ensure that about:blank is permitted for any subresource.
   3619 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3620                        PrerenderAllowAboutBlankSubresource) {
   3621   GURL image_url = GURL("about:blank");
   3622   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3623   replacement_text.push_back(
   3624       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3625   std::string replacement_path;
   3626   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3627       "files/prerender/prerender_with_image.html",
   3628       replacement_text,
   3629       &replacement_path));
   3630   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   3631   NavigateToDestURL();
   3632 }
   3633 
   3634 // Checks that non-http/https/chrome-extension subresource cancels the prerender
   3635 // on redirect.
   3636 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3637                        PrerenderCancelSubresourceRedirectUnsupportedScheme) {
   3638   GURL image_url = test_server()->GetURL(
   3639       CreateServerRedirect("invalidscheme://www.google.com/test.jpg"));
   3640   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3641   replacement_text.push_back(
   3642       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3643   std::string replacement_path;
   3644   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3645       "files/prerender/prerender_with_image.html",
   3646       replacement_text,
   3647       &replacement_path));
   3648   PrerenderTestURL(replacement_path, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
   3649 }
   3650 
   3651 // Checks that chrome-extension subresource does not cancel the prerender.
   3652 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3653                        PrerenderKeepSubresourceExtensionScheme) {
   3654   GURL image_url = GURL("chrome-extension://abcdefg/test.jpg");
   3655   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3656   replacement_text.push_back(
   3657       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3658   std::string replacement_path;
   3659   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3660       "files/prerender/prerender_with_image.html",
   3661       replacement_text,
   3662       &replacement_path));
   3663   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   3664   NavigateToDestURL();
   3665 }
   3666 
   3667 // Checks that redirect to chrome-extension subresource does not cancel the
   3668 // prerender.
   3669 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3670                        PrerenderKeepSubresourceRedirectExtensionScheme) {
   3671   GURL image_url = test_server()->GetURL(
   3672       CreateServerRedirect("chrome-extension://abcdefg/test.jpg"));
   3673   std::vector<net::SpawnedTestServer::StringPair> replacement_text;
   3674   replacement_text.push_back(
   3675       std::make_pair("REPLACE_WITH_IMAGE_URL", image_url.spec()));
   3676   std::string replacement_path;
   3677   ASSERT_TRUE(net::SpawnedTestServer::GetFilePathWithReplacements(
   3678       "files/prerender/prerender_with_image.html",
   3679       replacement_text,
   3680       &replacement_path));
   3681   PrerenderTestURL(replacement_path, FINAL_STATUS_USED, 1);
   3682   NavigateToDestURL();
   3683 }
   3684 
   3685 // Checks that non-http/https main page redirects cancel the prerender.
   3686 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3687                        PrerenderCancelMainFrameRedirectUnsupportedScheme) {
   3688   GURL url = test_server()->GetURL(
   3689       CreateServerRedirect("invalidscheme://www.google.com/test.html"));
   3690   PrerenderTestURL(url, FINAL_STATUS_UNSUPPORTED_SCHEME, 0);
   3691 }
   3692 
   3693 // Checks that media source video loads are deferred on prerendering.
   3694 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderHTML5MediaSourceVideo) {
   3695   PrerenderTestURL("files/prerender/prerender_html5_video_media_source.html",
   3696                    FINAL_STATUS_USED,
   3697                    1);
   3698   NavigateToDestURL();
   3699   WaitForASCIITitle(GetActiveWebContents(), kPassTitle);
   3700 }
   3701 
   3702 // Checks that a prerender that creates an audio stream (via a WebAudioDevice)
   3703 // is cancelled.
   3704 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWebAudioDevice) {
   3705   DisableLoadEventCheck();
   3706   PrerenderTestURL("files/prerender/prerender_web_audio_device.html",
   3707                    FINAL_STATUS_CREATING_AUDIO_STREAM, 0);
   3708 }
   3709 
   3710 // Checks that prerenders do not swap in to WebContents being captured.
   3711 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCapturedWebContents) {
   3712   PrerenderTestURL("files/prerender/prerender_page.html",
   3713                    FINAL_STATUS_PAGE_BEING_CAPTURED, 1);
   3714   WebContents* web_contents = GetActiveWebContents();
   3715   web_contents->IncrementCapturerCount(gfx::Size());
   3716   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   3717   web_contents->DecrementCapturerCount();
   3718 }
   3719 
   3720 // Checks that prerenders are aborted on cross-process navigation from
   3721 // a server redirect.
   3722 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3723                        PrerenderCrossProcessServerRedirect) {
   3724   // Force everything to be a process swap.
   3725   SwapProcessesContentBrowserClient test_browser_client;
   3726   content::ContentBrowserClient* original_browser_client =
   3727       content::SetBrowserClientForTesting(&test_browser_client);
   3728 
   3729   PrerenderTestURL(
   3730       CreateServerRedirect("files/prerender/prerender_page.html"),
   3731       FINAL_STATUS_OPEN_URL, 0);
   3732 
   3733   content::SetBrowserClientForTesting(original_browser_client);
   3734 }
   3735 
   3736 // Checks that URLRequests for prerenders being aborted on cross-process
   3737 // navigation from a server redirect are cleaned up, so they don't keep cache
   3738 // entries locked.
   3739 // See http://crbug.com/341134
   3740 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3741                        PrerenderCrossProcessServerRedirectNoHang) {
   3742   const char kDestPath[] = "files/prerender/prerender_page.html";
   3743   // Force everything to be a process swap.
   3744   SwapProcessesContentBrowserClient test_browser_client;
   3745   content::ContentBrowserClient* original_browser_client =
   3746       content::SetBrowserClientForTesting(&test_browser_client);
   3747 
   3748   PrerenderTestURL(CreateServerRedirect(kDestPath), FINAL_STATUS_OPEN_URL, 0);
   3749 
   3750   ui_test_utils::NavigateToURL(
   3751       browser(),
   3752       test_server()->GetURL(kDestPath));
   3753 
   3754   content::SetBrowserClientForTesting(original_browser_client);
   3755 }
   3756 
   3757 // Checks that prerenders are aborted on cross-process navigation from
   3758 // a client redirect.
   3759 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3760                        PrerenderCrossProcessClientRedirect) {
   3761   // Cross-process navigation logic for renderer-initiated navigations
   3762   // is partially controlled by the renderer, namely
   3763   // ChromeContentRendererClient. This test instead relies on the Web
   3764   // Store triggering such navigations.
   3765   std::string webstore_url = extension_urls::GetWebstoreLaunchURL();
   3766 
   3767   // Mock out requests to the Web Store.
   3768   base::FilePath file(GetTestPath("prerender_page.html"));
   3769   BrowserThread::PostTask(
   3770       BrowserThread::IO, FROM_HERE,
   3771       base::Bind(&CreateMockInterceptorOnIO, GURL(webstore_url), file));
   3772 
   3773   PrerenderTestURL(CreateClientRedirect(webstore_url),
   3774                    FINAL_STATUS_OPEN_URL, 1);
   3775 }
   3776 
   3777 // Checks that canceling a MatchComplete dummy doesn't result in two
   3778 // stop events.
   3779 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, CancelMatchCompleteDummy) {
   3780   std::vector<FinalStatus> expected_final_status_queue;
   3781   expected_final_status_queue.push_back(FINAL_STATUS_JAVASCRIPT_ALERT);
   3782   expected_final_status_queue.push_back(FINAL_STATUS_CANCELLED);
   3783   ScopedVector<TestPrerender> prerenders =
   3784       PrerenderTestURL("files/prerender/prerender_alert_before_onload.html",
   3785                        expected_final_status_queue, 0);
   3786 
   3787   // Cancel the MatchComplete dummy.
   3788   GetPrerenderManager()->CancelAllPrerenders();
   3789   prerenders[1]->WaitForStop();
   3790 
   3791   // Check the referring page only got one copy of the event.
   3792   EXPECT_FALSE(HadPrerenderEventErrors());
   3793 }
   3794 
   3795 // Checks that a deferred redirect to an image is not loaded until the page is
   3796 // visible. Also test the right histogram events are emitted in this case.
   3797 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredImage) {
   3798   DisableJavascriptCalls();
   3799   UMAHistogramHelper histograms;
   3800 
   3801   // The prerender will not completely load until after the swap, so wait for a
   3802   // title change before calling DidPrerenderPass.
   3803   scoped_ptr<TestPrerender> prerender =
   3804       PrerenderTestURL(
   3805           "files/prerender/prerender_deferred_image.html",
   3806           FINAL_STATUS_USED, 0);
   3807   WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
   3808   EXPECT_EQ(1, GetPrerenderDomContentLoadedEventCountForLinkNumber(0));
   3809   EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
   3810   EXPECT_EQ(0, prerender->number_of_loads());
   3811   histograms.Fetch();
   3812   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   3813   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   3814   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   3815   histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0);
   3816 
   3817   // Swap.
   3818   NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
   3819                                          GetActiveWebContents());
   3820   ui_test_utils::NavigateToURLWithDisposition(
   3821       current_browser(), dest_url(), CURRENT_TAB,
   3822       ui_test_utils::BROWSER_TEST_NONE);
   3823   swap_observer.Wait();
   3824 
   3825   // The prerender never observes the final load.
   3826   EXPECT_EQ(0, prerender->number_of_loads());
   3827 
   3828   // Now check DidDisplayPass.
   3829   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   3830 
   3831   histograms.Fetch();
   3832   histograms.ExpectTotalCount("Prerender.websame_PrerenderNotSwappedInPLT", 0);
   3833   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLT", 1);
   3834   histograms.ExpectTotalCount("Prerender.websame_PerceivedPLTMatched", 1);
   3835   histograms.ExpectTotalCount(
   3836       "Prerender.websame_PerceivedPLTMatchedComplete", 1);
   3837 }
   3838 
   3839 // Checks that a deferred redirect to an image is not loaded until the
   3840 // page is visible, even after another redirect.
   3841 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3842                        PrerenderDeferredImageAfterRedirect) {
   3843   DisableJavascriptCalls();
   3844 
   3845   // The prerender will not completely load until after the swap, so wait for a
   3846   // title change before calling DidPrerenderPass.
   3847   scoped_ptr<TestPrerender> prerender =
   3848       PrerenderTestURL(
   3849           "files/prerender/prerender_deferred_image.html",
   3850           FINAL_STATUS_USED, 0);
   3851   WaitForASCIITitle(prerender->contents()->prerender_contents(), kReadyTitle);
   3852   EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
   3853   EXPECT_EQ(0, prerender->number_of_loads());
   3854 
   3855   // Swap.
   3856   NavigationOrSwapObserver swap_observer(current_browser()->tab_strip_model(),
   3857                                          GetActiveWebContents());
   3858   ui_test_utils::NavigateToURLWithDisposition(
   3859       current_browser(), dest_url(), CURRENT_TAB,
   3860       ui_test_utils::BROWSER_TEST_NONE);
   3861   swap_observer.Wait();
   3862 
   3863   // The prerender never observes the final load.
   3864   EXPECT_EQ(0, prerender->number_of_loads());
   3865 
   3866   // Now check DidDisplayPass.
   3867   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   3868 }
   3869 
   3870 // Checks that deferred redirects in the main frame are followed.
   3871 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredMainFrame) {
   3872   DisableJavascriptCalls();
   3873   PrerenderTestURL(
   3874       "files/prerender/image-deferred.png",
   3875       FINAL_STATUS_USED, 1);
   3876   NavigateToDestURL();
   3877 }
   3878 
   3879 // Checks that deferred redirects in the main frame are followed, even
   3880 // with a double-redirect.
   3881 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3882                        PrerenderDeferredMainFrameAfterRedirect) {
   3883   DisableJavascriptCalls();
   3884   PrerenderTestURL(
   3885       CreateServerRedirect("files/prerender/image-deferred.png"),
   3886       FINAL_STATUS_USED, 1);
   3887   NavigateToDestURL();
   3888 }
   3889 
   3890 // Checks that deferred redirects in a synchronous XHR abort the
   3891 // prerender.
   3892 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDeferredSynchronousXHR) {
   3893   PrerenderTestURL("files/prerender/prerender_deferred_sync_xhr.html",
   3894                    FINAL_STATUS_BAD_DEFERRED_REDIRECT, 0);
   3895   NavigateToDestURL();
   3896 }
   3897 
   3898 // Checks that prerenders are not swapped for navigations with extra headers.
   3899 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderExtraHeadersNoSwap) {
   3900   PrerenderTestURL("files/prerender/prerender_page.html",
   3901                    FINAL_STATUS_APP_TERMINATING, 1);
   3902 
   3903   content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
   3904                                 content::PAGE_TRANSITION_TYPED, false);
   3905   params.extra_headers = "X-Custom-Header: 42\r\n";
   3906   NavigateToURLWithParams(params, false);
   3907 }
   3908 
   3909 // Checks that prerenders are not swapped for navigations with browser-initiated
   3910 // POST data.
   3911 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   3912                        PrerenderBrowserInitiatedPostNoSwap) {
   3913   PrerenderTestURL("files/prerender/prerender_page.html",
   3914                    FINAL_STATUS_APP_TERMINATING, 1);
   3915 
   3916   std::string post_data = "DATA";
   3917   content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
   3918                                 content::PAGE_TRANSITION_TYPED, false);
   3919   params.uses_post = true;
   3920   params.browser_initiated_post_data =
   3921       base::RefCountedString::TakeString(&post_data);
   3922   NavigateToURLWithParams(params, false);
   3923 }
   3924 
   3925 // Checks that the prerendering of a page is canceled correctly when the
   3926 // prerendered page tries to make a second navigation entry.
   3927 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderNewNavigationEntry) {
   3928   PrerenderTestURL("files/prerender/prerender_new_entry.html",
   3929                    FINAL_STATUS_NEW_NAVIGATION_ENTRY,
   3930                    1);
   3931 }
   3932 
   3933 // Attempt a swap-in in a new tab, verifying that session storage namespace
   3934 // merging works.
   3935 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTab) {
   3936   // Mock out some URLs and count the number of requests to one of them. Both
   3937   // prerender_session_storage.html and init_session_storage.html need to be
   3938   // mocked so they are same-origin.
   3939   const GURL kInitURL("http://prerender.test/init_session_storage.html");
   3940   base::FilePath init_file = GetTestPath("init_session_storage.html");
   3941   BrowserThread::PostTask(
   3942       BrowserThread::IO, FROM_HERE,
   3943       base::Bind(&CreateMockInterceptorOnIO, kInitURL, init_file));
   3944 
   3945   const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
   3946   base::FilePath test_file = GetTestPath("prerender_session_storage.html");
   3947   RequestCounter counter;
   3948   BrowserThread::PostTask(
   3949       BrowserThread::IO, FROM_HERE,
   3950       base::Bind(&CreateCountingInterceptorOnIO,
   3951                  kTestURL, test_file, counter.AsWeakPtr()));
   3952 
   3953   PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
   3954 
   3955   // Open a new tab to navigate in.
   3956   ui_test_utils::NavigateToURLWithDisposition(
   3957       current_browser(), kInitURL, NEW_FOREGROUND_TAB,
   3958       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   3959 
   3960   // Now navigate in the new tab. Set expect_swap_to_succeed to false because
   3961   // the swap does not occur synchronously.
   3962   //
   3963   // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
   3964   // return value assertion and let this go through the usual successful-swap
   3965   // codepath.
   3966   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   3967 
   3968   // Verify DidDisplayPass manually since the previous call skipped it.
   3969   EXPECT_TRUE(DidDisplayPass(
   3970       current_browser()->tab_strip_model()->GetActiveWebContents()));
   3971 
   3972   // Only one request to the test URL started.
   3973   //
   3974   // TODO(davidben): Re-enable this check when the races in attaching the
   3975   // throttle are resolved. http://crbug.com/335835
   3976   // EXPECT_EQ(1, counter.count());
   3977 }
   3978 
   3979 // Attempt a swap-in in a new tab, verifying that session storage namespace
   3980 // merging works. Unlike the above test, the swap is for a navigation that would
   3981 // normally be cross-process.
   3982 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPageNewTabCrossProcess) {
   3983   base::FilePath test_data_dir;
   3984   ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
   3985 
   3986   // Mock out some URLs and count the number of requests to one of them. Both
   3987   // prerender_session_storage.html and init_session_storage.html need to be
   3988   // mocked so they are same-origin.
   3989   const GURL kInitURL("http://prerender.test/init_session_storage.html");
   3990   base::FilePath init_file = GetTestPath("init_session_storage.html");
   3991   BrowserThread::PostTask(
   3992       BrowserThread::IO, FROM_HERE,
   3993       base::Bind(&CreateMockInterceptorOnIO, kInitURL, init_file));
   3994 
   3995   const GURL kTestURL("http://prerender.test/prerender_session_storage.html");
   3996   base::FilePath test_file = GetTestPath("prerender_session_storage.html");
   3997   RequestCounter counter;
   3998   BrowserThread::PostTask(
   3999       BrowserThread::IO, FROM_HERE,
   4000       base::Bind(&CreateCountingInterceptorOnIO,
   4001                  kTestURL, test_file, counter.AsWeakPtr()));
   4002 
   4003   PrerenderTestURL(kTestURL, FINAL_STATUS_USED, 1);
   4004 
   4005   // Open a new tab to navigate in.
   4006   ui_test_utils::NavigateToURLWithDisposition(
   4007       current_browser(), kInitURL, NEW_FOREGROUND_TAB,
   4008       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   4009 
   4010   // Navigate to about:blank so the next navigation is cross-process.
   4011   ui_test_utils::NavigateToURL(current_browser(), GURL(url::kAboutBlankURL));
   4012 
   4013   // Now navigate in the new tab. Set expect_swap_to_succeed to false because
   4014   // the swap does not occur synchronously.
   4015   //
   4016   // TODO(davidben): When all swaps become asynchronous, remove the OpenURL
   4017   // return value assertion and let this go through the usual successful-swap
   4018   // codepath.
   4019   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   4020 
   4021   // Verify DidDisplayPass manually since the previous call skipped it.
   4022   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   4023 
   4024   // Only one request to the test URL started.
   4025   //
   4026   // TODO(davidben): Re-enable this check when the races in attaching the
   4027   // throttle are resolved. http://crbug.com/335835
   4028   // EXPECT_EQ(1, counter.count());
   4029 }
   4030 
   4031 // Verify that session storage conflicts don't merge.
   4032 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderSessionStorageConflict) {
   4033   PrerenderTestURL("files/prerender/prerender_session_storage_conflict.html",
   4034                    FINAL_STATUS_APP_TERMINATING, 1);
   4035 
   4036   // Open a new tab to navigate in.
   4037   ui_test_utils::NavigateToURLWithDisposition(
   4038       current_browser(),
   4039       test_server()->GetURL("files/prerender/init_session_storage.html"),
   4040       NEW_FOREGROUND_TAB,
   4041       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   4042 
   4043   // Now navigate in the new tab.
   4044   NavigateToDestURLWithDisposition(CURRENT_TAB, false);
   4045 
   4046   // Verify DidDisplayPass in the new tab.
   4047   EXPECT_TRUE(DidDisplayPass(GetActiveWebContents()));
   4048 }
   4049 
   4050 // Checks that prerenders honor |should_replace_current_entry|.
   4051 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderReplaceCurrentEntry) {
   4052   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   4053 
   4054   content::OpenURLParams params(dest_url(), Referrer(), CURRENT_TAB,
   4055                                 content::PAGE_TRANSITION_TYPED, false);
   4056   params.should_replace_current_entry = true;
   4057   NavigateToURLWithParams(params, false);
   4058 
   4059   const NavigationController& controller =
   4060       GetActiveWebContents()->GetController();
   4061   // First entry is about:blank, second is prerender_page.html.
   4062   EXPECT_TRUE(controller.GetPendingEntry() == NULL);
   4063   EXPECT_EQ(2, controller.GetEntryCount());
   4064   EXPECT_EQ(GURL(url::kAboutBlankURL), controller.GetEntryAtIndex(0)->GetURL());
   4065   EXPECT_EQ(dest_url(), controller.GetEntryAtIndex(1)->GetURL());
   4066 }
   4067 
   4068 // Checks prerender does not hit DCHECKs and behaves properly if two pending
   4069 // swaps occur in a row.
   4070 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderDoublePendingSwap) {
   4071   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   4072   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   4073 
   4074   GURL url1 = test_server()->GetURL("files/prerender/prerender_page.html?1");
   4075   scoped_ptr<TestPrerender> prerender1 =
   4076       PrerenderTestURL(url1, FINAL_STATUS_APP_TERMINATING, 1);
   4077 
   4078   GURL url2 = test_server()->GetURL("files/prerender/prerender_page.html?2");
   4079   scoped_ptr<TestPrerender> prerender2 = ExpectPrerender(FINAL_STATUS_USED);
   4080   AddPrerender(url2, 1);
   4081   prerender2->WaitForStart();
   4082   prerender2->WaitForLoads(1);
   4083 
   4084   // There's no reason the second prerender can't be used, but the swap races
   4085   // with didStartProvisionalLoad and didFailProvisionalLoad from the previous
   4086   // navigation. The current logic will conservatively fail to swap under such
   4087   // races. However, if the renderer is slow enough, it's possible for the
   4088   // prerender to still be used, so don't program in either expectation.
   4089   ASSERT_TRUE(prerender2->contents());
   4090   prerender2->contents()->set_skip_final_checks(true);
   4091 
   4092   // Open a new tab to navigate in.
   4093   ui_test_utils::NavigateToURLWithDisposition(
   4094       current_browser(),
   4095       GURL(url::kAboutBlankURL),
   4096       NEW_FOREGROUND_TAB,
   4097       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   4098 
   4099   // Fire off two navigations, without running the event loop between them.
   4100   NavigationOrSwapObserver swap_observer(
   4101       current_browser()->tab_strip_model(),
   4102       GetActiveWebContents(), 2);
   4103   current_browser()->OpenURL(OpenURLParams(
   4104       url1, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false));
   4105   current_browser()->OpenURL(OpenURLParams(
   4106       url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false));
   4107   swap_observer.Wait();
   4108 
   4109   // The WebContents should be on url2. There may be 2 or 3 entries, depending
   4110   // on whether the first one managed to complete.
   4111   //
   4112   // TODO(davidben): When http://crbug.com/335835 is fixed, the 3 entry case
   4113   // shouldn't be possible because it's throttled by the pending swap that
   4114   // cannot complete.
   4115   const NavigationController& controller =
   4116       GetActiveWebContents()->GetController();
   4117   EXPECT_TRUE(controller.GetPendingEntry() == NULL);
   4118   EXPECT_LE(2, controller.GetEntryCount());
   4119   EXPECT_GE(3, controller.GetEntryCount());
   4120   EXPECT_EQ(GURL(url::kAboutBlankURL), controller.GetEntryAtIndex(0)->GetURL());
   4121   EXPECT_EQ(url2, controller.GetEntryAtIndex(
   4122       controller.GetEntryCount() - 1)->GetURL());
   4123 }
   4124 
   4125 // Verify that pending swaps get aborted on new navigations.
   4126 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   4127                        PrerenderPendingSwapNewNavigation) {
   4128   PrerenderManager::HangSessionStorageMergesForTesting();
   4129 
   4130   PrerenderTestURL("files/prerender/prerender_page.html",
   4131                    FINAL_STATUS_APP_TERMINATING, 1);
   4132 
   4133   // Open a new tab to navigate in.
   4134   ui_test_utils::NavigateToURLWithDisposition(
   4135       current_browser(),
   4136       GURL(url::kAboutBlankURL),
   4137       NEW_FOREGROUND_TAB,
   4138       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   4139 
   4140   // Navigate to the URL. Wait for DidStartLoading, just so it's definitely
   4141   // progressed somewhere.
   4142   content::WindowedNotificationObserver page_load_observer(
   4143       content::NOTIFICATION_LOAD_START,
   4144       content::Source<NavigationController>(
   4145           &GetActiveWebContents()->GetController()));
   4146   current_browser()->OpenURL(OpenURLParams(
   4147       dest_url(), Referrer(), CURRENT_TAB,
   4148       content::PAGE_TRANSITION_TYPED, false));
   4149   page_load_observer.Wait();
   4150 
   4151   // Navigate somewhere else. This should succeed and abort the pending swap.
   4152   TestNavigationObserver nav_observer(GetActiveWebContents());
   4153   current_browser()->OpenURL(OpenURLParams(GURL(url::kAboutBlankURL),
   4154                                            Referrer(),
   4155                                            CURRENT_TAB,
   4156                                            content::PAGE_TRANSITION_TYPED,
   4157                                            false));
   4158   nav_observer.Wait();
   4159 }
   4160 
   4161 // Checks that <a ping> requests are not dropped in prerender.
   4162 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPing) {
   4163   // Count hits to a certain URL.
   4164   const GURL kPingURL("http://prerender.test/ping");
   4165   base::FilePath empty_file = ui_test_utils::GetTestFilePath(
   4166       base::FilePath(), base::FilePath(FILE_PATH_LITERAL("empty.html")));
   4167   RequestCounter ping_counter;
   4168   BrowserThread::PostTask(
   4169       BrowserThread::IO, FROM_HERE,
   4170       base::Bind(&CreateCountingInterceptorOnIO,
   4171                  kPingURL, empty_file, ping_counter.AsWeakPtr()));
   4172 
   4173   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   4174   OpenDestURLViaClickPing(kPingURL);
   4175 
   4176   ping_counter.WaitForCount(1);
   4177 }
   4178 
   4179 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderPPLTNormalNavigation) {
   4180   UMAHistogramHelper histograms;
   4181 
   4182   GURL url = test_server()->GetURL("files/prerender/prerender_page.html");
   4183   ui_test_utils::NavigateToURL(current_browser(), url);
   4184   histograms.Fetch();
   4185   histograms.ExpectTotalCount("Prerender.none_PerceivedPLT", 1);
   4186   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatched", 0);
   4187   histograms.ExpectTotalCount("Prerender.none_PerceivedPLTMatchedComplete", 0);
   4188 }
   4189 
   4190 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   4191                        PrerenderCookieChangeConflictTest) {
   4192   NavigateStraightToURL(
   4193       "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
   4194 
   4195   GURL url = test_server()->GetURL(
   4196       "files/prerender/prerender_cookie.html?set=1&key=c&value=2");
   4197 
   4198   scoped_ptr<TestPrerender> prerender =
   4199       ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
   4200   AddPrerender(url, 1);
   4201   prerender->WaitForStart();
   4202   prerender->WaitForLoads(1);
   4203   // Ensure that in the prerendered page, querying the cookie again
   4204   // via javascript yields the same value that was set during load.
   4205   EXPECT_TRUE(DidPrerenderPass(prerender->contents()->prerender_contents()));
   4206 
   4207   // The prerender has loaded. Ensure that the change is not visible
   4208   // to visible tabs.
   4209   std::string value;
   4210   RunJSReturningString("GetCookie('c')", &value);
   4211   ASSERT_EQ(value, "1");
   4212 
   4213   // Make a conflicting cookie change, which should cancel the prerender.
   4214   RunJS("SetCookie('c', '3')");
   4215   prerender->WaitForStop();
   4216 }
   4217 
   4218 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderCookieChangeUseTest) {
   4219   // Permit 2 concurrent prerenders.
   4220   GetPrerenderManager()->mutable_config().max_link_concurrency = 2;
   4221   GetPrerenderManager()->mutable_config().max_link_concurrency_per_launcher = 2;
   4222 
   4223   // Go to a first URL setting the cookie to value "1".
   4224   NavigateStraightToURL(
   4225       "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
   4226 
   4227   // Prerender a URL setting the cookie to value "2".
   4228   GURL url = test_server()->GetURL(
   4229       "files/prerender/prerender_cookie.html?set=1&key=c&value=2");
   4230 
   4231   scoped_ptr<TestPrerender> prerender1 = ExpectPrerender(FINAL_STATUS_USED);
   4232   AddPrerender(url, 1);
   4233   prerender1->WaitForStart();
   4234   prerender1->WaitForLoads(1);
   4235 
   4236   // Launch a second prerender, setting the cookie to value "3".
   4237   scoped_ptr<TestPrerender> prerender2 =
   4238       ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
   4239   AddPrerender(test_server()->GetURL(
   4240       "files/prerender/prerender_cookie.html?set=1&key=c&value=3"), 1);
   4241   prerender2->WaitForStart();
   4242   prerender2->WaitForLoads(1);
   4243 
   4244   // Both prerenders have loaded. Ensure that the visible tab is still
   4245   // unchanged and cannot see their changes.
   4246   // to visible tabs.
   4247   std::string value;
   4248   RunJSReturningString("GetCookie('c')", &value);
   4249   ASSERT_EQ(value, "1");
   4250 
   4251   // Navigate to the prerendered URL. The first prerender should be swapped in,
   4252   // and the changes should now be visible. The second prerender should
   4253   // be cancelled due to the conflict.
   4254   ui_test_utils::NavigateToURLWithDisposition(
   4255       current_browser(),
   4256       url,
   4257       CURRENT_TAB,
   4258       ui_test_utils::BROWSER_TEST_NONE);
   4259   RunJSReturningString("GetCookie('c')", &value);
   4260   ASSERT_EQ(value, "2");
   4261   prerender2->WaitForStop();
   4262 }
   4263 
   4264 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
   4265                        PrerenderCookieChangeConflictHTTPHeaderTest) {
   4266   NavigateStraightToURL(
   4267       "files/prerender/prerender_cookie.html?set=1&key=c&value=1");
   4268 
   4269   GURL url = test_server()->GetURL("set-cookie?c=2");
   4270   scoped_ptr<TestPrerender> prerender =
   4271       ExpectPrerender(FINAL_STATUS_COOKIE_CONFLICT);
   4272   AddPrerender(url, 1);
   4273   prerender->WaitForStart();
   4274   prerender->WaitForLoads(1);
   4275 
   4276   // The prerender has loaded. Ensure that the change is not visible
   4277   // to visible tabs.
   4278   std::string value;
   4279   RunJSReturningString("GetCookie('c')", &value);
   4280   ASSERT_EQ(value, "1");
   4281 
   4282   // Make a conflicting cookie change, which should cancel the prerender.
   4283   RunJS("SetCookie('c', '3')");
   4284   prerender->WaitForStop();
   4285 }
   4286 
   4287 // Checks that a prerender which calls window.close() on itself is aborted.
   4288 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowClose) {
   4289   DisableLoadEventCheck();
   4290   PrerenderTestURL("files/prerender/prerender_window_close.html",
   4291                    FINAL_STATUS_CLOSED, 0);
   4292 }
   4293 
   4294 class PrerenderIncognitoBrowserTest : public PrerenderBrowserTest {
   4295  public:
   4296   virtual void SetUpOnMainThread() OVERRIDE {
   4297     Profile* normal_profile = current_browser()->profile();
   4298     set_browser(ui_test_utils::OpenURLOffTheRecord(
   4299         normal_profile, GURL("about:blank")));
   4300     PrerenderBrowserTest::SetUpOnMainThread();
   4301   }
   4302 };
   4303 
   4304 // Checks that prerendering works in incognito mode.
   4305 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest, PrerenderIncognito) {
   4306   PrerenderTestURL("files/prerender/prerender_page.html", FINAL_STATUS_USED, 1);
   4307   NavigateToDestURL();
   4308 }
   4309 
   4310 // Checks that prerenders are aborted when an incognito profile is closed.
   4311 IN_PROC_BROWSER_TEST_F(PrerenderIncognitoBrowserTest,
   4312                        PrerenderIncognitoClosed) {
   4313   scoped_ptr<TestPrerender> prerender =
   4314       PrerenderTestURL("files/prerender/prerender_page.html",
   4315                        FINAL_STATUS_PROFILE_DESTROYED, 1);
   4316   current_browser()->window()->Close();
   4317   prerender->WaitForStop();
   4318 }
   4319 
   4320 class PrerenderOmniboxBrowserTest : public PrerenderBrowserTest {
   4321  public:
   4322   LocationBar* GetLocationBar() {
   4323     return current_browser()->window()->GetLocationBar();
   4324   }
   4325 
   4326   OmniboxView* GetOmniboxView() {
   4327     return GetLocationBar()->GetOmniboxView();
   4328   }
   4329 
   4330   void WaitForAutocompleteDone(OmniboxView* omnibox_view) {
   4331     AutocompleteController* controller =
   4332         omnibox_view->model()->popup_model()->autocomplete_controller();
   4333     while (!controller->done()) {
   4334       content::WindowedNotificationObserver ready_observer(
   4335           chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
   4336           content::Source<AutocompleteController>(controller));
   4337       ready_observer.Wait();
   4338     }
   4339   }
   4340 
   4341   predictors::AutocompleteActionPredictor* GetAutocompleteActionPredictor() {
   4342     Profile* profile = current_browser()->profile();
   4343     return predictors::AutocompleteActionPredictorFactory::GetForProfile(
   4344         profile);
   4345   }
   4346 
   4347   scoped_ptr<TestPrerender> StartOmniboxPrerender(
   4348       const GURL& url,
   4349       FinalStatus expected_final_status) {
   4350     scoped_ptr<TestPrerender> prerender =
   4351         ExpectPrerender(expected_final_status);
   4352     WebContents* web_contents = GetActiveWebContents();
   4353     GetAutocompleteActionPredictor()->StartPrerendering(
   4354         url,
   4355         web_contents->GetController().GetSessionStorageNamespaceMap(),
   4356         gfx::Size(50, 50));
   4357     prerender->WaitForStart();
   4358     return prerender.Pass();
   4359   }
   4360 };
   4361 
   4362 // Checks that closing the omnibox popup cancels an omnibox prerender.
   4363 IN_PROC_BROWSER_TEST_F(PrerenderOmniboxBrowserTest, PrerenderOmniboxCancel) {
   4364   // Ensure the cookie store has been loaded.
   4365   if (!GetPrerenderManager()->cookie_store_loaded()) {
   4366     base::RunLoop loop;
   4367     GetPrerenderManager()->set_on_cookie_store_loaded_cb_for_testing(
   4368         loop.QuitClosure());
   4369     loop.Run();
   4370   }
   4371 
   4372   // Fake an omnibox prerender.
   4373   scoped_ptr<TestPrerender> prerender = StartOmniboxPrerender(
   4374       test_server()->GetURL("files/empty.html"),
   4375       FINAL_STATUS_CANCELLED);
   4376 
   4377   // Revert the location bar. This should cancel the prerender.
   4378   GetLocationBar()->Revert();
   4379   prerender->WaitForStop();
   4380 }
   4381 
   4382 // Checks that accepting omnibox input abandons an omnibox prerender.
   4383 IN_PROC_BROWSER_TEST_F(PrerenderOmniboxBrowserTest, PrerenderOmniboxAbandon) {
   4384   // Set the abandon timeout to something high so it does not introduce
   4385   // flakiness if the prerender times out before the test completes.
   4386   GetPrerenderManager()->mutable_config().abandon_time_to_live =
   4387       base::TimeDelta::FromDays(999);
   4388 
   4389   // Ensure the cookie store has been loaded.
   4390   if (!GetPrerenderManager()->cookie_store_loaded()) {
   4391     base::RunLoop loop;
   4392     GetPrerenderManager()->set_on_cookie_store_loaded_cb_for_testing(
   4393         loop.QuitClosure());
   4394     loop.Run();
   4395   }
   4396 
   4397   // Enter a URL into the Omnibox.
   4398   OmniboxView* omnibox_view = GetOmniboxView();
   4399   omnibox_view->OnBeforePossibleChange();
   4400   omnibox_view->SetUserText(
   4401       base::UTF8ToUTF16(test_server()->GetURL("files/empty.html?1").spec()));
   4402   omnibox_view->OnAfterPossibleChange();
   4403   WaitForAutocompleteDone(omnibox_view);
   4404 
   4405   // Fake an omnibox prerender for a different URL.
   4406   scoped_ptr<TestPrerender> prerender = StartOmniboxPrerender(
   4407       test_server()->GetURL("files/empty.html?2"),
   4408       FINAL_STATUS_APP_TERMINATING);
   4409 
   4410   // The final status may be either FINAL_STATUS_APP_TERMINATING or
   4411   // FINAL_STATUS_CANCELLED. Although closing the omnibox will not cancel an
   4412   // abandoned prerender, the AutocompleteActionPredictor will cancel the
   4413   // predictor on destruction.
   4414   prerender->contents()->set_skip_final_checks(true);
   4415 
   4416   // Navigate to the URL entered.
   4417   omnibox_view->model()->AcceptInput(CURRENT_TAB, false);
   4418 
   4419   // Prerender should be running, but abandoned.
   4420   EXPECT_TRUE(
   4421       GetAutocompleteActionPredictor()->IsPrerenderAbandonedForTesting());
   4422 }
   4423 
   4424 }  // namespace prerender
   4425