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