summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorjianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-10 00:00:32 +0000
committerjianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-10 00:00:32 +0000
commit8af9d0341d6c00ee537adc089f938b120d1d8d34 (patch)
tree334fcf5a09c2b3e12face9d46ae4f25ee62921eb /app
parent8d292399e6dcdfa776a1de94da07841bf1487f5b (diff)
downloadchromium_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.gypi1
-rw-r--r--app/download_file_interface.h46
-rw-r--r--app/os_exchange_data.cc2
-rw-r--r--app/os_exchange_data.h40
-rw-r--r--app/os_exchange_data_provider_win.cc71
-rw-r--r--app/os_exchange_data_provider_win.h18
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_;