diff options
author | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 00:00:32 +0000 |
---|---|---|
committer | jianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-10 00:00:32 +0000 |
commit | 8af9d0341d6c00ee537adc089f938b120d1d8d34 (patch) | |
tree | 334fcf5a09c2b3e12face9d46ae4f25ee62921eb /app | |
parent | 8d292399e6dcdfa776a1de94da07841bf1487f5b (diff) | |
download | chromium_src-8af9d0341d6c00ee537adc089f938b120d1d8d34.zip chromium_src-8af9d0341d6c00ee537adc089f938b120d1d8d34.tar.gz chromium_src-8af9d0341d6c00ee537adc089f938b120d1d8d34.tar.bz2 |
Refactor DragDownloadFile so that it can be used by both Windows and MacOSX.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/572014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38545 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'app')
-rw-r--r-- | app/app_base.gypi | 1 | ||||
-rw-r--r-- | app/download_file_interface.h | 46 | ||||
-rw-r--r-- | app/os_exchange_data.cc | 2 | ||||
-rw-r--r-- | app/os_exchange_data.h | 40 | ||||
-rw-r--r-- | app/os_exchange_data_provider_win.cc | 71 | ||||
-rw-r--r-- | app/os_exchange_data_provider_win.h | 18 |
6 files changed, 87 insertions, 91 deletions
diff --git a/app/app_base.gypi b/app/app_base.gypi index daa2f52..fdc8854 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -106,6 +106,7 @@ 'drag_drop_types_gtk.cc', 'drag_drop_types_win.cc', 'drag_drop_types.h', + 'file_download_interface.h', 'gfx/blit.cc', 'gfx/blit.h', 'gfx/canvas.cc', diff --git a/app/download_file_interface.h b/app/download_file_interface.h new file mode 100644 index 0000000..13d2dcf --- /dev/null +++ b/app/download_file_interface.h @@ -0,0 +1,46 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef APP_DOWNLOAD_FILE_INTERFACE_H_ +#define APP_DOWNLOAD_FILE_INTERFACE_H_ + +#include "build/build_config.h" + +#include "base/basictypes.h" +#include "base/ref_counted.h" + +#if defined(OS_WIN) +#include <objidl.h> +#endif + +class FilePath; + +// Defines the interface to observe the status of file download. +class DownloadFileObserver + : public base::RefCountedThreadSafe<DownloadFileObserver> { + public: + virtual void OnDownloadCompleted(const FilePath& file_path) = 0; + virtual void OnDownloadAborted() = 0; + + protected: + friend class base::RefCountedThreadSafe<DownloadFileObserver>; + virtual ~DownloadFileObserver() {} +}; + +// Defines the interface to control how a file is downloaded. +class DownloadFileProvider + : public base::RefCountedThreadSafe<DownloadFileProvider> { + public: + virtual bool Start(DownloadFileObserver* observer) = 0; + virtual void Stop() = 0; +#if defined(OS_WIN) + virtual IStream* GetStream() = 0; +#endif + + protected: + friend class base::RefCountedThreadSafe<DownloadFileProvider>; + virtual ~DownloadFileProvider() {} +}; + +#endif // APP_DOWNLOAD_FILE_INTERFACE_H_ diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc index dc57cd1..8081f37 100644 --- a/app/os_exchange_data.cc +++ b/app/os_exchange_data.cc @@ -129,7 +129,7 @@ bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const { return provider_->GetHtml(html, base_url); } -void OSExchangeData::SetDownloadFileInfo(DownloadFileInfo* download) { +void OSExchangeData::SetDownloadFileInfo(const DownloadFileInfo& download) { return provider_->SetDownloadFileInfo(download); } #endif diff --git a/app/os_exchange_data.h b/app/os_exchange_data.h index b38e655..316db88 100644 --- a/app/os_exchange_data.h +++ b/app/os_exchange_data.h @@ -17,9 +17,9 @@ #include <gtk/gtk.h> #endif +#include "app/download_file_interface.h" #include "base/basictypes.h" #include "base/file_path.h" -#include "base/ref_counted.h" #include "base/scoped_ptr.h" class GURL; @@ -61,45 +61,13 @@ class OSExchangeData { #endif }; - struct DownloadFileInfo; - - // Defines the interface to observe the status of file download. - class DownloadFileObserver : public base::RefCounted<DownloadFileObserver> { - public: - // The caller is responsible to free the DownloadFileInfo objects passed - // in the vector parameter. - virtual void OnDataReady( - int format, - const std::vector<DownloadFileInfo*>& downloads) = 0; - - protected: - friend class base::RefCounted<DownloadFileObserver>; - virtual ~DownloadFileObserver() {} - }; - - // Defines the interface to control how a file is downloaded. - class DownloadFileProvider : - public base::RefCountedThreadSafe<DownloadFileProvider> { - public: - virtual bool Start(DownloadFileObserver* observer, int format) = 0; - virtual void Stop() = 0; - - protected: - friend class base::RefCountedThreadSafe<DownloadFileProvider>; - virtual ~DownloadFileProvider() {} - }; - // Encapsulates the info about a file to be downloaded. struct DownloadFileInfo { FilePath filename; - uint64 size; scoped_refptr<DownloadFileProvider> downloader; - DownloadFileInfo(const FilePath& filename, - uint64 size, - DownloadFileProvider* downloader) + DownloadFileInfo(const FilePath& filename, DownloadFileProvider* downloader) : filename(filename), - size(size), downloader(downloader) {} }; @@ -135,7 +103,7 @@ class OSExchangeData { virtual bool GetHtml(std::wstring* html, GURL* base_url) const = 0; virtual bool HasFileContents() const = 0; virtual bool HasHtml() const = 0; - virtual void SetDownloadFileInfo(DownloadFileInfo* download) = 0; + virtual void SetDownloadFileInfo(const DownloadFileInfo& download) = 0; #endif }; @@ -211,7 +179,7 @@ class OSExchangeData { bool GetHtml(std::wstring* html, GURL* base_url) const; // Adds a download file with full path (CF_HDROP). - void SetDownloadFileInfo(DownloadFileInfo* download); + void SetDownloadFileInfo(const DownloadFileInfo& download); #endif private: diff --git a/app/os_exchange_data_provider_win.cc b/app/os_exchange_data_provider_win.cc index dc28597..8f953d1 100644 --- a/app/os_exchange_data_provider_win.cc +++ b/app/os_exchange_data_provider_win.cc @@ -455,17 +455,17 @@ bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const { } void OSExchangeDataProviderWin::SetDownloadFileInfo( - OSExchangeData::DownloadFileInfo* download) { + const OSExchangeData::DownloadFileInfo& download) { // If the filename is not provided, set stoarge to NULL to indicate that // the delay rendering will be used. STGMEDIUM* storage = NULL; - if (!download->filename.empty()) - storage = GetStorageForFileName(download->filename.value()); + if (!download.filename.empty()) + storage = GetStorageForFileName(download.filename.value()); // Add CF_HDROP. DataObjectImpl::StoredDataInfo* info = new DataObjectImpl::StoredDataInfo( ClipboardUtil::GetCFHDropFormat()->cfFormat, storage); - info->downloads.push_back(download); + info->downloader = download.downloader; data_->contents_.push_back(info); } @@ -560,35 +560,18 @@ DataObjectImpl::~DataObjectImpl() { void DataObjectImpl::StopDownloads() { for (StoredData::iterator iter = contents_.begin(); iter != contents_.end(); ++iter) { - for (size_t i = 0; i < (*iter)->downloads.size(); ++i) { - if ((*iter)->downloads[i]->downloader) { - (*iter)->downloads[i]->downloader->Stop(); - (*iter)->downloads[i]->downloader = 0; - } - delete (*iter)->downloads[i]; + if ((*iter)->downloader.get()) { + (*iter)->downloader->Stop(); + (*iter)->downloader = 0; } - (*iter)->downloads.clear(); } } -void DataObjectImpl::OnDataReady( - int format, - const std::vector<OSExchangeData::DownloadFileInfo*>& downloads) { - // Find and update the data corresponding to the format. - CLIPFORMAT clip_format = static_cast<CLIPFORMAT>(format); - DCHECK(clip_format == ClipboardUtil::GetCFHDropFormat()->cfFormat); +void DataObjectImpl::OnDownloadCompleted(const FilePath& file_path) { + CLIPFORMAT hdrop_format = ClipboardUtil::GetCFHDropFormat()->cfFormat; DataObjectImpl::StoredData::iterator iter = contents_.begin(); for (; iter != contents_.end(); ++iter) { - if ((*iter)->format_etc.cfFormat == clip_format) { - // Update the downloads. - DCHECK(downloads.size() == (*iter)->downloads.size()); - for (size_t i = 0; i < (*iter)->downloads.size(); ++i) { - OSExchangeData::DownloadFileInfo* old_download = (*iter)->downloads[i]; - (*iter)->downloads[i] = downloads[i]; - (*iter)->downloads[i]->downloader = old_download->downloader; - delete old_download; - } - + if ((*iter)->format_etc.cfFormat == hdrop_format) { // Release the old storage. if ((*iter)->owns_medium) { ReleaseStgMedium((*iter)->medium); @@ -597,7 +580,7 @@ void DataObjectImpl::OnDataReady( // Update the storage. (*iter)->owns_medium = true; - (*iter)->medium = GetStorageForFileName(downloads[0]->filename.value()); + (*iter)->medium = GetStorageForFileName(file_path.value()); break; } @@ -605,6 +588,9 @@ void DataObjectImpl::OnDataReady( DCHECK(iter != contents_.end()); } +void DataObjectImpl::OnDownloadAborted() { +} + HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { if (is_aborting_) return DV_E_FORMATETC; @@ -629,7 +615,12 @@ HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { if (is_left_button_down) return DV_E_FORMATETC; - wait_for_data = true; + // In async mode, we do not want to start waiting for the data before + // the async operation is started. This is because we want to postpone + // until Shell kicks off a background thread to do the work so that + // we do not block the UI thread. + if (!in_async_mode_ || async_operation_started_) + wait_for_data = true; } else { // If the left button is up and the target has not requested the data // yet, it probably means that the target does not support delay- @@ -648,18 +639,11 @@ HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { if (observer_) observer_->OnWaitForData(); - // Now we can start the downloads. Each download will wait till the - // necessary data is ready and then return the control. - for (size_t i = 0; i < (*iter)->downloads.size(); ++i) { - if ((*iter)->downloads[i]->downloader) { - if (!(*iter)->downloads[i]->downloader->Start( - this, format_etc->cfFormat)) { - // If any of the download fails to start, abort the whole - // process. - is_aborting_ = true; - StopDownloads(); - return DV_E_FORMATETC; - } + // Now we can start the download. + if ((*iter)->downloader.get()) { + if (!(*iter)->downloader->Start(this)) { + is_aborting_ = true; + return DV_E_FORMATETC; } } @@ -788,12 +772,12 @@ HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) { } ULONG DataObjectImpl::AddRef() { - base::RefCounted<OSExchangeData::DownloadFileObserver>::AddRef(); + base::RefCountedThreadSafe<DownloadFileObserver>::AddRef(); return 0; } ULONG DataObjectImpl::Release() { - base::RefCounted<OSExchangeData::DownloadFileObserver>::Release(); + base::RefCountedThreadSafe<DownloadFileObserver>::Release(); return 0; } @@ -918,6 +902,7 @@ static STGMEDIUM* GetStorageForFileDescriptor( return storage; } + /////////////////////////////////////////////////////////////////////////////// // OSExchangeData, public: diff --git a/app/os_exchange_data_provider_win.h b/app/os_exchange_data_provider_win.h index 4bd0d80..6ea014b 100644 --- a/app/os_exchange_data_provider_win.h +++ b/app/os_exchange_data_provider_win.h @@ -12,7 +12,7 @@ #include "app/os_exchange_data.h" #include "base/scoped_comptr_win.h" -class DataObjectImpl : public OSExchangeData::DownloadFileObserver, +class DataObjectImpl : public DownloadFileObserver, public IDataObject, public IAsyncOperation { public: @@ -30,9 +30,8 @@ class DataObjectImpl : public OSExchangeData::DownloadFileObserver, void set_observer(Observer* observer) { observer_ = observer; } // DownloadFileObserver implementation: - virtual void OnDataReady( - int format, - const std::vector<OSExchangeData::DownloadFileInfo*>& downloads); + virtual void OnDownloadCompleted(const FilePath& file_path); + virtual void OnDownloadAborted(); // IDataObject implementation: HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium); @@ -77,7 +76,7 @@ class DataObjectImpl : public OSExchangeData::DownloadFileObserver, STGMEDIUM* medium; bool owns_medium; bool in_delay_rendering; - std::vector<OSExchangeData::DownloadFileInfo*> downloads; + scoped_refptr<DownloadFileProvider> downloader; StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* medium) : medium(medium), @@ -102,11 +101,8 @@ class DataObjectImpl : public OSExchangeData::DownloadFileObserver, ReleaseStgMedium(medium); delete medium; } - for (size_t i = 0; i < downloads.size(); ++i) { - if (downloads[i]->downloader) - downloads[i]->downloader->Stop(); - } - downloads.clear(); + if (downloader.get()) + downloader->Stop(); } }; @@ -167,7 +163,7 @@ class OSExchangeDataProviderWin : public OSExchangeData::Provider { virtual bool HasHtml() const; virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const; virtual void SetDownloadFileInfo( - OSExchangeData::DownloadFileInfo* download_info); + const OSExchangeData::DownloadFileInfo& download_info); private: scoped_refptr<DataObjectImpl> data_; |