12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/download_handler.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/supports_user_data.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/drive/drive_integration_service.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_interface.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/chromeos/drive/write_on_cache_file.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/download/download_history.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/download/download_service.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/download/download_service_factory.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::DownloadManager; 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::DownloadItem; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace drive { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Key for base::SupportsUserData::Data. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDrivePathKey[] = "DrivePath"; 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// User Data stored in DownloadItem for drive path. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DriveUserData : public base::SupportsUserData::Data { 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit DriveUserData(const base::FilePath& path) : file_path_(path), 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch is_complete_(false) {} 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~DriveUserData() {} 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path() const { return file_path_; } 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::FilePath& cache_file_path() const { return cache_file_path_; } 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void set_cache_file_path(const base::FilePath& path) { 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cache_file_path_ = path; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_complete() const { return is_complete_; } 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_complete() { is_complete_ = true; } 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath file_path_; 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::FilePath cache_file_path_; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_complete_; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Extracts DriveUserData* from |download|. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const DriveUserData* GetDriveUserData(const DownloadItem* download) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<const DriveUserData*>( 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetUserData(&kDrivePathKey)); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveUserData* GetDriveUserData(DownloadItem* download) { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<DriveUserData*>(download->GetUserData(&kDrivePathKey)); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Creates a temporary file |drive_tmp_download_path| in 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |drive_tmp_download_dir|. Must be called on a thread that allows file 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// operations. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetDriveTempDownloadPath( 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_tmp_download_dir) { 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool created = base::CreateDirectory(drive_tmp_download_dir); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(created) << "Can not create temp download directory at " 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << drive_tmp_download_dir.value(); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath drive_tmp_download_path; 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) created = base::CreateTemporaryFileInDir(drive_tmp_download_dir, 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &drive_tmp_download_path); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(created) << "Temporary download file creation failed"; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return drive_tmp_download_path; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Moves downloaded file to Drive. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MoveDownloadedFile(const base::FilePath& downloaded_file, 79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::FilePath* cache_file_path, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& dest_path) { 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (error != FILE_ERROR_OK || 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !base::Move(downloaded_file, dest_path)) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *cache_file_path = dest_path; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to implement CheckForFileExistence(). 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContinueCheckingForFileExistence( 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::CheckForFileExistenceCallback& callback, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ResourceEntry> entry) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(error == FILE_ERROR_OK); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns true if |download| is a Drive download created from data persisted 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on the download history DB. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsPersistedDriveDownload(const base::FilePath& drive_tmp_download_path, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download) { 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!drive_tmp_download_path.IsParent(download->GetTargetFilePath())) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DownloadService* download_service = 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DownloadServiceFactory::GetForBrowserContext( 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) download->GetBrowserContext()); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DownloadHistory* download_history = download_service->GetDownloadHistory(); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return download_history && download_history->WasRestoredFromHistory(download); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)DownloadHandler::DownloadHandler(FileSystemInterface* file_system) 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : file_system_(file_system), 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DownloadHandler::~DownloadHandler() { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DownloadHandler* DownloadHandler::GetForProfile(Profile* profile) { 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DriveIntegrationService* service = 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DriveIntegrationServiceFactory::FindForProfile(profile); 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!service || !service->IsMounted()) 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return NULL; 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return service->download_handler(); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::Initialize( 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadManager* download_manager, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_tmp_download_path) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!drive_tmp_download_path.empty()); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) drive_tmp_download_path_ = drive_tmp_download_path; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (download_manager) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) notifier_.reset(new AllDownloadItemNotifier(download_manager, this)); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove any persisted Drive DownloadItem. crbug.com/171384 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadManager::DownloadVector downloads; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_manager->GetAllDownloads(&downloads); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < downloads.size(); ++i) { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsPersistedDriveDownload(drive_tmp_download_path_, downloads[i])) 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) downloads[i]->Remove(); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DownloadHandler::ObserveIncognitoDownloadManager( 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DownloadManager* download_manager) { 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) notifier_incognito_.reset(new AllDownloadItemNotifier(download_manager, 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this)); 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::SubstituteDriveDownloadPath( 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& drive_path, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DownloadItem* download, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SubstituteDriveDownloadPathCallback& callback) { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "SubstituteDriveDownloadPath " << drive_path.value(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetDownloadParams(drive_path, download); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (util::IsUnderDriveMountPoint(drive_path)) { 164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Prepare the destination directory. 165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const bool is_exclusive = false, is_recursive = true; 166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) file_system_->CreateDirectory( 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) util::ExtractDrivePath(drive_path.DirName()), 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) is_exclusive, is_recursive, 169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&DownloadHandler::OnCreateDirectory, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(drive_path); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::SetDownloadParams(const base::FilePath& drive_path, 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DownloadItem* download) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (util::IsUnderDriveMountPoint(drive_path)) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->SetUserData(&kDrivePathKey, new DriveUserData(drive_path)); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->SetDisplayName(drive_path.BaseName()); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (IsDriveDownload(download)) { 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This may have been previously set if the default download folder is 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // /drive, and the user has now changed the download target to a local 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // folder. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->SetUserData(&kDrivePathKey, NULL); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->SetDisplayName(base::FilePath()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::FilePath DownloadHandler::GetTargetPath( 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadItem* download) { 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DriveUserData* data = GetDriveUserData(download); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If data is NULL, we've somehow lost the drive path selected by the file 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // picker. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(data); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return data ? data->file_path() : base::FilePath(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::FilePath DownloadHandler::GetCacheFilePath(const DownloadItem* download) { 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const DriveUserData* data = GetDriveUserData(download); 205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return data ? data->cache_file_path() : base::FilePath(); 206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DownloadHandler::IsDriveDownload(const DownloadItem* download) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We use the existence of the DriveUserData object in download as a 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // signal that this is a download to Drive. 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetDriveUserData(download) != NULL; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::CheckForFileExistence( 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DownloadItem* download, 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::CheckForFileExistenceCallback& callback) { 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) file_system_->GetResourceEntry( 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) util::ExtractDrivePath(GetTargetPath(download)), 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ContinueCheckingForFileExistence, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback)); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::OnDownloadCreated(DownloadManager* manager, 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DownloadItem* download) { 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove any persisted Drive DownloadItem. crbug.com/171384 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsPersistedDriveDownload(drive_tmp_download_path_, download)) { 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove download later, since doing it here results in a crash. 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask(BrowserThread::UI, 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&DownloadHandler::RemoveDownload, 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<void*>(manager), 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->GetId())); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DownloadHandler::RemoveDownload(void* manager_id, int id) { 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DownloadManager* manager = GetDownloadManager(manager_id); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!manager) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadItem* download = manager->GetDownload(id); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!download) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->Remove(); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::OnDownloadUpdated( 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DownloadManager* manager, DownloadItem* download) { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only accept downloads that have the Drive meta data associated with them. 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DriveUserData* data = GetDriveUserData(download); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!drive_tmp_download_path_.IsParent(download->GetTargetFilePath()) || 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !data || 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data->is_complete()) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (download->GetState()) { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DownloadItem::IN_PROGRESS: 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DownloadItem::COMPLETE: 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) UploadDownloadItem(manager, download); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data->set_complete(); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case DownloadItem::CANCELLED: 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download->SetUserData(&kDrivePathKey, NULL); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case DownloadItem::INTERRUPTED: 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Interrupted downloads can be resumed. Keep the Drive user data around 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // so that it can be used when the download resumes. The download is truly 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // done when it's complete, is cancelled or is removed. 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DownloadHandler::OnCreateDirectory( 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SubstituteDriveDownloadPathCallback& callback, 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileError error) { 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "OnCreateDirectory " << FileErrorToString(error); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (error == FILE_ERROR_OK) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PostTaskAndReplyWithResult( 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::GetBlockingPool(), 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GetDriveTempDownloadPath, drive_tmp_download_path_), 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << "Failed to create directory, error = " 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << FileErrorToString(error); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(base::FilePath()); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DownloadHandler::UploadDownloadItem(DownloadManager* manager, 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DownloadItem* download) { 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK_EQ(DownloadItem::COMPLETE, download->GetState()); 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::FilePath* cache_file_path = new base::FilePath; 303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WriteOnCacheFileAndReply( 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) file_system_, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) util::ExtractDrivePath(GetTargetPath(download)), 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) download->GetMimeType(), 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&MoveDownloadedFile, download->GetTargetFilePath(), 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cache_file_path), 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Bind(&DownloadHandler::SetCacheFilePath, 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) static_cast<void*>(manager), 312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) download->GetId(), 313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Owned(cache_file_path))); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void DownloadHandler::SetCacheFilePath(void* manager_id, 31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) int id, 318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::FilePath* cache_file_path, 319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FileError error) { 320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (error != FILE_ERROR_OK) 321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DownloadManager* manager = GetDownloadManager(manager_id); 323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!manager) 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 325a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DownloadItem* download = manager->GetDownload(id); 326a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!download) 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 328a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DriveUserData* data = GetDriveUserData(download); 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!data) 330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) data->set_cache_file_path(*cache_file_path); 332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)DownloadManager* DownloadHandler::GetDownloadManager(void* manager_id) { 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (manager_id == notifier_->GetManager()) 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return notifier_->GetManager(); 33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (notifier_incognito_ && manager_id == notifier_incognito_->GetManager()) 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return notifier_incognito_->GetManager(); 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return NULL; 34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace drive 343