| Index: chrome/browser/download/drag_download_file_win.cc
|
| ===================================================================
|
| --- chrome/browser/download/drag_download_file_win.cc (revision 0)
|
| +++ chrome/browser/download/drag_download_file_win.cc (revision 0)
|
| @@ -0,0 +1,217 @@
|
| +// 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.
|
| +
|
| +#include "chrome/browser/download/drag_download_file_win.h"
|
| +
|
| +#include "base/file_util.h"
|
| +#include "base/message_loop.h"
|
| +#include "chrome/browser/chrome_thread.h"
|
| +#include "chrome/browser/download/download_manager.h"
|
| +#include "chrome/browser/profile.h"
|
| +#include "chrome/browser/tab_contents/tab_contents.h"
|
| +
|
| +DragDownloadFile::DragDownloadFile(
|
| + const GURL& url,
|
| + const GURL& referrer,
|
| + const std::string& referrer_encoding,
|
| + TabContents* tab_contents)
|
| + : url_(url),
|
| + referrer_(referrer),
|
| + referrer_encoding_(referrer_encoding),
|
| + tab_contents_(tab_contents),
|
| + drag_message_loop_(MessageLoop::current()),
|
| + is_started_(false),
|
| + is_running_nested_message_loop_(false),
|
| + initiate_download_result_(false),
|
| + format_(0),
|
| + download_manager_(NULL),
|
| + download_item_observer_added_(false) {
|
| +}
|
| +
|
| +DragDownloadFile::~DragDownloadFile() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + // Since the target application can still hold and use the dragged file,
|
| + // we do not know the time that it can be safely deleted. To solve this
|
| + // problem, we schedule it to be removed after the system is restarted.
|
| +#if defined(OS_WIN)
|
| + if (!dir_path_.empty()) {
|
| + if (!file_path_.empty())
|
| + file_util::DeleteAfterReboot(file_path_);
|
| + file_util::DeleteAfterReboot(dir_path_);
|
| + }
|
| +#endif
|
| +
|
| + if (download_manager_)
|
| + download_manager_->RemoveObserver(this);
|
| +}
|
| +
|
| +bool DragDownloadFile::Start(OSExchangeData::DownloadFileObserver* observer,
|
| + int format) {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + if (is_started_)
|
| + return true;
|
| + is_started_ = true;
|
| +
|
| + DCHECK(!observer_.get());
|
| + observer_ = observer;
|
| + format_ = format;
|
| +
|
| + if (!InitiateDownload())
|
| + return false;
|
| +
|
| + // Wait till the download is fully initiated.
|
| + StartNestedMessageLoop();
|
| +
|
| + return initiate_download_result_;
|
| +}
|
| +
|
| +void DragDownloadFile::Stop() {
|
| +}
|
| +
|
| +bool DragDownloadFile::InitiateDownload() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + // Create a temporary directory to save the temporary download file. We do
|
| + // not want to use the default download directory since we do not want the
|
| + // twisted file name shown in the download shelf if the file with the same
|
| + // name already exists.
|
| + if (!file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome"),
|
| + &dir_path_))
|
| + return false;
|
| +
|
| + // DownloadManager could only be invoked from the UI thread.
|
| + ChromeThread::PostTask(
|
| + ChromeThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &DragDownloadFile::OnInitiateDownload,
|
| + dir_path_));
|
| +
|
| + return true;
|
| +}
|
| +
|
| +void DragDownloadFile::OnInitiateDownload(const FilePath& dir_path) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| +
|
| + download_manager_ = tab_contents_->profile()->GetDownloadManager();
|
| + download_manager_->AddObserver(this);
|
| +
|
| + // Start the download.
|
| + download_manager_->DownloadUrlToFile(url_,
|
| + referrer_,
|
| + referrer_encoding_,
|
| + dir_path,
|
| + tab_contents_);
|
| +}
|
| +
|
| +void DragDownloadFile::InitiateDownloadSucceeded(
|
| + const std::vector<OSExchangeData::DownloadFileInfo*>& downloads) {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + // Notify the drag-and-drop observer about the file info.
|
| + DCHECK(observer_);
|
| + observer_->OnDataReady(format_, downloads);
|
| +
|
| + InitiateDownloadCompleted(true);
|
| +}
|
| +
|
| +void DragDownloadFile::InitiateDownloadFailed() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + InitiateDownloadCompleted(false);
|
| +}
|
| +
|
| +void DragDownloadFile::InitiateDownloadCompleted(bool result) {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + // Release the observer since we do not need it any more.
|
| + observer_ = NULL;
|
| +
|
| + initiate_download_result_ = result;
|
| + QuitNestedMessageLoopIfNeeded();
|
| +}
|
| +
|
| +void DragDownloadFile::StartNestedMessageLoop() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + bool old_state = MessageLoop::current()->NestableTasksAllowed();
|
| + MessageLoop::current()->SetNestableTasksAllowed(true);
|
| + is_running_nested_message_loop_ = true;
|
| + MessageLoop::current()->Run();
|
| + MessageLoop::current()->SetNestableTasksAllowed(old_state);
|
| +}
|
| +
|
| +void DragDownloadFile::QuitNestedMessageLoopIfNeeded() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + if (is_running_nested_message_loop_) {
|
| + is_running_nested_message_loop_ = false;
|
| + MessageLoop::current()->Quit();
|
| + }
|
| +}
|
| +
|
| +void DragDownloadFile::ModelChanged() {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| +
|
| + download_manager_->GetTemporaryDownloads(this, dir_path_);
|
| +}
|
| +
|
| +void DragDownloadFile::SetDownloads(std::vector<DownloadItem*>& downloads) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| +
|
| + std::vector<DownloadItem*>::const_iterator it = downloads.begin();
|
| + for (; it != downloads.end(); ++it) {
|
| + if (!download_item_observer_added_ && (*it)->url() == url_) {
|
| + download_item_observer_added_ = true;
|
| + (*it)->AddObserver(this);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void DragDownloadFile::OnDownloadUpdated(DownloadItem* download) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| +
|
| + if (download->state() == DownloadItem::CANCELLED) {
|
| + download->RemoveObserver(this);
|
| + download_manager_->RemoveObserver(this);
|
| +
|
| + drag_message_loop_->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &DragDownloadFile::DownloadCancelled));
|
| + }
|
| +}
|
| +
|
| +void DragDownloadFile::OnDownloadFileCompleted(DownloadItem* download) {
|
| + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
|
| + DCHECK(download->state() == DownloadItem::COMPLETE);
|
| +
|
| + download->RemoveObserver(this);
|
| + download_manager_->RemoveObserver(this);
|
| +
|
| + drag_message_loop_->PostTask(
|
| + FROM_HERE,
|
| + NewRunnableMethod(this,
|
| + &DragDownloadFile::DownloadCompleted,
|
| + download->full_path()));
|
| +}
|
| +
|
| +void DragDownloadFile::DownloadCancelled() {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + InitiateDownloadFailed();
|
| +}
|
| +
|
| +void DragDownloadFile::DownloadCompleted(const FilePath& file_path) {
|
| + DCHECK(drag_message_loop_ == MessageLoop::current());
|
| +
|
| + file_path_ = file_path;
|
| +
|
| + // The download has been successfully initiated.
|
| + std::vector<OSExchangeData::DownloadFileInfo*> downloads;
|
| + downloads.push_back(
|
| + new OSExchangeData::DownloadFileInfo(file_path, 0, NULL));
|
| + InitiateDownloadSucceeded(downloads);
|
| +}
|
|
|
| Property changes on: chrome\browser\download\drag_download_file_win.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|