Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2011 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 "base/file_path.h"
      6 #include "base/file_util.h"
      7 #include "base/memory/ref_counted.h"
      8 #include "base/memory/scoped_temp_dir.h"
      9 #include "base/path_service.h"
     10 #include "base/test/test_file_util.h"
     11 #include "base/utf_string_conversions.h"
     12 #include "chrome/browser/browser_process.h"
     13 #include "chrome/browser/download/download_item.h"
     14 #include "chrome/browser/download/download_file_manager.h"
     15 #include "chrome/browser/download/download_manager.h"
     16 #include "chrome/browser/download/download_prefs.h"
     17 #include "chrome/browser/download/download_shelf.h"
     18 #include "chrome/browser/history/download_create_info.h"
     19 #include "chrome/browser/history/history.h"
     20 #include "chrome/browser/net/url_request_mock_http_job.h"
     21 #include "chrome/browser/net/url_request_slow_download_job.h"
     22 #include "chrome/browser/prefs/pref_service.h"
     23 #include "chrome/browser/profiles/profile.h"
     24 #include "chrome/browser/ui/browser.h"
     25 #include "chrome/browser/ui/browser_list.h"
     26 #include "chrome/browser/ui/browser_window.h"
     27 #include "chrome/common/chrome_paths.h"
     28 #include "chrome/common/pref_names.h"
     29 #include "chrome/common/url_constants.h"
     30 #include "chrome/test/in_process_browser_test.h"
     31 #include "chrome/test/ui_test_utils.h"
     32 #include "content/browser/cancelable_request.h"
     33 #include "content/browser/renderer_host/resource_dispatcher_host.h"
     34 #include "content/common/page_transition_types.h"
     35 #include "net/base/net_util.h"
     36 #include "testing/gtest/include/gtest/gtest.h"
     37 
     38 namespace {
     39 
     40 // Variation of DownloadsCompleteObserver from ui_test_utils.cc; the
     41 // specifically targeted download tests need finer granularity on waiting.
     42 // Construction of this class defines a system state, based on some number
     43 // of downloads being seen in a particular state + other events that
     44 // may occur in the download system.  That state will be recorded if it
     45 // occurs at any point after construction.  When that state occurs, the class
     46 // is considered finished.  Callers may either probe for the finished state, or
     47 // wait on it.
     48 //
     49 // TODO(rdsmith): Detect manager going down, remove pointer to
     50 // DownloadManager, transition to finished.  (For right now we
     51 // just use a scoped_refptr<> to keep it around, but that may cause
     52 // timeouts on waiting if a DownloadManager::Shutdown() occurs which
     53 // cancels our in-progress downloads.)
     54 class DownloadsObserver : public DownloadManager::Observer,
     55                           public DownloadItem::Observer {
     56  public:
     57   // Create an object that will be considered finished when |wait_count|
     58   // download items have entered state |download_finished_state|.
     59   // If |finish_on_select_file| is true, the object will also be
     60   // considered finished if the DownloadManager raises a
     61   // SelectFileDialogDisplayed() notification.
     62 
     63   // TODO(rdsmith): Add option of "dangerous accept/reject dialog" as
     64   // a unblocking event; if that shows up when you aren't expecting it,
     65   // it'll result in a hang/timeout as we'll never get to final rename.
     66   // This probably means rewriting the interface to take a list of events
     67   // to treat as completion events.
     68   DownloadsObserver(DownloadManager* download_manager,
     69                     size_t wait_count,
     70                     DownloadItem::DownloadState download_finished_state,
     71                     bool finish_on_select_file)
     72       : download_manager_(download_manager),
     73         wait_count_(wait_count),
     74         finished_downloads_at_construction_(0),
     75         waiting_(false),
     76         download_finished_state_(download_finished_state),
     77         finish_on_select_file_(finish_on_select_file),
     78         select_file_dialog_seen_(false) {
     79     download_manager_->AddObserver(this);  // Will call initial ModelChanged().
     80     finished_downloads_at_construction_ = finished_downloads_.size();
     81   }
     82 
     83   ~DownloadsObserver() {
     84     std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
     85     for (; it != downloads_observed_.end(); ++it) {
     86       (*it)->RemoveObserver(this);
     87     }
     88     download_manager_->RemoveObserver(this);
     89   }
     90 
     91   // State accessors.
     92   bool select_file_dialog_seen() { return select_file_dialog_seen_; }
     93 
     94   // Wait for whatever state was specified in the constructor.
     95   void WaitForFinished() {
     96     if (!IsFinished()) {
     97       waiting_ = true;
     98       ui_test_utils::RunMessageLoop();
     99       waiting_ = false;
    100     }
    101   }
    102 
    103   // Return true if everything's happened that we're configured for.
    104   bool IsFinished() {
    105     if (finished_downloads_.size() - finished_downloads_at_construction_
    106         >= wait_count_)
    107       return true;
    108     return (finish_on_select_file_ && select_file_dialog_seen_);
    109   }
    110 
    111   // DownloadItem::Observer
    112   virtual void OnDownloadUpdated(DownloadItem* download) {
    113     if (download->state() == download_finished_state_)
    114       DownloadInFinalState(download);
    115   }
    116 
    117   virtual void OnDownloadOpened(DownloadItem* download) {}
    118 
    119   // DownloadManager::Observer
    120   virtual void ModelChanged() {
    121     // Regenerate DownloadItem observers.  If there are any download items
    122     // in our final state, note them in |finished_downloads_|
    123     // (done by |OnDownloadUpdated()|).
    124     std::vector<DownloadItem*> downloads;
    125     download_manager_->SearchDownloads(string16(), &downloads);
    126 
    127     std::vector<DownloadItem*>::iterator it = downloads.begin();
    128     for (; it != downloads.end(); ++it) {
    129       OnDownloadUpdated(*it);  // Safe to call multiple times; checks state.
    130 
    131       std::set<DownloadItem*>::const_iterator
    132           finished_it(finished_downloads_.find(*it));
    133       std::set<DownloadItem*>::iterator
    134           observed_it(downloads_observed_.find(*it));
    135 
    136       // If it isn't finished and we're aren't observing it, start.
    137       if (finished_it == finished_downloads_.end() &&
    138           observed_it == downloads_observed_.end()) {
    139         (*it)->AddObserver(this);
    140         downloads_observed_.insert(*it);
    141         continue;
    142       }
    143 
    144       // If it is finished and we are observing it, stop.
    145       if (finished_it != finished_downloads_.end() &&
    146           observed_it != downloads_observed_.end()) {
    147         (*it)->RemoveObserver(this);
    148         downloads_observed_.erase(observed_it);
    149         continue;
    150       }
    151     }
    152   }
    153 
    154   virtual void SelectFileDialogDisplayed(int32 /* id */) {
    155     select_file_dialog_seen_ = true;
    156     SignalIfFinished();
    157   }
    158 
    159  private:
    160   // Called when we know that a download item is in a final state.
    161   // Note that this is not the same as it first transitioning in to the
    162   // final state; multiple notifications may occur once the item is in
    163   // that state.  So we keep our own track of transitions into final.
    164   void DownloadInFinalState(DownloadItem* download) {
    165     if (finished_downloads_.find(download) != finished_downloads_.end()) {
    166       // We've already seen terminal state on this download.
    167       return;
    168     }
    169 
    170     // Record the transition.
    171     finished_downloads_.insert(download);
    172 
    173     SignalIfFinished();
    174   }
    175 
    176   void SignalIfFinished() {
    177     if (waiting_ && IsFinished())
    178       MessageLoopForUI::current()->Quit();
    179   }
    180 
    181   // The observed download manager.
    182   scoped_refptr<DownloadManager> download_manager_;
    183 
    184   // The set of DownloadItem's that have transitioned to their finished state
    185   // since construction of this object.  When the size of this array
    186   // reaches wait_count_, we're done.
    187   std::set<DownloadItem*> finished_downloads_;
    188 
    189   // The set of DownloadItem's we are currently observing.  Generally there
    190   // won't be any overlap with the above; once we see the final state
    191   // on a DownloadItem, we'll stop observing it.
    192   std::set<DownloadItem*> downloads_observed_;
    193 
    194   // The number of downloads to wait on completing.
    195   size_t wait_count_;
    196 
    197   // The number of downloads entered in final state in initial
    198   // ModelChanged().  We use |finished_downloads_| to track the incoming
    199   // transitions to final state we should ignore, and to track the
    200   // number of final state transitions that occurred between
    201   // construction and return from wait.  But some downloads may be in our
    202   // final state (and thus be entered into |finished_downloads_|) when we
    203   // construct this class.  We don't want to count those in our transition
    204   // to finished.
    205   int finished_downloads_at_construction_;
    206 
    207   // Whether an internal message loop has been started and must be quit upon
    208   // all downloads completing.
    209   bool waiting_;
    210 
    211   // The state on which to consider the DownloadItem finished.
    212   DownloadItem::DownloadState download_finished_state_;
    213 
    214   // True if we should transition the DownloadsObserver to finished if
    215   // the select file dialog comes up.
    216   bool finish_on_select_file_;
    217 
    218   // True if we've seen the select file dialog.
    219   bool select_file_dialog_seen_;
    220 
    221   DISALLOW_COPY_AND_ASSIGN(DownloadsObserver);
    222 };
    223 
    224 // WaitForFlush() returns after:
    225 //      * There are no IN_PROGRESS download items remaining on the
    226 //        DownloadManager.
    227 //      * There have been two round trip messages through the file and
    228 //        IO threads.
    229 // This almost certainly means that a Download cancel has propagated through
    230 // the system.
    231 class DownloadsFlushObserver
    232     : public DownloadManager::Observer,
    233       public DownloadItem::Observer,
    234       public base::RefCountedThreadSafe<DownloadsFlushObserver> {
    235  public:
    236   explicit DownloadsFlushObserver(DownloadManager* download_manager)
    237       : download_manager_(download_manager),
    238         waiting_for_zero_inprogress_(true) { }
    239 
    240   void WaitForFlush() {
    241     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    242     download_manager_->AddObserver(this);
    243     ui_test_utils::RunMessageLoop();
    244   }
    245 
    246   // DownloadsManager observer methods.
    247   virtual void ModelChanged() {
    248     // Model has changed, so there may be more DownloadItems to observe.
    249     CheckDownloadsInProgress(true);
    250   }
    251 
    252   // DownloadItem observer methods.
    253   virtual void OnDownloadUpdated(DownloadItem* download) {
    254     // No change in DownloadItem set on manager.
    255     CheckDownloadsInProgress(false);
    256   }
    257   virtual void OnDownloadOpened(DownloadItem* download) {}
    258 
    259  protected:
    260   friend class base::RefCountedThreadSafe<DownloadsFlushObserver>;
    261 
    262   virtual ~DownloadsFlushObserver() {
    263     download_manager_->RemoveObserver(this);
    264     for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
    265          it != downloads_observed_.end(); ++it) {
    266       (*it)->RemoveObserver(this);
    267     }
    268   }
    269 
    270  private:
    271   // If we're waiting for that flush point, check the number
    272   // of downloads in the IN_PROGRESS state and take appropriate
    273   // action.  If requested, also observes all downloads while iterating.
    274   void CheckDownloadsInProgress(bool observe_downloads) {
    275     if (waiting_for_zero_inprogress_) {
    276       int count = 0;
    277 
    278       std::vector<DownloadItem*> downloads;
    279       download_manager_->SearchDownloads(string16(), &downloads);
    280       std::vector<DownloadItem*>::iterator it = downloads.begin();
    281       for (; it != downloads.end(); ++it) {
    282         if ((*it)->state() == DownloadItem::IN_PROGRESS)
    283           count++;
    284         if (observe_downloads) {
    285           if (downloads_observed_.find(*it) == downloads_observed_.end()) {
    286             (*it)->AddObserver(this);
    287           }
    288           // Download items are forever, and we don't want to make
    289           // assumptions about future state transitions, so once we
    290           // start observing them, we don't stop until destruction.
    291         }
    292       }
    293 
    294       if (count == 0) {
    295         waiting_for_zero_inprogress_ = false;
    296         // Stop observing DownloadItems.  We maintain the observation
    297         // of DownloadManager so that we don't have to independently track
    298         // whether we are observing it for conditional destruction.
    299         for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
    300              it != downloads_observed_.end(); ++it) {
    301           (*it)->RemoveObserver(this);
    302         }
    303         downloads_observed_.clear();
    304 
    305         // Trigger next step.  We need to go past the IO thread twice, as
    306         // there's a self-task posting in the IO thread cancel path.
    307         BrowserThread::PostTask(
    308             BrowserThread::FILE, FROM_HERE,
    309             NewRunnableMethod(this,
    310                               &DownloadsFlushObserver::PingFileThread, 2));
    311       }
    312     }
    313   }
    314 
    315   void PingFileThread(int cycle) {
    316     BrowserThread::PostTask(
    317         BrowserThread::IO, FROM_HERE,
    318         NewRunnableMethod(this, &DownloadsFlushObserver::PingIOThread,
    319                           cycle));
    320   }
    321 
    322   void PingIOThread(int cycle) {
    323     if (--cycle) {
    324       BrowserThread::PostTask(
    325           BrowserThread::UI, FROM_HERE,
    326           NewRunnableMethod(this, &DownloadsFlushObserver::PingFileThread,
    327                             cycle));
    328     } else {
    329       BrowserThread::PostTask(
    330           BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
    331     }
    332   }
    333 
    334   DownloadManager* download_manager_;
    335   std::set<DownloadItem*> downloads_observed_;
    336   bool waiting_for_zero_inprogress_;
    337 
    338   DISALLOW_COPY_AND_ASSIGN(DownloadsFlushObserver);
    339 };
    340 
    341 // Collect the information from FILE and IO threads needed for the Cancel
    342 // Test, specifically the number of outstanding requests on the
    343 // ResourceDispatcherHost and the number of pending downloads on the
    344 // DownloadFileManager.
    345 class CancelTestDataCollector
    346     : public base::RefCountedThreadSafe<CancelTestDataCollector> {
    347  public:
    348   CancelTestDataCollector()
    349       : resource_dispatcher_host_(
    350           g_browser_process->resource_dispatcher_host()),
    351         rdh_pending_requests_(0),
    352         dfm_pending_downloads_(0) { }
    353 
    354   void WaitForDataCollected() {
    355     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    356     BrowserThread::PostTask(
    357         BrowserThread::IO, FROM_HERE,
    358         NewRunnableMethod(this, &CancelTestDataCollector::IOInfoCollector));
    359     ui_test_utils::RunMessageLoop();
    360   }
    361 
    362   int rdh_pending_requests() { return rdh_pending_requests_; }
    363   int dfm_pending_downloads() { return dfm_pending_downloads_; }
    364 
    365  protected:
    366   friend class base::RefCountedThreadSafe<CancelTestDataCollector>;
    367 
    368   virtual ~CancelTestDataCollector() {}
    369 
    370  private:
    371 
    372   void IOInfoCollector() {
    373     download_file_manager_ = resource_dispatcher_host_->download_file_manager();
    374     rdh_pending_requests_ = resource_dispatcher_host_->pending_requests();
    375     BrowserThread::PostTask(
    376         BrowserThread::FILE, FROM_HERE,
    377         NewRunnableMethod(this, &CancelTestDataCollector::FileInfoCollector));
    378   }
    379 
    380   void FileInfoCollector() {
    381     dfm_pending_downloads_ = download_file_manager_->NumberOfActiveDownloads();
    382     BrowserThread::PostTask(
    383         BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
    384   }
    385 
    386   ResourceDispatcherHost* resource_dispatcher_host_;
    387   DownloadFileManager* download_file_manager_;
    388   int rdh_pending_requests_;
    389   int dfm_pending_downloads_;
    390 
    391   DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector);
    392 };
    393 
    394 }  // namespace
    395 
    396 class DownloadTest : public InProcessBrowserTest {
    397  public:
    398   enum SelectExpectation {
    399     EXPECT_NO_SELECT_DIALOG = -1,
    400     EXPECT_NOTHING,
    401     EXPECT_SELECT_DIALOG
    402   };
    403 
    404   // Returning false indicates a failure of the setup, and should be asserted
    405   // in the caller.
    406   virtual bool InitialSetup(bool prompt_for_download) {
    407     bool have_test_dir = PathService::Get(chrome::DIR_TEST_DATA, &test_dir_);
    408     EXPECT_TRUE(have_test_dir);
    409     if (!have_test_dir)
    410       return false;
    411 
    412     // Sanity check default values for window / tab count and shelf visibility.
    413     int window_count = BrowserList::size();
    414     EXPECT_EQ(1, window_count);
    415     EXPECT_EQ(1, browser()->tab_count());
    416     bool is_shelf_visible = browser()->window()->IsDownloadShelfVisible();
    417     EXPECT_FALSE(is_shelf_visible);
    418 
    419     // Set up the temporary download folder.
    420     bool created_downloads_dir = CreateAndSetDownloadsDirectory(browser());
    421     EXPECT_TRUE(created_downloads_dir);
    422     if (!created_downloads_dir)
    423       return false;
    424     browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
    425                                                  prompt_for_download);
    426 
    427     return true;
    428   }
    429 
    430  protected:
    431 
    432   enum SizeTestType {
    433     SIZE_TEST_TYPE_KNOWN,
    434     SIZE_TEST_TYPE_UNKNOWN,
    435   };
    436 
    437   // Location of the file source (the place from which it is downloaded).
    438   FilePath OriginFile(FilePath file) {
    439     return test_dir_.Append(file);
    440   }
    441 
    442   // Location of the file destination (place to which it is downloaded).
    443   FilePath DestinationFile(Browser* browser, FilePath file) {
    444     return GetDownloadDirectory(browser).Append(file);
    445   }
    446 
    447   // Must be called after browser creation.  Creates a temporary
    448   // directory for downloads that is auto-deleted on destruction.
    449   // Returning false indicates a failure of the function, and should be asserted
    450   // in the caller.
    451   bool CreateAndSetDownloadsDirectory(Browser* browser) {
    452     if (!browser)
    453       return false;
    454 
    455     if (!downloads_directory_.CreateUniqueTempDir())
    456       return false;
    457 
    458     browser->profile()->GetPrefs()->SetFilePath(
    459         prefs::kDownloadDefaultDirectory,
    460         downloads_directory_.path());
    461 
    462     return true;
    463   }
    464 
    465   FilePath GetDownloadDirectory(Browser* browser) {
    466     DownloadManager* download_mananger =
    467         browser->profile()->GetDownloadManager();
    468     return download_mananger->download_prefs()->download_path();
    469   }
    470 
    471   // Create a DownloadsObserver that will wait for the
    472   // specified number of downloads to finish.
    473   DownloadsObserver* CreateWaiter(Browser* browser, int num_downloads) {
    474     DownloadManager* download_manager =
    475         browser->profile()->GetDownloadManager();
    476     return new DownloadsObserver(
    477         download_manager, num_downloads,
    478         DownloadItem::COMPLETE,          // Really done
    479         true);                           // Bail on select file
    480   }
    481 
    482   // Create a DownloadsObserver that will wait for the
    483   // specified number of downloads to start.
    484   DownloadsObserver* CreateInProgressWaiter(Browser* browser,
    485                                             int num_downloads) {
    486     DownloadManager* download_manager =
    487         browser->profile()->GetDownloadManager();
    488     return new DownloadsObserver(
    489         download_manager, num_downloads,
    490         DownloadItem::IN_PROGRESS,      // Has started
    491         true);                          // Bail on select file
    492   }
    493 
    494   // Download |url|, then wait for the download to finish.
    495   // |disposition| indicates where the navigation occurs (current tab, new
    496   // foreground tab, etc).
    497   // |expectation| indicates whether or not a Select File dialog should be
    498   // open when the download is finished, or if we don't care.
    499   // If the dialog appears, the routine exits.  The only effect |expectation|
    500   // has is whether or not the test succeeds.
    501   // |browser_test_flags| indicate what to wait for, and is an OR of 0 or more
    502   // values in the ui_test_utils::BrowserTestWaitFlags enum.
    503   void DownloadAndWaitWithDisposition(Browser* browser,
    504                                       const GURL& url,
    505                                       WindowOpenDisposition disposition,
    506                                       SelectExpectation expectation,
    507                                       int browser_test_flags) {
    508     // Setup notification, navigate, and block.
    509     scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1));
    510     // This call will block until the condition specified by
    511     // |browser_test_flags|, but will not wait for the download to finish.
    512     ui_test_utils::NavigateToURLWithDisposition(browser,
    513                                                 url,
    514                                                 disposition,
    515                                                 browser_test_flags);
    516     // Waits for the download to complete.
    517     observer->WaitForFinished();
    518 
    519     // If specified, check the state of the select file dialog.
    520     if (expectation != EXPECT_NOTHING) {
    521       EXPECT_EQ(expectation == EXPECT_SELECT_DIALOG,
    522                 observer->select_file_dialog_seen());
    523     }
    524   }
    525 
    526   // Download a file in the current tab, then wait for the download to finish.
    527   void DownloadAndWait(Browser* browser,
    528                        const GURL& url,
    529                        SelectExpectation expectation) {
    530     DownloadAndWaitWithDisposition(
    531         browser,
    532         url,
    533         CURRENT_TAB,
    534         expectation,
    535         ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    536   }
    537 
    538   // Should only be called when the download is known to have finished
    539   // (in error or not).
    540   // Returning false indicates a failure of the function, and should be asserted
    541   // in the caller.
    542   bool CheckDownload(Browser* browser,
    543                      const FilePath& downloaded_filename,
    544                      const FilePath& origin_filename) {
    545     // Find the path to which the data will be downloaded.
    546     FilePath downloaded_file(DestinationFile(browser, downloaded_filename));
    547 
    548     // Find the origin path (from which the data comes).
    549     FilePath origin_file(OriginFile(origin_filename));
    550     bool origin_file_exists = file_util::PathExists(origin_file);
    551     EXPECT_TRUE(origin_file_exists);
    552     if (!origin_file_exists)
    553       return false;
    554 
    555     // Confirm the downloaded data file exists.
    556     bool downloaded_file_exists = file_util::PathExists(downloaded_file);
    557     EXPECT_TRUE(downloaded_file_exists);
    558     if (!downloaded_file_exists)
    559       return false;
    560 
    561     int64 origin_file_size = 0;
    562     int64 downloaded_file_size = 0;
    563     EXPECT_TRUE(file_util::GetFileSize(origin_file, &origin_file_size));
    564     EXPECT_TRUE(file_util::GetFileSize(downloaded_file, &downloaded_file_size));
    565     EXPECT_EQ(origin_file_size, downloaded_file_size);
    566     EXPECT_TRUE(file_util::ContentsEqual(downloaded_file, origin_file));
    567 
    568     // Delete the downloaded copy of the file.
    569     bool downloaded_file_deleted =
    570         file_util::DieFileDie(downloaded_file, false);
    571     EXPECT_TRUE(downloaded_file_deleted);
    572     return downloaded_file_deleted;
    573   }
    574 
    575   bool RunSizeTest(Browser* browser,
    576                    SizeTestType type,
    577                    const std::string& partial_indication,
    578                    const std::string& total_indication) {
    579     if (!InitialSetup(false))
    580       return false;
    581 
    582     EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN);
    583     if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN)
    584       return false;
    585     GURL url(type == SIZE_TEST_TYPE_KNOWN ?
    586              URLRequestSlowDownloadJob::kKnownSizeUrl :
    587              URLRequestSlowDownloadJob::kUnknownSizeUrl);
    588 
    589   // TODO(ahendrickson) -- |expected_title_in_progress| and
    590   // |expected_title_finished| need to be checked.
    591     FilePath filename;
    592     net::FileURLToFilePath(url, &filename);
    593     string16 expected_title_in_progress(
    594         ASCIIToUTF16(partial_indication) + filename.LossyDisplayName());
    595     string16 expected_title_finished(
    596         ASCIIToUTF16(total_indication) + filename.LossyDisplayName());
    597 
    598     // Download a partial web page in a background tab and wait.
    599     // The mock system will not complete until it gets a special URL.
    600     scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1));
    601     ui_test_utils::NavigateToURL(browser, url);
    602 
    603     // TODO(ahendrickson): check download status text before downloading.
    604     // Need to:
    605     //  - Add a member function to the |DownloadShelf| interface class, that
    606     //    indicates how many members it has.
    607     //  - Add a member function to |DownloadShelf| to get the status text
    608     //    of a given member (for example, via the name in |DownloadItemView|'s
    609     //    GetAccessibleState() member function), by index.
    610     //  - Iterate over browser->window()->GetDownloadShelf()'s members
    611     //    to see if any match the status text we want.  Start with the last one.
    612 
    613     // Allow the request to finish.  We do this by loading a second URL in a
    614     // separate tab.
    615     GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
    616     ui_test_utils::NavigateToURLWithDisposition(
    617         browser,
    618         finish_url,
    619         NEW_FOREGROUND_TAB,
    620         ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    621     observer->WaitForFinished();
    622 
    623     EXPECT_EQ(2, browser->tab_count());
    624 
    625     // TODO(ahendrickson): check download status text after downloading.
    626 
    627     // Make sure the download shelf is showing.
    628     EXPECT_TRUE(IsDownloadUIVisible(browser));
    629 
    630     FilePath basefilename(filename.BaseName());
    631     net::FileURLToFilePath(url, &filename);
    632     FilePath download_path = downloads_directory_.path().Append(basefilename);
    633 
    634     bool downloaded_path_exists = file_util::PathExists(download_path);
    635     EXPECT_TRUE(downloaded_path_exists);
    636     if (!downloaded_path_exists)
    637       return false;
    638 
    639     // Delete the file we just downloaded.
    640     EXPECT_TRUE(file_util::DieFileDie(download_path, true));
    641     EXPECT_FALSE(file_util::PathExists(download_path));
    642 
    643     return true;
    644   }
    645 
    646   void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) {
    647     DCHECK(downloads);
    648     DownloadManager* manager = browser->profile()->GetDownloadManager();
    649     manager->SearchDownloads(string16(), downloads);
    650   }
    651 
    652   // Figure out if the appropriate download visibility was done.  A
    653   // utility function to support ChromeOS variations.  On ChromeOS
    654   // a webui panel is used instead of the download shelf; the
    655   // test for TYPE_APP_PANEL detects this type of panel.
    656   static bool IsDownloadUIVisible(Browser* browser) {
    657 #if defined(OS_CHROMEOS)
    658     for (BrowserList::const_iterator it = BrowserList::begin();
    659          it != BrowserList::end(); ++it) {
    660       if ((*it)->type() == Browser::TYPE_APP_PANEL) {
    661         return true;
    662       }
    663     }
    664     return false;
    665 #else
    666     return browser->window()->IsDownloadShelfVisible();
    667 #endif
    668   }
    669 
    670   static void ExpectWindowCountAfterDownload(size_t expected) {
    671 #if defined(OS_CHROMEOS)
    672     // On ChromeOS, a download panel is created to display
    673     // download information, and this counts as a window.
    674     expected++;
    675 #endif
    676     EXPECT_EQ(expected, BrowserList::size());
    677   }
    678 
    679  private:
    680   // Location of the test data.
    681   FilePath test_dir_;
    682 
    683   // Location of the downloads directory for these tests
    684   ScopedTempDir downloads_directory_;
    685 };
    686 
    687 // Get History Information.
    688 class DownloadsHistoryDataCollector {
    689  public:
    690   explicit DownloadsHistoryDataCollector(int64 download_db_handle,
    691                                          DownloadManager* manager)
    692       : result_valid_(false),
    693         download_db_handle_(download_db_handle) {
    694     HistoryService* hs =
    695         manager->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
    696     DCHECK(hs);
    697     hs->QueryDownloads(
    698         &callback_consumer_,
    699         NewCallback(this,
    700                     &DownloadsHistoryDataCollector::OnQueryDownloadsComplete));
    701 
    702     // Cannot complete immediately because the history backend runs on a
    703     // separate thread, so we can assume that the RunMessageLoop below will
    704     // be exited by the Quit in OnQueryDownloadsComplete.
    705     ui_test_utils::RunMessageLoop();
    706   }
    707 
    708   bool GetDownloadsHistoryEntry(DownloadCreateInfo* result) {
    709     DCHECK(result);
    710     *result = result_;
    711     return result_valid_;
    712   }
    713 
    714  private:
    715   void OnQueryDownloadsComplete(
    716       std::vector<DownloadCreateInfo>* entries) {
    717     result_valid_ = false;
    718     for (std::vector<DownloadCreateInfo>::const_iterator it = entries->begin();
    719          it != entries->end(); ++it) {
    720       if (it->db_handle == download_db_handle_) {
    721         result_ = *it;
    722         result_valid_ = true;
    723       }
    724     }
    725     MessageLoopForUI::current()->Quit();
    726   }
    727 
    728   DownloadCreateInfo result_;
    729   bool result_valid_;
    730   int64 download_db_handle_;
    731   CancelableRequestConsumer callback_consumer_;
    732 
    733   DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector);
    734 };
    735 
    736 // NOTES:
    737 //
    738 // Files for these tests are found in DIR_TEST_DATA (currently
    739 // "chrome\test\data\", see chrome_paths.cc).
    740 // Mock responses have extension .mock-http-headers appended to the file name.
    741 
    742 // Download a file due to the associated MIME type.
    743 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) {
    744   ASSERT_TRUE(InitialSetup(false));
    745   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
    746   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    747 
    748   // Download the file and wait.  We do not expect the Select File dialog.
    749   DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
    750 
    751   // Check state.
    752   EXPECT_EQ(1, browser()->tab_count());
    753   CheckDownload(browser(), file, file);
    754   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    755 }
    756 
    757 #if defined(OS_WIN)
    758 // Download a file and confirm that the zone identifier (on windows)
    759 // is set to internet.
    760 IN_PROC_BROWSER_TEST_F(DownloadTest, CheckInternetZone) {
    761   ASSERT_TRUE(InitialSetup(false));
    762   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
    763   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    764 
    765   // Download the file and wait.  We do not expect the Select File dialog.
    766   DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
    767 
    768   // Check state.  Special file state must be checked before CheckDownload,
    769   // as CheckDownload will delete the output file.
    770   EXPECT_EQ(1, browser()->tab_count());
    771   FilePath downloaded_file(DestinationFile(browser(), file));
    772   if (file_util::VolumeSupportsADS(downloaded_file))
    773     EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file));
    774   CheckDownload(browser(), file, file);
    775   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    776 }
    777 #endif
    778 
    779 // Put up a Select File dialog when the file is downloaded, due to its MIME
    780 // type.
    781 //
    782 // This test runs correctly, but leaves behind turds in the test user's
    783 // download directory because of http://crbug.com/62099.  No big loss; it
    784 // was primarily confirming DownloadsObserver wait on select file dialog
    785 // functionality anyway.
    786 IN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) {
    787   ASSERT_TRUE(InitialSetup(true));
    788   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
    789   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    790 
    791   // Download the file and wait.  We expect the Select File dialog to appear
    792   // due to the MIME type.
    793   DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
    794 
    795   // Check state.
    796   EXPECT_EQ(1, browser()->tab_count());
    797   // Since we exited while the Select File dialog was visible, there should not
    798   // be anything in the download shelf and so it should not be visible.
    799   EXPECT_FALSE(IsDownloadUIVisible(browser()));
    800 }
    801 
    802 // Access a file with a viewable mime-type, verify that a download
    803 // did not initiate.
    804 IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) {
    805   ASSERT_TRUE(InitialSetup(false));
    806   FilePath file(FILE_PATH_LITERAL("download-test2.html"));
    807   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    808   FilePath file_path(DestinationFile(browser(), file));
    809 
    810   // Open a web page and wait.
    811   ui_test_utils::NavigateToURL(browser(), url);
    812 
    813   // Check that we did not download the web page.
    814   EXPECT_FALSE(file_util::PathExists(file_path));
    815 
    816   // Check state.
    817   EXPECT_EQ(1, browser()->tab_count());
    818   EXPECT_FALSE(IsDownloadUIVisible(browser()));
    819 }
    820 
    821 // Download a 0-size file with a content-disposition header, verify that the
    822 // download tab opened and the file exists as the filename specified in the
    823 // header.  This also ensures we properly handle empty file downloads.
    824 // The download shelf should be visible in the current tab.
    825 IN_PROC_BROWSER_TEST_F(DownloadTest, ContentDisposition) {
    826   ASSERT_TRUE(InitialSetup(false));
    827   FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
    828   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    829   FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));
    830 
    831   // Download a file and wait.
    832   DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
    833 
    834   CheckDownload(browser(), download_file, file);
    835 
    836   // Check state.
    837   EXPECT_EQ(1, browser()->tab_count());
    838   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    839 }
    840 
    841 #if !defined(OS_CHROMEOS)  // Download shelf is not per-window on ChromeOS.
    842 // Test that the download shelf is per-window by starting a download in one
    843 // tab, opening a second tab, closing the shelf, going back to the first tab,
    844 // and checking that the shelf is closed.
    845 IN_PROC_BROWSER_TEST_F(DownloadTest, PerWindowShelf) {
    846   ASSERT_TRUE(InitialSetup(false));
    847   FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
    848   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    849   FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));
    850 
    851   // Download a file and wait.
    852   DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
    853 
    854   CheckDownload(browser(), download_file, file);
    855 
    856   // Check state.
    857   EXPECT_EQ(1, browser()->tab_count());
    858   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    859 
    860   // Open a second tab and wait.
    861   EXPECT_NE(static_cast<TabContentsWrapper*>(NULL),
    862             browser()->AddSelectedTabWithURL(GURL(), PageTransition::TYPED));
    863   EXPECT_EQ(2, browser()->tab_count());
    864   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    865 
    866   // Hide the download shelf.
    867   browser()->window()->GetDownloadShelf()->Close();
    868   EXPECT_FALSE(IsDownloadUIVisible(browser()));
    869 
    870   // Go to the first tab.
    871   browser()->ActivateTabAt(0, true);
    872   EXPECT_EQ(2, browser()->tab_count());
    873 
    874   // The download shelf should not be visible.
    875   EXPECT_FALSE(IsDownloadUIVisible(browser()));
    876 }
    877 #endif  // !OS_CHROMEOS
    878 
    879 // UnknownSize and KnownSize are tests which depend on
    880 // URLRequestSlowDownloadJob to serve content in a certain way. Data will be
    881 // sent in two chunks where the first chunk is 35K and the second chunk is 10K.
    882 // The test will first attempt to download a file; but the server will "pause"
    883 // in the middle until the server receives a second request for
    884 // "download-finish".  At that time, the download will finish.
    885 // These tests don't currently test much due to holes in |RunSizeTest()|.  See
    886 // comments in that routine for details.
    887 IN_PROC_BROWSER_TEST_F(DownloadTest, UnknownSize) {
    888   ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_UNKNOWN,
    889                           "32.0 KB - ", "100% - "));
    890 }
    891 
    892 IN_PROC_BROWSER_TEST_F(DownloadTest, KnownSize) {
    893   ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_KNOWN,
    894                           "71% - ", "100% - "));
    895 }
    896 
    897 // Test that when downloading an item in Incognito mode, we don't crash when
    898 // closing the last Incognito window (http://crbug.com/13983).
    899 // Also check that the download shelf is not visible after closing the
    900 // Incognito window.
    901 IN_PROC_BROWSER_TEST_F(DownloadTest, IncognitoDownload) {
    902   ASSERT_TRUE(InitialSetup(false));
    903 
    904   // Open an Incognito window.
    905   Browser* incognito = CreateIncognitoBrowser();  // Waits.
    906   ASSERT_TRUE(incognito);
    907   int window_count = BrowserList::size();
    908   EXPECT_EQ(2, window_count);
    909 
    910   // Download a file in the Incognito window and wait.
    911   CreateAndSetDownloadsDirectory(incognito);
    912   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
    913   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    914   // Since |incognito| is a separate browser, we have to set it up explicitly.
    915   incognito->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
    916                                                false);
    917   DownloadAndWait(incognito, url, EXPECT_NO_SELECT_DIALOG);
    918 
    919   // We should still have 2 windows.
    920   ExpectWindowCountAfterDownload(2);
    921 
    922   // Verify that the download shelf is showing for the Incognito window.
    923   bool is_shelf_visible = IsDownloadUIVisible(incognito);
    924   EXPECT_TRUE(is_shelf_visible);
    925 
    926   // Close the Incognito window and don't crash.
    927   incognito->CloseWindow();
    928 #if !defined(OS_MACOSX)
    929   // On Mac OS X, the UI window close is delayed until the outermost
    930   // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
    931   // notification inside of a test.
    932   ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED,
    933                                          Source<Browser>(incognito));
    934 
    935   ExpectWindowCountAfterDownload(1);
    936 #endif
    937 
    938   // Verify that the regular window does not have a download shelf.
    939   is_shelf_visible = IsDownloadUIVisible(browser());
    940 
    941 #if defined(OS_CHROMEOS)
    942   // On ChromeOS it's a popup rather than a download shelf, and it sticks
    943   // around.
    944   EXPECT_TRUE(is_shelf_visible);
    945 #else
    946   EXPECT_FALSE(is_shelf_visible);
    947 #endif
    948 
    949   CheckDownload(browser(), file, file);
    950 }
    951 
    952 // Navigate to a new background page, but don't download.  Confirm that the
    953 // download shelf is not visible and that we have two tabs.
    954 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab1) {
    955   ASSERT_TRUE(InitialSetup(false));
    956   // Because it's an HTML link, it should open a web page rather than
    957   // downloading.
    958   FilePath file1(FILE_PATH_LITERAL("download-test2.html"));
    959   GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
    960 
    961   // Open a web page and wait.
    962   ui_test_utils::NavigateToURLWithDisposition(
    963       browser(),
    964       url,
    965       NEW_BACKGROUND_TAB,
    966       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    967 
    968   // We should have two tabs now.
    969   EXPECT_EQ(2, browser()->tab_count());
    970   EXPECT_FALSE(IsDownloadUIVisible(browser()));
    971 }
    972 
    973 // Download a file in a background tab. Verify that the tab is closed
    974 // automatically, and that the download shelf is visible in the current tab.
    975 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab1) {
    976   ASSERT_TRUE(InitialSetup(false));
    977 
    978   // Download a file in a new background tab and wait.  The tab is automatically
    979   // closed when the download begins.
    980   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
    981   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
    982   DownloadAndWaitWithDisposition(
    983       browser(),
    984       url,
    985       NEW_BACKGROUND_TAB,
    986       EXPECT_NO_SELECT_DIALOG,
    987       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    988 
    989   // When the download finishes, we should still have one tab.
    990   EXPECT_TRUE(IsDownloadUIVisible(browser()));
    991   EXPECT_EQ(1, browser()->tab_count());
    992 
    993   CheckDownload(browser(), file, file);
    994 }
    995 
    996 // Open a web page in the current tab, then download a file in another tab via
    997 // a Javascript call.
    998 // Verify that we have 2 tabs, and the download shelf is visible in the current
    999 // tab.
   1000 //
   1001 // The download_page1.html page contains an openNew() function that opens a
   1002 // tab and then downloads download-test1.lib.
   1003 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab2) {
   1004   ASSERT_TRUE(InitialSetup(false));
   1005   // Because it's an HTML link, it should open a web page rather than
   1006   // downloading.
   1007   FilePath file1(FILE_PATH_LITERAL("download_page1.html"));
   1008   GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
   1009 
   1010   // Open a web page and wait.
   1011   ui_test_utils::NavigateToURL(browser(), url);
   1012 
   1013   // Download a file in a new tab and wait (via Javascript).
   1014   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1015   DownloadAndWaitWithDisposition(browser(),
   1016                                  GURL("javascript:openNew()"),
   1017                                  CURRENT_TAB,
   1018                                  EXPECT_NO_SELECT_DIALOG,
   1019                                  ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   1020 
   1021   // When the download finishes, we should have two tabs.
   1022   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1023   EXPECT_EQ(2, browser()->tab_count());
   1024 
   1025   CheckDownload(browser(), file, file);
   1026 }
   1027 
   1028 // Open a web page in the current tab, open another tab via a Javascript call,
   1029 // then download a file in the new tab.
   1030 // Verify that we have 2 tabs, and the download shelf is visible in the current
   1031 // tab.
   1032 //
   1033 // The download_page2.html page contains an openNew() function that opens a
   1034 // tab.
   1035 IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab3) {
   1036   ASSERT_TRUE(InitialSetup(false));
   1037   // Because it's an HTML link, it should open a web page rather than
   1038   // downloading.
   1039   FilePath file1(FILE_PATH_LITERAL("download_page2.html"));
   1040   GURL url1(URLRequestMockHTTPJob::GetMockUrl(file1));
   1041 
   1042   // Open a web page and wait.
   1043   ui_test_utils::NavigateToURL(browser(), url1);
   1044 
   1045   // Open a new tab and wait.
   1046   ui_test_utils::NavigateToURLWithDisposition(
   1047       browser(),
   1048       GURL("javascript:openNew()"),
   1049       CURRENT_TAB,
   1050       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   1051 
   1052   EXPECT_EQ(2, browser()->tab_count());
   1053 
   1054   // Download a file and wait.
   1055   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1056   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1057   DownloadAndWaitWithDisposition(browser(),
   1058                                  url,
   1059                                  CURRENT_TAB,
   1060                                  EXPECT_NO_SELECT_DIALOG,
   1061                                  ui_test_utils::BROWSER_TEST_NONE);
   1062 
   1063   // When the download finishes, we should have two tabs.
   1064   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1065   EXPECT_EQ(2, browser()->tab_count());
   1066 
   1067   CheckDownload(browser(), file, file);
   1068 }
   1069 
   1070 // Open a web page in the current tab, then download a file via Javascript,
   1071 // which will do so in a temporary tab.
   1072 // Verify that we have 1 tab, and the download shelf is visible.
   1073 //
   1074 // The download_page3.html page contains an openNew() function that opens a
   1075 // tab with download-test1.lib in the URL.  When the URL is determined to be
   1076 // a download, the tab is closed automatically.
   1077 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab2) {
   1078   ASSERT_TRUE(InitialSetup(false));
   1079   // Because it's an HTML link, it should open a web page rather than
   1080   // downloading.
   1081   FilePath file1(FILE_PATH_LITERAL("download_page3.html"));
   1082   GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
   1083 
   1084   // Open a web page and wait.
   1085   ui_test_utils::NavigateToURL(browser(), url);
   1086 
   1087   // Download a file and wait.
   1088   // The file to download is "download-test1.lib".
   1089   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1090   DownloadAndWaitWithDisposition(browser(),
   1091                                  GURL("javascript:openNew()"),
   1092                                  CURRENT_TAB,
   1093                                  EXPECT_NO_SELECT_DIALOG,
   1094                                  ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   1095 
   1096   // When the download finishes, we should still have one tab.
   1097   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1098   EXPECT_EQ(1, browser()->tab_count());
   1099 
   1100   CheckDownload(browser(), file, file);
   1101 }
   1102 
   1103 // Open a web page in the current tab, then call Javascript via a button to
   1104 // download a file in a new tab, which is closed automatically when the
   1105 // download begins.
   1106 // Verify that we have 1 tab, and the download shelf is visible.
   1107 //
   1108 // The download_page4.html page contains a form with download-test1.lib as the
   1109 // action.
   1110 IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab3) {
   1111   ASSERT_TRUE(InitialSetup(false));
   1112   // Because it's an HTML link, it should open a web page rather than
   1113   // downloading.
   1114   FilePath file1(FILE_PATH_LITERAL("download_page4.html"));
   1115   GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
   1116 
   1117   // Open a web page and wait.
   1118   ui_test_utils::NavigateToURL(browser(), url);
   1119 
   1120   // Download a file in a new tab and wait.  The tab will automatically close
   1121   // when the download begins.
   1122   // The file to download is "download-test1.lib".
   1123   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1124   DownloadAndWaitWithDisposition(
   1125       browser(),
   1126       GURL("javascript:document.getElementById('form').submit()"),
   1127       CURRENT_TAB,
   1128       EXPECT_NO_SELECT_DIALOG,
   1129       ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
   1130 
   1131   // When the download finishes, we should still have one tab.
   1132   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1133   EXPECT_EQ(1, browser()->tab_count());
   1134 
   1135   CheckDownload(browser(), file, file);
   1136 }
   1137 
   1138 // Download a file in a new window.
   1139 // Verify that we have 2 windows, and the download shelf is not visible in the
   1140 // first window, but is visible in the second window.
   1141 // Close the new window.
   1142 // Verify that we have 1 window, and the download shelf is not visible.
   1143 //
   1144 // Regression test for http://crbug.com/44454
   1145 IN_PROC_BROWSER_TEST_F(DownloadTest, NewWindow) {
   1146   ASSERT_TRUE(InitialSetup(false));
   1147   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1148   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1149 #if !defined(OS_MACOSX)
   1150   // See below.
   1151   Browser* first_browser = browser();
   1152 #endif
   1153 
   1154   // Download a file in a new window and wait.
   1155   DownloadAndWaitWithDisposition(browser(),
   1156                                  url,
   1157                                  NEW_WINDOW,
   1158                                  EXPECT_NO_SELECT_DIALOG,
   1159                                  ui_test_utils::BROWSER_TEST_NONE);
   1160 
   1161   // When the download finishes, the download shelf SHOULD NOT be visible in
   1162   // the first window.
   1163   ExpectWindowCountAfterDownload(2);
   1164   EXPECT_EQ(1, browser()->tab_count());
   1165 #if defined(OS_CHROMEOS)
   1166   // Except on chromeos the download UI isn't window-specific.
   1167   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1168 #else
   1169   EXPECT_FALSE(IsDownloadUIVisible(browser()));
   1170 #endif
   1171 
   1172   // The download shelf SHOULD be visible in the second window.
   1173   std::set<Browser*> original_browsers;
   1174   original_browsers.insert(browser());
   1175   Browser* download_browser =
   1176       ui_test_utils::GetBrowserNotInSet(original_browsers);
   1177   ASSERT_TRUE(download_browser != NULL);
   1178   EXPECT_NE(download_browser, browser());
   1179   EXPECT_EQ(1, download_browser->tab_count());
   1180   EXPECT_TRUE(IsDownloadUIVisible(download_browser));
   1181 
   1182   // Close the new window.
   1183   download_browser->CloseWindow();
   1184 #if !defined(OS_MACOSX)
   1185   // On Mac OS X, the UI window close is delayed until the outermost
   1186   // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
   1187   // notification inside of a test.
   1188   ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED,
   1189                                          Source<Browser>(download_browser));
   1190   EXPECT_EQ(first_browser, browser());
   1191   ExpectWindowCountAfterDownload(1);
   1192 #endif
   1193 
   1194   EXPECT_EQ(1, browser()->tab_count());
   1195 #if defined(OS_CHROMEOS)
   1196   // On ChromeOS the popup sticks around.
   1197   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1198 #else
   1199   // Otherwise, the download shelf should not be visible in the
   1200   // remaining window.
   1201   EXPECT_FALSE(IsDownloadUIVisible(browser()));
   1202 #endif
   1203 
   1204   CheckDownload(browser(), file, file);
   1205 }
   1206 
   1207 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) {
   1208   ASSERT_TRUE(InitialSetup(false));
   1209   EXPECT_EQ(1, browser()->tab_count());
   1210 
   1211   // TODO(rdsmith): Fragile code warning!  The code below relies on the
   1212   // DownloadsObserver only finishing when the new download has reached
   1213   // the state of being entered into the history and being user-visible
   1214   // (that's what's required for the Remove to be valid and for the
   1215   // download shelf to be visible).  By the pure semantics of
   1216   // DownloadsObserver, that's not guaranteed; DownloadItems are created
   1217   // in the IN_PROGRESS state and made known to the DownloadManager
   1218   // immediately, so any ModelChanged event on the DownloadManager after
   1219   // navigation would allow the observer to return.  However, the only
   1220   // ModelChanged() event the code will currently fire is in
   1221   // OnCreateDownloadEntryComplete, at which point the download item will
   1222   // be in the state we need.
   1223   // The right way to fix this is to create finer grained states on the
   1224   // DownloadItem, and wait for the state that indicates the item has been
   1225   // entered in the history and made visible in the UI.
   1226 
   1227   // Create a download, wait until it's started, and confirm
   1228   // we're in the expected state.
   1229   scoped_ptr<DownloadsObserver> observer(CreateInProgressWaiter(browser(), 1));
   1230   ui_test_utils::NavigateToURL(
   1231       browser(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
   1232   observer->WaitForFinished();
   1233 
   1234   std::vector<DownloadItem*> downloads;
   1235   browser()->profile()->GetDownloadManager()->SearchDownloads(
   1236       string16(), &downloads);
   1237   ASSERT_EQ(1u, downloads.size());
   1238   ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state());
   1239   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1240 
   1241   // Cancel the download and wait for download system quiesce.
   1242   downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
   1243   scoped_refptr<DownloadsFlushObserver> flush_observer(
   1244       new DownloadsFlushObserver(browser()->profile()->GetDownloadManager()));
   1245   flush_observer->WaitForFlush();
   1246 
   1247   // Get the important info from other threads and check it.
   1248   scoped_refptr<CancelTestDataCollector> info(new CancelTestDataCollector());
   1249   info->WaitForDataCollected();
   1250   EXPECT_EQ(0, info->rdh_pending_requests());
   1251   EXPECT_EQ(0, info->dfm_pending_downloads());
   1252 
   1253   // Using "DownloadItem::Remove" follows the discard dangerous download path,
   1254   // which completely removes the browser from the shelf and closes the shelf
   1255   // if it was there.
   1256 #if defined(OS_CHROMEOS)
   1257   // Except under ChromeOS in which case if we've brought up the file
   1258   // picker panel, it stays.
   1259   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1260 #else
   1261   EXPECT_FALSE(IsDownloadUIVisible(browser()));
   1262 #endif
   1263 }
   1264 
   1265 // Confirm a download makes it into the history properly.
   1266 IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) {
   1267   ASSERT_TRUE(InitialSetup(false));
   1268   FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
   1269   GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
   1270   FilePath origin_file(OriginFile(file));
   1271   int64 origin_size;
   1272   file_util::GetFileSize(origin_file, &origin_size);
   1273 
   1274   // Download the file and wait.  We do not expect the Select File dialog.
   1275   DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
   1276 
   1277   // Get details of what downloads have just happened.
   1278   std::vector<DownloadItem*> downloads;
   1279   GetDownloads(browser(), &downloads);
   1280   ASSERT_EQ(1u, downloads.size());
   1281   int64 db_handle = downloads[0]->db_handle();
   1282 
   1283   // Check state.
   1284   EXPECT_EQ(1, browser()->tab_count());
   1285   CheckDownload(browser(), file, file);
   1286   EXPECT_TRUE(IsDownloadUIVisible(browser()));
   1287 
   1288   // Check history results.
   1289   DownloadsHistoryDataCollector history_collector(
   1290       db_handle,
   1291       browser()->profile()->GetDownloadManager());
   1292   DownloadCreateInfo info;
   1293   EXPECT_TRUE(history_collector.GetDownloadsHistoryEntry(&info)) << db_handle;
   1294   EXPECT_EQ(file, info.path.BaseName());
   1295   EXPECT_EQ(url, info.url());
   1296   // Ignore start_time.
   1297   EXPECT_EQ(origin_size, info.received_bytes);
   1298   EXPECT_EQ(origin_size, info.total_bytes);
   1299   EXPECT_EQ(DownloadItem::COMPLETE, info.state);
   1300 }
   1301