Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system / open_file_operation.cc
blob6f4e9bdd2b72343d64cde96de557e1ae00a26d42
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/task_runner_util.h"
14 #include "chrome/browser/chromeos/drive/drive.pb.h"
15 #include "chrome/browser/chromeos/drive/file_cache.h"
16 #include "chrome/browser/chromeos/drive/file_errors.h"
17 #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
18 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
19 #include "chrome/browser/chromeos/drive/file_system/operation_delegate.h"
20 #include "chrome/browser/chromeos/drive/job_scheduler.h"
21 #include "content/public/browser/browser_thread.h"
23 using content::BrowserThread;
25 namespace drive {
26 namespace file_system {
28 OpenFileOperation::OpenFileOperation(
29 base::SequencedTaskRunner* blocking_task_runner,
30 OperationDelegate* delegate,
31 JobScheduler* scheduler,
32 internal::ResourceMetadata* metadata,
33 internal::FileCache* cache,
34 const base::FilePath& temporary_file_directory)
35 : blocking_task_runner_(blocking_task_runner),
36 delegate_(delegate),
37 cache_(cache),
38 create_file_operation_(new CreateFileOperation(
39 blocking_task_runner, delegate, metadata)),
40 download_operation_(new DownloadOperation(
41 blocking_task_runner, delegate, scheduler,
42 metadata, cache, temporary_file_directory)),
43 weak_ptr_factory_(this) {
46 OpenFileOperation::~OpenFileOperation() {
49 void OpenFileOperation::OpenFile(const base::FilePath& file_path,
50 OpenMode open_mode,
51 const std::string& mime_type,
52 const OpenFileCallback& callback) {
53 DCHECK_CURRENTLY_ON(BrowserThread::UI);
54 DCHECK(!callback.is_null());
56 switch (open_mode) {
57 case OPEN_FILE:
58 // It is not necessary to create a new file even if not exists.
59 // So call OpenFileAfterCreateFile directly with FILE_ERROR_OK
60 // to skip file creation.
61 OpenFileAfterCreateFile(file_path, callback, FILE_ERROR_OK);
62 break;
63 case CREATE_FILE:
64 create_file_operation_->CreateFile(
65 file_path,
66 true, // exclusive: fail if already exists
67 mime_type,
68 base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
69 weak_ptr_factory_.GetWeakPtr(), file_path, callback));
70 break;
71 case OPEN_OR_CREATE_FILE:
72 create_file_operation_->CreateFile(
73 file_path,
74 false, // not-exclusive
75 mime_type,
76 base::Bind(&OpenFileOperation::OpenFileAfterCreateFile,
77 weak_ptr_factory_.GetWeakPtr(), file_path, callback));
78 break;
82 void OpenFileOperation::OpenFileAfterCreateFile(
83 const base::FilePath& file_path,
84 const OpenFileCallback& callback,
85 FileError error) {
86 DCHECK_CURRENTLY_ON(BrowserThread::UI);
87 DCHECK(!callback.is_null());
89 if (error != FILE_ERROR_OK) {
90 callback.Run(error, base::FilePath(), base::Closure());
91 return;
94 download_operation_->EnsureFileDownloadedByPath(
95 file_path,
96 ClientContext(USER_INITIATED),
97 GetFileContentInitializedCallback(),
98 google_apis::GetContentCallback(),
99 base::Bind(
100 &OpenFileOperation::OpenFileAfterFileDownloaded,
101 weak_ptr_factory_.GetWeakPtr(), callback));
104 void OpenFileOperation::OpenFileAfterFileDownloaded(
105 const OpenFileCallback& callback,
106 FileError error,
107 const base::FilePath& local_file_path,
108 scoped_ptr<ResourceEntry> entry) {
109 DCHECK_CURRENTLY_ON(BrowserThread::UI);
110 DCHECK(!callback.is_null());
112 if (error == FILE_ERROR_OK) {
113 DCHECK(entry);
114 DCHECK(entry->has_file_specific_info());
115 if (entry->file_specific_info().is_hosted_document())
116 // No support for opening a hosted document.
117 error = FILE_ERROR_INVALID_OPERATION;
120 if (error != FILE_ERROR_OK) {
121 callback.Run(error, base::FilePath(), base::Closure());
122 return;
125 scoped_ptr<base::ScopedClosureRunner>* file_closer =
126 new scoped_ptr<base::ScopedClosureRunner>;
127 base::PostTaskAndReplyWithResult(
128 blocking_task_runner_.get(),
129 FROM_HERE,
130 base::Bind(&internal::FileCache::OpenForWrite,
131 base::Unretained(cache_),
132 entry->local_id(),
133 file_closer),
134 base::Bind(&OpenFileOperation::OpenFileAfterOpenForWrite,
135 weak_ptr_factory_.GetWeakPtr(),
136 local_file_path,
137 entry->local_id(),
138 callback,
139 base::Owned(file_closer)));
142 void OpenFileOperation::OpenFileAfterOpenForWrite(
143 const base::FilePath& local_file_path,
144 const std::string& local_id,
145 const OpenFileCallback& callback,
146 scoped_ptr<base::ScopedClosureRunner>* file_closer,
147 FileError error) {
148 DCHECK_CURRENTLY_ON(BrowserThread::UI);
149 DCHECK(!callback.is_null());
151 if (error != FILE_ERROR_OK) {
152 callback.Run(error, base::FilePath(), base::Closure());
153 return;
156 ++open_files_[local_id];
157 callback.Run(error, local_file_path,
158 base::Bind(&OpenFileOperation::CloseFile,
159 weak_ptr_factory_.GetWeakPtr(),
160 local_id,
161 base::Passed(file_closer)));
164 void OpenFileOperation::CloseFile(
165 const std::string& local_id,
166 scoped_ptr<base::ScopedClosureRunner> file_closer) {
167 DCHECK_CURRENTLY_ON(BrowserThread::UI);
168 DCHECK_GT(open_files_[local_id], 0);
170 if (--open_files_[local_id] == 0) {
171 // All clients closes this file, so notify to upload the file.
172 open_files_.erase(local_id);
173 delegate_->OnEntryUpdatedByOperation(ClientContext(USER_INITIATED),
174 local_id);
176 // Clients may have enlarged the file. By FreeDiskpSpaceIfNeededFor(0),
177 // we try to ensure (0 + the-minimum-safe-margin = 512MB as of now) space.
178 blocking_task_runner_->PostTask(
179 FROM_HERE,
180 base::Bind(base::IgnoreResult(
181 base::Bind(&internal::FileCache::FreeDiskSpaceIfNeededFor,
182 base::Unretained(cache_),
183 0))));
187 } // namespace file_system
188 } // namespace drive