OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/file_manager/filesystem_api_util.h" | 5 #include "chrome/browser/chromeos/file_manager/filesystem_api_util.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "chrome/browser/chromeos/drive/file_errors.h" | 10 #include "chrome/browser/chromeos/drive/file_errors.h" |
11 #include "chrome/browser/chromeos/drive/file_system_interface.h" | 11 #include "chrome/browser/chromeos/drive/file_system_interface.h" |
12 #include "chrome/browser/chromeos/drive/file_system_util.h" | 12 #include "chrome/browser/chromeos/drive/file_system_util.h" |
13 #include "chrome/browser/chromeos/file_manager/app_id.h" | 13 #include "chrome/browser/chromeos/file_manager/app_id.h" |
14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h" | 14 #include "chrome/browser/chromeos/file_manager/fileapi_util.h" |
15 #include "chrome/browser/extensions/extension_util.h" | 15 #include "chrome/browser/extensions/extension_util.h" |
16 #include "chrome/browser/profiles/profile.h" | 16 #include "chrome/browser/profiles/profile.h" |
17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
18 #include "content/public/browser/storage_partition.h" | 18 #include "content/public/browser/storage_partition.h" |
| 19 #include "google_apis/drive/task_util.h" |
19 #include "webkit/browser/fileapi/file_system_context.h" | 20 #include "webkit/browser/fileapi/file_system_context.h" |
20 | 21 |
21 namespace file_manager { | 22 namespace file_manager { |
22 namespace util { | 23 namespace util { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
| 27 // Helper function used to implement GetNonNativeLocalPathMimeType. It extracts |
| 28 // the mime type from the passed Drive resource entry. |
26 void GetMimeTypeAfterGetResourceEntry( | 29 void GetMimeTypeAfterGetResourceEntry( |
27 const base::Callback<void(bool, const std::string&)>& callback, | 30 const base::Callback<void(bool, const std::string&)>& callback, |
28 drive::FileError error, | 31 drive::FileError error, |
29 scoped_ptr<drive::ResourceEntry> entry) { | 32 scoped_ptr<drive::ResourceEntry> entry) { |
30 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 33 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
31 | 34 |
32 if (error != drive::FILE_ERROR_OK || !entry->has_file_specific_info()) { | 35 if (error != drive::FILE_ERROR_OK || !entry->has_file_specific_info()) { |
33 callback.Run(false, std::string()); | 36 callback.Run(false, std::string()); |
34 return; | 37 return; |
35 } | 38 } |
36 callback.Run(true, entry->file_specific_info().content_mime_type()); | 39 callback.Run(true, entry->file_specific_info().content_mime_type()); |
37 } | 40 } |
38 | 41 |
39 // Helper function to converts a callback that takes boolean value to that takes | 42 // Helper function to converts a callback that takes boolean value to that takes |
40 // File::Error, by regarding FILE_OK as the only successful value. | 43 // File::Error, by regarding FILE_OK as the only successful value. |
41 void BoolCallbackAsFileErrorCallback( | 44 void BoolCallbackAsFileErrorCallback( |
42 const base::Callback<void(bool)>& callback, | 45 const base::Callback<void(bool)>& callback, |
43 base::File::Error error) { | 46 base::File::Error error) { |
44 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
45 | |
46 return callback.Run(error == base::File::FILE_OK); | 47 return callback.Run(error == base::File::FILE_OK); |
47 } | 48 } |
48 | 49 |
49 void CheckWritableAfterDriveCheck(const base::Callback<void(bool)>& callback, | 50 // Part of PrepareFileOnIOThread. It tries to create a new file if the given |
50 drive::FileError error, | 51 // |url| is not already inhabited. |
51 const base::FilePath& local_path) { | 52 void PrepareFileAfterCheckExistOnIOThread( |
52 // This is called on the IO-allowed blocking pool. Call back to UI. | 53 scoped_refptr<fileapi::FileSystemContext> file_system_context, |
53 content::BrowserThread::PostTask( | 54 const fileapi::FileSystemURL& url, |
54 content::BrowserThread::UI, | 55 const fileapi::FileSystemOperation::StatusCallback& callback, |
55 FROM_HERE, | 56 base::File::Error error) { |
56 base::Bind(callback, error == drive::FILE_ERROR_OK)); | 57 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 58 |
| 59 if (error != base::File::FILE_ERROR_NOT_FOUND) { |
| 60 callback.Run(error); |
| 61 return; |
| 62 } |
| 63 |
| 64 // Call with the second argument |exclusive| set to false, meaning that it |
| 65 // is not an error even if the file already exists (it can happen if the file |
| 66 // is created after the previous FileExists call and before this CreateFile.) |
| 67 // |
| 68 // Note that the preceding call to FileExists is necessary for handling |
| 69 // read only filesystems that blindly rejects handling CreateFile(). |
| 70 file_system_context->operation_runner()->CreateFile(url, false, callback); |
| 71 } |
| 72 |
| 73 // Checks whether a file exists at the given |url|, and try creating it if it |
| 74 // is not already there. |
| 75 void PrepareFileOnIOThread( |
| 76 scoped_refptr<fileapi::FileSystemContext> file_system_context, |
| 77 const fileapi::FileSystemURL& url, |
| 78 const base::Callback<void(bool)>& callback) { |
| 79 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 80 |
| 81 file_system_context->operation_runner()->FileExists( |
| 82 url, |
| 83 base::Bind(&PrepareFileAfterCheckExistOnIOThread, |
| 84 file_system_context, |
| 85 url, |
| 86 base::Bind(&BoolCallbackAsFileErrorCallback, callback))); |
57 } | 87 } |
58 | 88 |
59 } // namespace | 89 } // namespace |
60 | 90 |
61 bool IsUnderNonNativeLocalPath(Profile* profile, | 91 bool IsUnderNonNativeLocalPath(Profile* profile, |
62 const base::FilePath& path) { | 92 const base::FilePath& path) { |
63 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 93 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
64 | 94 |
65 GURL url; | 95 GURL url; |
66 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( | 96 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 Profile* profile, | 151 Profile* profile, |
122 const base::FilePath& path, | 152 const base::FilePath& path, |
123 const base::Callback<void(bool)>& callback) { | 153 const base::Callback<void(bool)>& callback) { |
124 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 154 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
125 DCHECK(IsUnderNonNativeLocalPath(profile, path)); | 155 DCHECK(IsUnderNonNativeLocalPath(profile, path)); |
126 | 156 |
127 GURL url; | 157 GURL url; |
128 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( | 158 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( |
129 profile, path, kFileManagerAppId, &url)) { | 159 profile, path, kFileManagerAppId, &url)) { |
130 // Posting to the current thread, so that we always call back asynchronously | 160 // Posting to the current thread, so that we always call back asynchronously |
131 // independent from whether or not the operation succeeeds. | 161 // independent from whether or not the operation succeeds. |
132 content::BrowserThread::PostTask(content::BrowserThread::UI, | 162 content::BrowserThread::PostTask(content::BrowserThread::UI, |
133 FROM_HERE, | 163 FROM_HERE, |
134 base::Bind(callback, false)); | 164 base::Bind(callback, false)); |
135 return; | 165 return; |
136 } | 166 } |
137 | 167 |
138 util::CheckIfDirectoryExists( | 168 util::CheckIfDirectoryExists( |
139 GetFileSystemContextForExtensionId(profile, kFileManagerAppId), | 169 GetFileSystemContextForExtensionId(profile, kFileManagerAppId), |
140 url, | 170 url, |
141 base::Bind(&BoolCallbackAsFileErrorCallback, callback)); | 171 base::Bind(&BoolCallbackAsFileErrorCallback, callback)); |
142 } | 172 } |
143 | 173 |
144 void PrepareNonNativeLocalPathWritableFile( | 174 void PrepareNonNativeLocalPathWritableFile( |
145 Profile* profile, | 175 Profile* profile, |
146 const base::FilePath& path, | 176 const base::FilePath& path, |
147 const base::Callback<void(bool)>& callback) { | 177 const base::Callback<void(bool)>& callback) { |
148 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 178 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 179 DCHECK(IsUnderNonNativeLocalPath(profile, path)); |
149 | 180 |
150 // TODO(kinaba): support other types of volumes besides Drive. | 181 GURL url; |
151 drive::util::PrepareWritableFileAndRun( | 182 if (!util::ConvertAbsoluteFilePathToFileSystemUrl( |
152 profile, | 183 profile, path, kFileManagerAppId, &url)) { |
153 path, | 184 // Posting to the current thread, so that we always call back asynchronously |
154 base::Bind(&CheckWritableAfterDriveCheck, callback)); | 185 // independent from whether or not the operation succeeds. |
| 186 content::BrowserThread::PostTask(content::BrowserThread::UI, |
| 187 FROM_HERE, |
| 188 base::Bind(callback, false)); |
| 189 return; |
| 190 } |
| 191 |
| 192 fileapi::FileSystemContext* const context = |
| 193 GetFileSystemContextForExtensionId(profile, kFileManagerAppId); |
| 194 DCHECK(context); |
| 195 |
| 196 // Check the existence of a file using file system API implementation on |
| 197 // behalf of the file manager app. We need to grant access beforehand. |
| 198 context->external_backend()->GrantFullAccessToExtension(kFileManagerAppId); |
| 199 |
| 200 content::BrowserThread::PostTask( |
| 201 content::BrowserThread::IO, |
| 202 FROM_HERE, |
| 203 base::Bind(&PrepareFileOnIOThread, |
| 204 make_scoped_refptr(context), |
| 205 context->CrackURL(url), |
| 206 google_apis::CreateRelayCallback(callback))); |
155 } | 207 } |
156 | 208 |
157 } // namespace util | 209 } // namespace util |
158 } // namespace file_manager | 210 } // namespace file_manager |
OLD | NEW |