1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/extensions/file_manager/private_api_file_system.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <sys/statvfs.h>
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/posix/eintr_wrapper.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/stringprintf.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/task_runner_util.h"
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/browser_process.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h"
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_interface.h"
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/chromeos/extensions/file_manager/event_router.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/chromeos/extensions/file_manager/event_router_factory.h"
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/chromeos/file_manager/volume_manager.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/api/file_manager_private.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/api/file_manager_private_internal.h"
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chromeos/disks/disk_mount_manager.h"
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/escape.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_file_util.h"
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h"
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_info.h"
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_types.h"
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using chromeos::disks::DiskMountManager;
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using content::BrowserThread;
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using content::ChildProcessSecurityPolicy;
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using file_manager::util::EntryDefinition;
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using file_manager::util::FileDefinition;
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemURL;
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace extensions {
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Retrieves total and remaining available size on |mount_path|.
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void GetSizeStatsOnBlockingPool(const std::string& mount_path,
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                uint64* total_size,
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                uint64* remaining_size) {
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  struct statvfs stat = {};  // Zero-clear
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (HANDLE_EINTR(statvfs(mount_path.c_str(), &stat)) == 0) {
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *total_size = static_cast<uint64>(stat.f_blocks) * stat.f_frsize;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *remaining_size = static_cast<uint64>(stat.f_bavail) * stat.f_frsize;
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Retrieves the maximum file name length of the file system of |path|.
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Returns 0 if it could not be queried.
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)size_t GetFileNameMaxLengthOnBlockingPool(const std::string& path) {
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  struct statvfs stat = {};
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (HANDLE_EINTR(statvfs(path.c_str(), &stat)) != 0) {
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // The filesystem seems not supporting statvfs(). Assume it to be a commonly
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // used bound 255, and log the failure.
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    LOG(ERROR) << "Cannot statvfs() the name length limit for: " << path;
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return 255;
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return stat.f_namemax;
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Returns EventRouter for the |profile_id| if available.
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)file_manager::EventRouter* GetEventRouterByProfileId(void* profile_id) {
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // |profile_id| needs to be checked with ProfileManager::IsValidProfile
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // before using it.
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Profile* profile = reinterpret_cast<Profile*>(profile_id);
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!g_browser_process->profile_manager()->IsValidProfile(profile))
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return NULL;
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return file_manager::EventRouterFactory::GetForProfile(profile);
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Notifies the copy progress to extensions via event router.
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void NotifyCopyProgress(
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void* profile_id,
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperationRunner::OperationID operation_id,
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperation::CopyProgressType type,
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& source_url,
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& destination_url,
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 size) {
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  file_manager::EventRouter* event_router =
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      GetEventRouterByProfileId(profile_id);
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (event_router) {
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    event_router->OnCopyProgress(
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        operation_id, type,
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        source_url.ToGURL(), destination_url.ToGURL(), size);
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Callback invoked periodically on progress update of Copy().
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void OnCopyProgress(
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void* profile_id,
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperationRunner::OperationID* operation_id,
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperation::CopyProgressType type,
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& source_url,
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& destination_url,
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int64 size) {
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  BrowserThread::PostTask(
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(&NotifyCopyProgress,
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 profile_id, *operation_id, type,
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 source_url, destination_url, size));
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Notifies the copy completion to extensions via event router.
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void NotifyCopyCompletion(
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    void* profile_id,
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperationRunner::OperationID operation_id,
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& source_url,
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& destination_url,
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  file_manager::EventRouter* event_router =
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      GetEventRouterByProfileId(profile_id);
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (event_router)
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    event_router->OnCopyCompleted(
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        operation_id,
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        source_url.ToGURL(), destination_url.ToGURL(), error);
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Callback invoked upon completion of Copy() (regardless of succeeded or
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// failed).
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void OnCopyCompleted(
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    void* profile_id,
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperationRunner::OperationID* operation_id,
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& source_url,
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& destination_url,
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error) {
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BrowserThread::PostTask(
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&NotifyCopyCompletion,
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 profile_id, *operation_id,
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                 source_url, destination_url, error));
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Starts the copy operation via FileSystemOperationRunner.
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemOperationRunner::OperationID StartCopyOnIOThread(
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    void* profile_id,
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context,
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const FileSystemURL& source_url,
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const FileSystemURL& destination_url) {
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Note: |operation_id| is owned by the callback for
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // FileSystemOperationRunner::Copy(). It is always called in the next message
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // loop or later, so at least during this invocation it should alive.
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemOperationRunner::OperationID* operation_id =
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new storage::FileSystemOperationRunner::OperationID;
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  *operation_id = file_system_context->operation_runner()->Copy(
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      source_url,
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      destination_url,
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&OnCopyProgress, profile_id, base::Unretained(operation_id)),
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&OnCopyCompleted,
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 profile_id,
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Owned(operation_id),
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 source_url,
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 destination_url));
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return *operation_id;
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OnCopyCancelled(base::File::Error error) {
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We just ignore the status if the copy is actually cancelled or not,
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // because failing cancellation means the operation is not running now.
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DLOG_IF(WARNING, error != base::File::FILE_OK)
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      << "Failed to cancel copy: " << error;
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Cancels the running copy operation identified by |operation_id|.
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void CancelCopyOnIOThread(
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context,
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemOperationRunner::OperationID operation_id) {
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  file_system_context->operation_runner()->Cancel(
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      operation_id, base::Bind(&OnCopyCancelled));
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateRequestFileSystemFunction::DidFail(
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error_code) {
208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetError(base::StringPrintf("File error %d", static_cast<int>(error_code)));
211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SendResponse(false);
212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciFileManagerPrivateRequestFileSystemFunction::SetupFileSystemAccessPermissions(
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<storage::FileSystemContext> file_system_context,
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int child_id,
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    Profile* profile,
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    scoped_refptr<const extensions::Extension> extension) {
220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!extension.get())
223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Make sure that only component extension can access the entire
226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // local file system.
227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (extension_->location() != extensions::Manifest::COMPONENT) {
228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    NOTREACHED() << "Private method access by non-component extension "
229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 << extension->id();
230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::ExternalFileSystemBackend* backend =
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_context->external_backend();
235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!backend)
236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Grant full access to File API from this component extension.
239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  backend->GrantFullAccessToExtension(extension_->id());
240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Grant R/W file permissions to the renderer hosting component
242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // extension for all paths exposed by our local file system backend.
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<base::FilePath> root_dirs = backend->GetRootDirectories();
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (size_t i = 0; i < root_dirs.size(); ++i) {
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ChildProcessSecurityPolicy::GetInstance()->GrantCreateReadWriteFile(
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        child_id, root_dirs[i]);
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Grant R/W permissions to profile-specific directories (Drive, Downloads)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // from other profiles. Those directories may not be mounted at this moment
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // yet, so we need to do this separately from the above loop over
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GetRootDirectories().
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<Profile*>& profiles =
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      g_browser_process->profile_manager()->GetLoadedProfiles();
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < profiles.size(); ++i) {
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!profiles[i]->IsOffTheRecord()) {
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      file_manager::util::SetupProfileFileAccessPermissions(child_id,
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                            profiles[i]);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateRequestFileSystemFunction::RunAsync() {
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private::RequestFileSystem::Params;
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!dispatcher() || !render_view_host() || !render_view_host()->GetProcess())
272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  set_log_on_completion(true);
275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  using file_manager::VolumeManager;
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  using file_manager::VolumeInfo;
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  VolumeManager* volume_manager = VolumeManager::Get(GetProfile());
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!volume_manager)
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  VolumeInfo volume_info;
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!volume_manager->FindVolumeInfoById(params->volume_id, &volume_info)) {
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DidFail(base::File::FILE_ERROR_NOT_FOUND);
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile(), render_view_host());
291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Set up file permission access.
2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const int child_id = render_view_host()->GetProcess()->GetID();
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!SetupFileSystemAccessPermissions(
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          file_system_context, child_id, GetProfile(), extension())) {
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DidFail(base::File::FILE_ERROR_SECURITY);
2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FileDefinition file_definition;
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath(
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           GetProfile(),
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           extension_id(),
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           volume_info.mount_path,
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           &file_definition.virtual_path)) {
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DidFail(base::File::FILE_ERROR_INVALID_OPERATION);
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  file_definition.is_directory = true;
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  file_manager::util::ConvertFileDefinitionToEntryDefinition(
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetProfile(),
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      extension_id(),
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      file_definition,
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &FileManagerPrivateRequestFileSystemFunction::OnEntryDefinition,
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          this));
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateRequestFileSystemFunction::OnEntryDefinition(
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const EntryDefinition& entry_definition) {
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (entry_definition.error != base::File::FILE_OK) {
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DidFail(entry_definition.error);
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!entry_definition.is_directory) {
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DidFail(base::File::FILE_ERROR_NOT_A_DIRECTORY);
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* dict = new base::DictionaryValue();
3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SetResult(dict);
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dict->SetString("name", entry_definition.file_system_name);
338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dict->SetString("root_url", entry_definition.file_system_root_url);
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->SetInteger("error", drive::FILE_ERROR_OK);
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SendResponse(true);
341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void FileWatchFunctionBase::Respond(bool success) {
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SetResult(new base::FundamentalValue(success));
347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SendResponse(success);
348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
350010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool FileWatchFunctionBase::RunAsync() {
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!render_view_host() || !render_view_host()->GetProcess())
354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // First param is url of a file to watch.
357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string url;
358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!args_->GetString(0, &url) || url.empty())
359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile(), render_view_host());
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemURL file_watch_url = file_system_context->CrackURL(GURL(url));
366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath local_path = file_watch_url.path();
367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath virtual_path = file_watch_url.virtual_path();
368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (local_path.empty()) {
369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Respond(false);
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return true;
371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PerformFileWatchOperation(local_path, virtual_path, extension_id());
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateAddFileWatchFunction::PerformFileWatchOperation(
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::FilePath& local_path,
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::FilePath& virtual_path,
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& extension_id) {
381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  file_manager::EventRouter* event_router =
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      file_manager::EventRouterFactory::GetForProfile(GetProfile());
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event_router->AddFileWatch(
386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      local_path,
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      virtual_path,
388a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      extension_id,
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&FileManagerPrivateAddFileWatchFunction::Respond, this));
390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateRemoveFileWatchFunction::PerformFileWatchOperation(
393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::FilePath& local_path,
394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const base::FilePath& unused,
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& extension_id) {
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  file_manager::EventRouter* event_router =
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      file_manager::EventRouterFactory::GetForProfile(GetProfile());
400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  event_router->RemoveFileWatch(local_path, extension_id);
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Respond(true);
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateGetSizeStatsFunction::RunAsync() {
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private::GetSizeStats::Params;
406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  using file_manager::VolumeManager;
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  using file_manager::VolumeInfo;
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VolumeManager* volume_manager = VolumeManager::Get(GetProfile());
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!volume_manager)
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VolumeInfo volume_info;
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!volume_manager->FindVolumeInfoById(params->volume_id, &volume_info))
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (volume_info.type == file_manager::VOLUME_TYPE_GOOGLE_DRIVE) {
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    drive::FileSystemInterface* file_system =
4211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        drive::util::GetFileSystemByProfile(GetProfile());
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (!file_system) {
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      // |file_system| is NULL if Drive is disabled.
424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // If stats couldn't be gotten for drive, result should be left
425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // undefined. See comments in GetDriveAvailableSpaceCallback().
426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      SendResponse(true);
427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return true;
428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    file_system->GetAvailableSpace(
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&FileManagerPrivateGetSizeStatsFunction::
432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                       GetDriveAvailableSpaceCallback,
433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   this));
434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  } else {
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    uint64* total_size = new uint64(0);
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    uint64* remaining_size = new uint64(0);
437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    BrowserThread::PostBlockingPoolTaskAndReply(
438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FROM_HERE,
439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::Bind(&GetSizeStatsOnBlockingPool,
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   volume_info.mount_path.value(),
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   total_size,
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   remaining_size),
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&FileManagerPrivateGetSizeStatsFunction::
444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                       GetSizeStatsCallback,
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   this,
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   base::Owned(total_size),
447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   base::Owned(remaining_size)));
448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateGetSizeStatsFunction::GetDriveAvailableSpaceCallback(
453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    drive::FileError error,
454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 bytes_total,
455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 bytes_used) {
456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (error == drive::FILE_ERROR_OK) {
457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const uint64 bytes_total_unsigned = bytes_total;
458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const uint64 bytes_remaining_unsigned = bytes_total - bytes_used;
459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    GetSizeStatsCallback(&bytes_total_unsigned,
460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         &bytes_remaining_unsigned);
461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  } else {
462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // If stats couldn't be gotten for drive, result should be left undefined.
463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SendResponse(true);
464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateGetSizeStatsFunction::GetSizeStatsCallback(
468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const uint64* total_size,
469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const uint64* remaining_size) {
470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::DictionaryValue* sizes = new base::DictionaryValue();
471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetResult(sizes);
472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sizes->SetDouble("totalSize", static_cast<double>(*total_size));
474a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sizes->SetDouble("remainingSize", static_cast<double>(*remaining_size));
475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SendResponse(true);
477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateValidatePathNameLengthFunction::RunAsync() {
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private::ValidatePathNameLength::Params;
481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
48403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile(), render_view_host());
487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL filesystem_url(
489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      file_system_context->CrackURL(GURL(params->parent_directory_url)));
490a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!chromeos::FileSystemBackend::CanHandleURL(filesystem_url))
491a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
492a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // No explicit limit on the length of Drive file names.
49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (filesystem_url.type() == storage::kFileSystemTypeDrive) {
495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetResult(new base::FundamentalValue(true));
496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SendResponse(true);
497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return true;
498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::PostTaskAndReplyWithResult(
501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      BrowserThread::GetBlockingPool(),
502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&GetFileNameMaxLengthOnBlockingPool,
504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 filesystem_url.path().AsUTF8Unsafe()),
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&FileManagerPrivateValidatePathNameLengthFunction::
506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                     OnFilePathLimitRetrieved,
507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                 this, params->name.size()));
508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateValidatePathNameLengthFunction::OnFilePathLimitRetrieved(
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    size_t current_length,
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    size_t max_length) {
514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SetResult(new base::FundamentalValue(current_length <= max_length));
515a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SendResponse(true);
516a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateFormatVolumeFunction::RunAsync() {
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private::FormatVolume::Params;
520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
521d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  using file_manager::VolumeManager;
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  using file_manager::VolumeInfo;
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VolumeManager* volume_manager = VolumeManager::Get(GetProfile());
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!volume_manager)
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  VolumeInfo volume_info;
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!volume_manager->FindVolumeInfoById(params->volume_id, &volume_info))
531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DiskMountManager::GetInstance()->FormatMountedDevice(
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      volume_info.mount_path.AsUTF8Unsafe());
535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SendResponse(true);
536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateStartCopyFunction::RunAsync() {
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using  extensions::api::file_manager_private::StartCopy::Params;
54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (params->source_url.empty() || params->parent.empty() ||
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      params->new_name.empty()) {
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Error code in format of DOMError.name.
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetError("EncodingError");
55058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
55158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
55258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
55458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
5551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile(), render_view_host());
55658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
557f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |parent| may have a trailing slash if it is a root directory.
558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string destination_url_string = params->parent;
559f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (destination_url_string[destination_url_string.size() - 1] != '/')
560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    destination_url_string += '/';
561f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  destination_url_string += net::EscapePath(params->new_name);
562f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
56303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL source_url(
56458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      file_system_context->CrackURL(GURL(params->source_url)));
56503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  storage::FileSystemURL destination_url(
566f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      file_system_context->CrackURL(GURL(destination_url_string)));
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!source_url.is_valid() || !destination_url.is_valid()) {
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Error code in format of DOMError.name.
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetError("EncodingError");
57158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
57258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
57358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
57458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return BrowserThread::PostTaskAndReplyWithResult(
57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BrowserThread::IO,
57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FROM_HERE,
57758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&StartCopyOnIOThread,
5781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 GetProfile(),
5791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 file_system_context,
5801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 source_url,
5811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 destination_url),
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&FileManagerPrivateStartCopyFunction::RunAfterStartCopy,
58358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 this));
58458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
58558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateStartCopyFunction::RunAfterStartCopy(
58758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int operation_id) {
58858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
58958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SetResult(new base::FundamentalValue(operation_id));
59158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SendResponse(true);
59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateCancelCopyFunction::RunAsync() {
59558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private::CancelCopy::Params;
59858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
59958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
60058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
60258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
6031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          GetProfile(), render_view_host());
60458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We don't much take care about the result of cancellation.
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BrowserThread::PostTask(
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      BrowserThread::IO,
60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      FROM_HERE,
60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      base::Bind(&CancelCopyOnIOThread, file_system_context, params->copy_id));
61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SendResponse(true);
61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool FileManagerPrivateInternalResolveIsolatedEntriesFunction::RunAsync() {
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private_internal::ResolveIsolatedEntries::
616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      Params;
617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const scoped_ptr<Params> params(Params::Create(*args_));
618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params);
619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_refptr<storage::FileSystemContext> file_system_context =
621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file_manager::util::GetFileSystemContextForRenderViewHost(
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          GetProfile(), render_view_host());
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(file_system_context.get());
624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
62503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const storage::ExternalFileSystemBackend* external_backend =
626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file_system_context->external_backend();
627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(external_backend);
628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_manager::util::FileDefinitionList file_definition_list;
630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < params->urls.size(); ++i) {
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FileSystemURL fileSystemUrl =
632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_system_context->CrackURL(GURL(params->urls[i]));
633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(external_backend->CanHandleType(fileSystemUrl.type()));
634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FileDefinition file_definition;
636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const bool result =
637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath(
638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            GetProfile(),
639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            extension_->id(),
640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            fileSystemUrl.path(),
641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            &file_definition.virtual_path);
642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!result)
643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The API only supports isolated files.
645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_definition.is_directory = false;
646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    file_definition_list.push_back(file_definition);
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  file_manager::util::ConvertFileDefinitionListToEntryDefinitionList(
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetProfile(),
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      extension_->id(),
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      file_definition_list,  // Safe, since copied internally.
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(
6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &FileManagerPrivateInternalResolveIsolatedEntriesFunction::
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              RunAsyncAfterConvertFileDefinitionListToEntryDefinitionList,
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          this));
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid FileManagerPrivateInternalResolveIsolatedEntriesFunction::
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RunAsyncAfterConvertFileDefinitionListToEntryDefinitionList(scoped_ptr<
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        file_manager::util::EntryDefinitionList> entry_definition_list) {
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using extensions::api::file_manager_private_internal::EntryDescription;
664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<linked_ptr<EntryDescription> > entries;
665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (size_t i = 0; i < entry_definition_list->size(); ++i) {
667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (entry_definition_list->at(i).error != base::File::FILE_OK)
668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      continue;
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    linked_ptr<EntryDescription> entry(new EntryDescription);
670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    entry->file_system_name = entry_definition_list->at(i).file_system_name;
671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    entry->file_system_root = entry_definition_list->at(i).file_system_root_url;
672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    entry->file_full_path =
673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "/" + entry_definition_list->at(i).full_path.AsUTF8Unsafe();
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    entry->file_is_directory = entry_definition_list->at(i).is_directory;
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    entries.push_back(entry);
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  results_ = extensions::api::file_manager_private_internal::
679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ResolveIsolatedEntries::Results::Create(entries);
680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SendResponse(true);
681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace extensions
683