| Index: content/test/test_file_error_injector.cc
 | 
| diff --git a/content/test/test_file_error_injector.cc b/content/test/test_file_error_injector.cc
 | 
| index 26eaf8ea11a734800abe17cfdef56cb6f7af3c01..73da59a4cb031d15f7991d3ee25636b42b38d2c1 100644
 | 
| --- a/content/test/test_file_error_injector.cc
 | 
| +++ b/content/test/test_file_error_injector.cc
 | 
| @@ -8,14 +8,13 @@
 | 
|  
 | 
|  #include "base/compiler_specific.h"
 | 
|  #include "base/logging.h"
 | 
| -#include "content/browser/download/download_create_info.h"
 | 
|  #include "content/browser/download/download_file_impl.h"
 | 
| -#include "content/browser/download/download_file_manager.h"
 | 
| +#include "content/browser/download/download_file_factory.h"
 | 
|  #include "content/browser/download/download_interrupt_reasons_impl.h"
 | 
| +#include "content/browser/download/download_manager_impl.h"
 | 
|  #include "content/browser/power_save_blocker.h"
 | 
|  #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
 | 
|  #include "content/public/browser/browser_thread.h"
 | 
| -#include "content/public/browser/download_id.h"
 | 
|  #include "googleurl/src/gurl.h"
 | 
|  
 | 
|  namespace content {
 | 
| @@ -24,35 +23,31 @@ class ByteStreamReader;
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| -DownloadFileManager* GetDownloadFileManager() {
 | 
| -  content::ResourceDispatcherHostImpl* rdh =
 | 
| -      content::ResourceDispatcherHostImpl::Get();
 | 
| -  DCHECK(rdh != NULL);
 | 
| -  return rdh->download_file_manager();
 | 
| -}
 | 
| -
 | 
|  // A class that performs file operations and injects errors.
 | 
|  class DownloadFileWithErrors: public DownloadFileImpl {
 | 
|   public:
 | 
| -  typedef base::Callback<void(const GURL& url, content::DownloadId id)>
 | 
| -      ConstructionCallback;
 | 
| +  typedef base::Callback<void(const GURL& url)> ConstructionCallback;
 | 
|    typedef base::Callback<void(const GURL& url)> DestructionCallback;
 | 
|  
 | 
|    DownloadFileWithErrors(
 | 
| -      const DownloadCreateInfo* info,
 | 
| -      scoped_ptr<content::ByteStreamReader> stream,
 | 
| -      DownloadRequestHandleInterface* request_handle,
 | 
| -      content::DownloadManager* download_manager,
 | 
| +      const content::DownloadSaveInfo& save_info,
 | 
| +      const GURL& url,
 | 
| +      const GURL& referrer_url,
 | 
| +      int64 received_bytes,
 | 
|        bool calculate_hash,
 | 
| +      scoped_ptr<content::ByteStreamReader> stream,
 | 
|        const net::BoundNetLog& bound_net_log,
 | 
| +      scoped_ptr<content::PowerSaveBlocker> power_save_blocker,
 | 
| +      base::WeakPtr<content::DownloadDestinationController> controller,
 | 
|        const content::TestFileErrorInjector::FileErrorInfo& error_info,
 | 
|        const ConstructionCallback& ctor_callback,
 | 
|        const DestructionCallback& dtor_callback);
 | 
|  
 | 
|    ~DownloadFileWithErrors();
 | 
|  
 | 
| +  virtual void Initialize(const InitializeCallback& callback) OVERRIDE;
 | 
| +
 | 
|    // DownloadFile interface.
 | 
| -  virtual content::DownloadInterruptReason Initialize() OVERRIDE;
 | 
|    virtual content::DownloadInterruptReason AppendDataToFile(
 | 
|        const char* data, size_t data_len) OVERRIDE;
 | 
|    virtual void Rename(const FilePath& full_path,
 | 
| @@ -65,6 +60,12 @@ class DownloadFileWithErrors: public DownloadFileImpl {
 | 
|        content::TestFileErrorInjector::FileOperationCode code,
 | 
|        content::DownloadInterruptReason original_error);
 | 
|  
 | 
| +  // Used in place of original Initialize callback to intercept
 | 
| +  // with ShouldReturnError.
 | 
| +  void InitializeErrorCallback(
 | 
| +    const InitializeCallback& original_callback,
 | 
| +    content::DownloadInterruptReason original_error);
 | 
| +
 | 
|    // Used in place of original rename callback to intercept with
 | 
|    // ShouldReturnError.
 | 
|    void RenameErrorCallback(
 | 
| @@ -87,36 +88,39 @@ class DownloadFileWithErrors: public DownloadFileImpl {
 | 
|  };
 | 
|  
 | 
|  DownloadFileWithErrors::DownloadFileWithErrors(
 | 
| -    const DownloadCreateInfo* info,
 | 
| -    scoped_ptr<content::ByteStreamReader> stream,
 | 
| -    DownloadRequestHandleInterface* request_handle,
 | 
| -    content::DownloadManager* download_manager,
 | 
| +    const content::DownloadSaveInfo& save_info,
 | 
| +    const GURL& url,
 | 
| +    const GURL& referrer_url,
 | 
| +    int64 received_bytes,
 | 
|      bool calculate_hash,
 | 
| +    scoped_ptr<content::ByteStreamReader> stream,
 | 
|      const net::BoundNetLog& bound_net_log,
 | 
| +    scoped_ptr<content::PowerSaveBlocker> power_save_blocker,
 | 
| +    base::WeakPtr<content::DownloadDestinationController> controller,
 | 
|      const content::TestFileErrorInjector::FileErrorInfo& error_info,
 | 
|      const ConstructionCallback& ctor_callback,
 | 
|      const DestructionCallback& dtor_callback)
 | 
| -        : DownloadFileImpl(info,
 | 
| -                           stream.Pass(),
 | 
| -                           request_handle,
 | 
| -                           download_manager,
 | 
| -                           calculate_hash,
 | 
| -                           scoped_ptr<content::PowerSaveBlocker>(NULL).Pass(),
 | 
| -                           bound_net_log),
 | 
| -          source_url_(info->url()),
 | 
| +        : DownloadFileImpl(
 | 
| +            save_info, url, referrer_url, received_bytes, calculate_hash,
 | 
| +            stream.Pass(), bound_net_log, power_save_blocker.Pass(),
 | 
| +            controller),
 | 
| +          source_url_(url),
 | 
|            error_info_(error_info),
 | 
|            destruction_callback_(dtor_callback) {
 | 
| -  ctor_callback.Run(source_url_, info->download_id);
 | 
| +  ctor_callback.Run(source_url_);
 | 
|  }
 | 
|  
 | 
|  DownloadFileWithErrors::~DownloadFileWithErrors() {
 | 
|    destruction_callback_.Run(source_url_);
 | 
|  }
 | 
|  
 | 
| -content::DownloadInterruptReason DownloadFileWithErrors::Initialize() {
 | 
| -  return ShouldReturnError(
 | 
| -          content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
 | 
| -          DownloadFileImpl::Initialize());
 | 
| +void DownloadFileWithErrors::Initialize(
 | 
| +    const InitializeCallback& callback) {
 | 
| +  DownloadFileImpl::Initialize(
 | 
| +      base::Bind(&DownloadFileWithErrors::InitializeErrorCallback,
 | 
| +                 // Unretained since this'll only be called from
 | 
| +                 // the DownloadFileImpl slice of the same object.
 | 
| +                 base::Unretained(this), callback));
 | 
|  }
 | 
|  
 | 
|  content::DownloadInterruptReason DownloadFileWithErrors::AppendDataToFile(
 | 
| @@ -165,6 +169,14 @@ content::DownloadInterruptReason DownloadFileWithErrors::ShouldReturnError(
 | 
|    return error_info_.error;
 | 
|  }
 | 
|  
 | 
| +void DownloadFileWithErrors::InitializeErrorCallback(
 | 
| +    const InitializeCallback& original_callback,
 | 
| +    content::DownloadInterruptReason original_error) {
 | 
| +  original_callback.Run(ShouldReturnError(
 | 
| +      content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
 | 
| +      original_error));
 | 
| +}
 | 
| +
 | 
|  void DownloadFileWithErrors::RenameErrorCallback(
 | 
|      const RenameCompletionCallback& original_callback,
 | 
|      content::DownloadInterruptReason original_error,
 | 
| @@ -179,8 +191,7 @@ void DownloadFileWithErrors::RenameErrorCallback(
 | 
|  namespace content {
 | 
|  
 | 
|  // A factory for constructing DownloadFiles that inject errors.
 | 
| -class DownloadFileWithErrorsFactory
 | 
| -    : public DownloadFileManager::DownloadFileFactory {
 | 
| +class DownloadFileWithErrorsFactory : public DownloadFileFactory {
 | 
|   public:
 | 
|  
 | 
|    DownloadFileWithErrorsFactory(
 | 
| @@ -190,11 +201,14 @@ class DownloadFileWithErrorsFactory
 | 
|  
 | 
|    // DownloadFileFactory interface.
 | 
|    virtual DownloadFile* CreateFile(
 | 
| -      DownloadCreateInfo* info,
 | 
| -      scoped_ptr<content::ByteStreamReader> stream,
 | 
| -      content::DownloadManager* download_manager,
 | 
| -      bool calculate_hash,
 | 
| -      const net::BoundNetLog& bound_net_log);
 | 
| +    const content::DownloadSaveInfo& save_info,
 | 
| +    GURL url,
 | 
| +    GURL referrer_url,
 | 
| +    int64 received_bytes,
 | 
| +    bool calculate_hash,
 | 
| +    scoped_ptr<content::ByteStreamReader> stream,
 | 
| +    const net::BoundNetLog& bound_net_log,
 | 
| +    base::WeakPtr<content::DownloadDestinationController> controller);
 | 
|  
 | 
|    bool AddError(
 | 
|        const TestFileErrorInjector::FileErrorInfo& error_info);
 | 
| @@ -221,32 +235,40 @@ DownloadFileWithErrorsFactory::~DownloadFileWithErrorsFactory() {
 | 
|  }
 | 
|  
 | 
|  content::DownloadFile* DownloadFileWithErrorsFactory::CreateFile(
 | 
| -    DownloadCreateInfo* info,
 | 
| -    scoped_ptr<content::ByteStreamReader> stream,
 | 
| -    content::DownloadManager* download_manager,
 | 
| +    const content::DownloadSaveInfo& save_info,
 | 
| +    GURL url,
 | 
| +    GURL referrer_url,
 | 
| +    int64 received_bytes,
 | 
|      bool calculate_hash,
 | 
| -    const net::BoundNetLog& bound_net_log) {
 | 
| -  std::string url = info->url().spec();
 | 
| -
 | 
| -  if (injected_errors_.find(url) == injected_errors_.end()) {
 | 
| +    scoped_ptr<content::ByteStreamReader> stream,
 | 
| +    const net::BoundNetLog& bound_net_log,
 | 
| +    base::WeakPtr<content::DownloadDestinationController> controller) {
 | 
| +  if (injected_errors_.find(url.spec()) == injected_errors_.end()) {
 | 
|      // Have to create entry, because FileErrorInfo is not a POD type.
 | 
|      TestFileErrorInjector::FileErrorInfo err_info = {
 | 
| -      url,
 | 
| +      url.spec(),
 | 
|        TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
 | 
|        -1,
 | 
|        content::DOWNLOAD_INTERRUPT_REASON_NONE
 | 
|      };
 | 
| -    injected_errors_[url] = err_info;
 | 
| +    injected_errors_[url.spec()] = err_info;
 | 
|    }
 | 
|  
 | 
| +  scoped_ptr<content::PowerSaveBlocker> psb(
 | 
| +      new content::PowerSaveBlocker(
 | 
| +          content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
 | 
| +          "Download in progress"));
 | 
|    return new DownloadFileWithErrors(
 | 
| -      info,
 | 
| -      stream.Pass(),
 | 
| -      new DownloadRequestHandle(info->request_handle),
 | 
| -      download_manager,
 | 
| +      save_info,
 | 
| +      url,
 | 
| +      referrer_url,
 | 
| +      received_bytes,
 | 
|        calculate_hash,
 | 
| +      stream.Pass(),
 | 
|        bound_net_log,
 | 
| -      injected_errors_[url],
 | 
| +      psb.Pass(),
 | 
| +      controller,
 | 
| +      injected_errors_[url.spec()],
 | 
|        construction_callback_,
 | 
|        destruction_callback_);
 | 
|  }
 | 
| @@ -263,47 +285,32 @@ void DownloadFileWithErrorsFactory::ClearErrors() {
 | 
|    injected_errors_.clear();
 | 
|  }
 | 
|  
 | 
| -TestFileErrorInjector::TestFileErrorInjector()
 | 
| -    : created_factory_(NULL) {
 | 
| +TestFileErrorInjector::TestFileErrorInjector(
 | 
| +    scoped_refptr<content::DownloadManager> download_manager)
 | 
| +    : created_factory_(NULL),
 | 
| +      // This code is only used for browser_tests, so a
 | 
| +      // DownloadManager is always a DownloadManagerImpl.
 | 
| +      download_manager_(
 | 
| +          static_cast<DownloadManagerImpl*>(download_manager.release())) {
 | 
|    // Record the value of the pointer, for later validation.
 | 
|    created_factory_ =
 | 
|        new DownloadFileWithErrorsFactory(
 | 
| -          base::Bind(&TestFileErrorInjector::
 | 
| -                         RecordDownloadFileConstruction,
 | 
| +          base::Bind(&TestFileErrorInjector::RecordDownloadFileConstruction,
 | 
|                       this),
 | 
| -          base::Bind(&TestFileErrorInjector::
 | 
| -                         RecordDownloadFileDestruction,
 | 
| +          base::Bind(&TestFileErrorInjector::RecordDownloadFileDestruction,
 | 
|                       this));
 | 
|  
 | 
| -  // We will transfer ownership of the factory to the download file manager.
 | 
| -  scoped_ptr<DownloadFileWithErrorsFactory> download_file_factory(
 | 
| +  // We will transfer ownership of the factory to the download manager.
 | 
| +  scoped_ptr<DownloadFileFactory> download_file_factory(
 | 
|        created_factory_);
 | 
|  
 | 
| -  content::BrowserThread::PostTask(
 | 
| -      content::BrowserThread::FILE,
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&TestFileErrorInjector::AddFactory,
 | 
| -                 this,
 | 
| -                 base::Passed(&download_file_factory)));
 | 
| +  download_manager_->SetDownloadFileFactoryForTesting(
 | 
| +      download_file_factory.Pass());
 | 
|  }
 | 
|  
 | 
|  TestFileErrorInjector::~TestFileErrorInjector() {
 | 
|  }
 | 
|  
 | 
| -void TestFileErrorInjector::AddFactory(
 | 
| -    scoped_ptr<DownloadFileWithErrorsFactory> factory) {
 | 
| -  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
 | 
| -
 | 
| -  DownloadFileManager* download_file_manager = GetDownloadFileManager();
 | 
| -  DCHECK(download_file_manager);
 | 
| -
 | 
| -  // Convert to base class pointer, for GCC.
 | 
| -  scoped_ptr<DownloadFileManager::DownloadFileFactory> plain_factory(
 | 
| -      factory.release());
 | 
| -
 | 
| -  download_file_manager->SetFileFactoryForTesting(plain_factory.Pass());
 | 
| -}
 | 
| -
 | 
|  bool TestFileErrorInjector::AddError(const FileErrorInfo& error_info) {
 | 
|    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
|    DCHECK_LE(0, error_info.operation_instance);
 | 
| @@ -325,37 +332,16 @@ bool TestFileErrorInjector::InjectErrors() {
 | 
|  
 | 
|    ClearFoundFiles();
 | 
|  
 | 
| -  content::BrowserThread::PostTask(
 | 
| -      content::BrowserThread::FILE,
 | 
| -      FROM_HERE,
 | 
| -      base::Bind(&TestFileErrorInjector::InjectErrorsOnFileThread,
 | 
| -                 this,
 | 
| -                 injected_errors_,
 | 
| -                 created_factory_));
 | 
| -
 | 
| -  return true;
 | 
| -}
 | 
| -
 | 
| -void TestFileErrorInjector::InjectErrorsOnFileThread(
 | 
| -    ErrorMap map, DownloadFileWithErrorsFactory* factory) {
 | 
| -  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
 | 
| +  DCHECK_EQ(static_cast<content::DownloadFileFactory*>(created_factory_),
 | 
| +            download_manager_->GetDownloadFileFactory());
 | 
|  
 | 
| -  // Validate that our factory is in use.
 | 
| -  DownloadFileManager* download_file_manager = GetDownloadFileManager();
 | 
| -  DCHECK(download_file_manager);
 | 
| +  created_factory_->ClearErrors();
 | 
|  
 | 
| -  DownloadFileManager::DownloadFileFactory* file_factory =
 | 
| -      download_file_manager->GetFileFactoryForTesting();
 | 
| +  for (ErrorMap::const_iterator it = injected_errors_.begin();
 | 
| +       it != injected_errors_.end(); ++it)
 | 
| +    created_factory_->AddError(it->second);
 | 
|  
 | 
| -  // Validate that we still have the same factory.
 | 
| -  DCHECK_EQ(static_cast<DownloadFileManager::DownloadFileFactory*>(factory),
 | 
| -            file_factory);
 | 
| -
 | 
| -  // We want to replace all existing injection errors.
 | 
| -  factory->ClearErrors();
 | 
| -
 | 
| -  for (ErrorMap::const_iterator it = map.begin(); it != map.end(); ++it)
 | 
| -    factory->AddError(it->second);
 | 
| +  return true;
 | 
|  }
 | 
|  
 | 
|  size_t TestFileErrorInjector::CurrentFileCount() const {
 | 
| @@ -375,28 +361,16 @@ bool TestFileErrorInjector::HadFile(const GURL& url) const {
 | 
|    return (found_files_.find(url) != found_files_.end());
 | 
|  }
 | 
|  
 | 
| -const content::DownloadId TestFileErrorInjector::GetId(
 | 
| -    const GURL& url) const {
 | 
| -  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
| -
 | 
| -  FileMap::const_iterator it = found_files_.find(url);
 | 
| -  if (it == found_files_.end())
 | 
| -    return content::DownloadId::Invalid();
 | 
| -
 | 
| -  return it->second;
 | 
| -}
 | 
| -
 | 
|  void TestFileErrorInjector::ClearFoundFiles() {
 | 
|    found_files_.clear();
 | 
|  }
 | 
|  
 | 
| -void TestFileErrorInjector::DownloadFileCreated(GURL url,
 | 
| -                                                    content::DownloadId id) {
 | 
| +void TestFileErrorInjector::DownloadFileCreated(GURL url) {
 | 
|    DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 | 
|    DCHECK(files_.find(url) == files_.end());
 | 
|  
 | 
| -  files_[url] = id;
 | 
| -  found_files_[url] = id;
 | 
| +  files_.insert(url);
 | 
| +  found_files_.insert(url);
 | 
|  }
 | 
|  
 | 
|  void TestFileErrorInjector::DestroyingDownloadFile(GURL url) {
 | 
| @@ -406,15 +380,13 @@ void TestFileErrorInjector::DestroyingDownloadFile(GURL url) {
 | 
|    files_.erase(url);
 | 
|  }
 | 
|  
 | 
| -void TestFileErrorInjector::RecordDownloadFileConstruction(
 | 
| -    const GURL& url, content::DownloadId id) {
 | 
| +void TestFileErrorInjector::RecordDownloadFileConstruction(const GURL& url) {
 | 
|    content::BrowserThread::PostTask(
 | 
|        content::BrowserThread::UI,
 | 
|        FROM_HERE,
 | 
|        base::Bind(&TestFileErrorInjector::DownloadFileCreated,
 | 
|                   this,
 | 
| -                 url,
 | 
| -                 id));
 | 
| +                 url));
 | 
|  }
 | 
|  
 | 
|  void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) {
 | 
| @@ -427,13 +399,14 @@ void TestFileErrorInjector::RecordDownloadFileDestruction(const GURL& url) {
 | 
|  }
 | 
|  
 | 
|  // static
 | 
| -scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create() {
 | 
| +scoped_refptr<TestFileErrorInjector> TestFileErrorInjector::Create(
 | 
| +    scoped_refptr<content::DownloadManager> download_manager) {
 | 
|    static bool visited = false;
 | 
|    DCHECK(!visited);  // Only allowed to be called once.
 | 
|    visited = true;
 | 
|  
 | 
|    scoped_refptr<TestFileErrorInjector> single_injector(
 | 
| -      new TestFileErrorInjector);
 | 
| +      new TestFileErrorInjector(download_manager));
 | 
|  
 | 
|    return single_injector;
 | 
|  }
 | 
| 
 |