OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // The file contains the implementation of | 5 // The file contains the implementation of |
6 // fileBrowserHandlerInternal.selectFile extension function. | 6 // fileBrowserHandlerInternal.selectFile extension function. |
7 // When invoked, the function does the following: | 7 // When invoked, the function does the following: |
8 // - Verifies that the extension function was invoked as a result of user | 8 // - Verifies that the extension function was invoked as a result of user |
9 // gesture. | 9 // gesture. |
10 // - Display 'save as' dialog using FileSelectorImpl which waits for the user | 10 // - Display 'save as' dialog using FileSelectorImpl which waits for the user |
11 // feedback. | 11 // feedback. |
12 // - Once the user selects the file path (or cancels the selection), | 12 // - Once the user selects the file path (or cancels the selection), |
13 // FileSelectorImpl notifies FileHandlerSelectFileFunction of the selection | 13 // FileSelectorImpl notifies FileBrowserHandlerInternalSelectFileFunction of |
14 // result by calling FileHandlerSelectFile::OnFilePathSelected. | 14 // the selection result by calling FileHandlerSelectFile::OnFilePathSelected. |
15 // - If the selection was canceled, FileHandlerSelectFileFunction returns | 15 // - If the selection was canceled, |
16 // reporting failure. | 16 // FileBrowserHandlerInternalSelectFileFunction returns reporting failure. |
17 // - If the file path was selected, the function opens external file system | 17 // - If the file path was selected, the function opens external file system |
18 // needed to create FileEntry object for the selected path | 18 // needed to create FileEntry object for the selected path |
19 // (opening file system will create file system name and root url for the | 19 // (opening file system will create file system name and root url for the |
20 // caller's external file system). | 20 // caller's external file system). |
21 // - The function grants permissions needed to read/write/create file under the | 21 // - The function grants permissions needed to read/write/create file under the |
22 // selected path. To grant permissions to the caller, caller's extension ID | 22 // selected path. To grant permissions to the caller, caller's extension ID |
23 // has to be allowed to access the files virtual path (e.g. /Downloads/foo) | 23 // has to be allowed to access the files virtual path (e.g. /Downloads/foo) |
24 // in ExternalFileSystemMountPointProvider. Additionally, the callers render | 24 // in ExternalFileSystemMountPointProvider. Additionally, the callers render |
25 // process ID has to be granted read, write and create permissions for the | 25 // process ID has to be granted read, write and create permissions for the |
26 // selected file's full filesystem path (e.g. | 26 // selected file's full filesystem path (e.g. |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 112 |
113 protected: | 113 protected: |
114 // file_handler::FileSelectr overrides. | 114 // file_handler::FileSelectr overrides. |
115 // Shows save as dialog with suggested name in window bound to |browser|. | 115 // Shows save as dialog with suggested name in window bound to |browser|. |
116 // |allowed_extensions| specifies the file extensions allowed to be shown, | 116 // |allowed_extensions| specifies the file extensions allowed to be shown, |
117 // and selected. Extensions should not include '.'. | 117 // and selected. Extensions should not include '.'. |
118 // | 118 // |
119 // After this method is called, the selector implementation should not be | 119 // After this method is called, the selector implementation should not be |
120 // deleted by the caller. It will delete itself after it receives response | 120 // deleted by the caller. It will delete itself after it receives response |
121 // from SelectFielDialog. | 121 // from SelectFielDialog. |
122 virtual void SelectFile(const FilePath& suggested_name, | 122 virtual void SelectFile( |
123 const std::vector<std::string>& allowed_extensions, | 123 const FilePath& suggested_name, |
124 Browser* browser, | 124 const std::vector<std::string>& allowed_extensions, |
125 FileHandlerSelectFileFunction* function) OVERRIDE; | 125 Browser* browser, |
| 126 FileBrowserHandlerInternalSelectFileFunction* function) OVERRIDE; |
126 | 127 |
127 // ui::SelectFileDialog::Listener overrides. | 128 // ui::SelectFileDialog::Listener overrides. |
128 virtual void FileSelected(const FilePath& path, | 129 virtual void FileSelected(const FilePath& path, |
129 int index, | 130 int index, |
130 void* params) OVERRIDE; | 131 void* params) OVERRIDE; |
131 virtual void MultiFilesSelected(const std::vector<FilePath>& files, | 132 virtual void MultiFilesSelected(const std::vector<FilePath>& files, |
132 void* params) OVERRIDE; | 133 void* params) OVERRIDE; |
133 virtual void FileSelectionCanceled(void* params) OVERRIDE; | 134 virtual void FileSelectionCanceled(void* params) OVERRIDE; |
134 | 135 |
135 private: | 136 private: |
(...skipping 15 matching lines...) Expand all Loading... |
151 // The |this| object is self destruct after the function is notified. | 152 // The |this| object is self destruct after the function is notified. |
152 // |success| indicates whether user has selectd the file. | 153 // |success| indicates whether user has selectd the file. |
153 // |selected_path| is path that was selected. It is empty if the file wasn't | 154 // |selected_path| is path that was selected. It is empty if the file wasn't |
154 // selected. | 155 // selected. |
155 void SendResponse(bool success, const FilePath& selected_path); | 156 void SendResponse(bool success, const FilePath& selected_path); |
156 | 157 |
157 // Dialog that is shown by selector. | 158 // Dialog that is shown by selector. |
158 scoped_refptr<ui::SelectFileDialog> dialog_; | 159 scoped_refptr<ui::SelectFileDialog> dialog_; |
159 | 160 |
160 // Extension function that uses the selector. | 161 // Extension function that uses the selector. |
161 scoped_refptr<FileHandlerSelectFileFunction> function_; | 162 scoped_refptr<FileBrowserHandlerInternalSelectFileFunction> function_; |
162 | 163 |
163 DISALLOW_COPY_AND_ASSIGN(FileSelectorImpl); | 164 DISALLOW_COPY_AND_ASSIGN(FileSelectorImpl); |
164 }; | 165 }; |
165 | 166 |
166 FileSelectorImpl::FileSelectorImpl() {} | 167 FileSelectorImpl::FileSelectorImpl() {} |
167 | 168 |
168 FileSelectorImpl::~FileSelectorImpl() { | 169 FileSelectorImpl::~FileSelectorImpl() { |
169 if (dialog_.get()) | 170 if (dialog_.get()) |
170 dialog_->ListenerDestroyed(); | 171 dialog_->ListenerDestroyed(); |
171 // Send response if needed. | 172 // Send response if needed. |
172 if (function_) | 173 if (function_) |
173 SendResponse(false, FilePath()); | 174 SendResponse(false, FilePath()); |
174 } | 175 } |
175 | 176 |
176 void FileSelectorImpl::SelectFile( | 177 void FileSelectorImpl::SelectFile( |
177 const FilePath& suggested_name, | 178 const FilePath& suggested_name, |
178 const std::vector<std::string>& allowed_extensions, | 179 const std::vector<std::string>& allowed_extensions, |
179 Browser* browser, | 180 Browser* browser, |
180 FileHandlerSelectFileFunction* function) { | 181 FileBrowserHandlerInternalSelectFileFunction* function) { |
181 // We will hold reference to the function until it is notified of selection | 182 // We will hold reference to the function until it is notified of selection |
182 // result. | 183 // result. |
183 function_ = function; | 184 function_ = function; |
184 | 185 |
185 if (!StartSelectFile(suggested_name, allowed_extensions, browser)) { | 186 if (!StartSelectFile(suggested_name, allowed_extensions, browser)) { |
186 // If the dialog wasn't launched, let's asynchronously report failure to the | 187 // If the dialog wasn't launched, let's asynchronously report failure to the |
187 // function. | 188 // function. |
188 base::MessageLoopProxy::current()->PostTask(FROM_HERE, | 189 base::MessageLoopProxy::current()->PostTask(FROM_HERE, |
189 base::Bind(&FileSelectorImpl::FileSelectionCanceled, | 190 base::Bind(&FileSelectorImpl::FileSelectionCanceled, |
190 base::Unretained(this), reinterpret_cast<void*>(NULL))); | 191 base::Unretained(this), reinterpret_cast<void*>(NULL))); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 const FileSystemOpenCallback& callback, | 283 const FileSystemOpenCallback& callback, |
283 base::PlatformFileError error, | 284 base::PlatformFileError error, |
284 const std::string& file_system_name, | 285 const std::string& file_system_name, |
285 const GURL& file_system_root) { | 286 const GURL& file_system_root) { |
286 bool success = (error == base::PLATFORM_FILE_OK); | 287 bool success = (error == base::PLATFORM_FILE_OK); |
287 callback.Run(success, file_system_name, file_system_root); | 288 callback.Run(success, file_system_name, file_system_root); |
288 } | 289 } |
289 | 290 |
290 } // namespace | 291 } // namespace |
291 | 292 |
292 FileHandlerSelectFileFunction::FileHandlerSelectFileFunction() | 293 FileBrowserHandlerInternalSelectFileFunction:: |
293 : file_selector_factory_(new FileSelectorFactoryImpl()), | 294 FileBrowserHandlerInternalSelectFileFunction() |
294 user_gesture_check_enabled_(true) { | 295 : file_selector_factory_(new FileSelectorFactoryImpl()), |
| 296 user_gesture_check_enabled_(true) { |
295 } | 297 } |
296 | 298 |
297 FileHandlerSelectFileFunction::FileHandlerSelectFileFunction( | 299 FileBrowserHandlerInternalSelectFileFunction:: |
298 FileSelectorFactory* file_selector_factory, | 300 FileBrowserHandlerInternalSelectFileFunction( |
299 bool enable_user_gesture_check) | 301 FileSelectorFactory* file_selector_factory, |
300 : file_selector_factory_(file_selector_factory), | 302 bool enable_user_gesture_check) |
301 user_gesture_check_enabled_(enable_user_gesture_check) { | 303 : file_selector_factory_(file_selector_factory), |
| 304 user_gesture_check_enabled_(enable_user_gesture_check) { |
302 DCHECK(file_selector_factory); | 305 DCHECK(file_selector_factory); |
303 } | 306 } |
304 | 307 |
305 FileHandlerSelectFileFunction::~FileHandlerSelectFileFunction() {} | 308 FileBrowserHandlerInternalSelectFileFunction:: |
| 309 ~FileBrowserHandlerInternalSelectFileFunction() {} |
306 | 310 |
307 bool FileHandlerSelectFileFunction::RunImpl() { | 311 bool FileBrowserHandlerInternalSelectFileFunction::RunImpl() { |
308 scoped_ptr<SelectFile::Params> params(SelectFile::Params::Create(*args_)); | 312 scoped_ptr<SelectFile::Params> params(SelectFile::Params::Create(*args_)); |
309 | 313 |
310 FilePath suggested_name(params->selection_params.suggested_name); | 314 FilePath suggested_name(params->selection_params.suggested_name); |
311 std::vector<std::string> allowed_extensions; | 315 std::vector<std::string> allowed_extensions; |
312 if (params->selection_params.allowed_file_extensions.get()) | 316 if (params->selection_params.allowed_file_extensions.get()) |
313 allowed_extensions = *params->selection_params.allowed_file_extensions; | 317 allowed_extensions = *params->selection_params.allowed_file_extensions; |
314 | 318 |
315 if (!user_gesture() && user_gesture_check_enabled_) { | 319 if (!user_gesture() && user_gesture_check_enabled_) { |
316 error_ = kNoUserGestureError; | 320 error_ = kNoUserGestureError; |
317 return false; | 321 return false; |
318 } | 322 } |
319 | 323 |
320 FileSelector* file_selector = file_selector_factory_->CreateFileSelector(); | 324 FileSelector* file_selector = file_selector_factory_->CreateFileSelector(); |
321 file_selector->SelectFile(suggested_name.BaseName(), | 325 file_selector->SelectFile(suggested_name.BaseName(), |
322 allowed_extensions, | 326 allowed_extensions, |
323 GetCurrentBrowser(), | 327 GetCurrentBrowser(), |
324 this); | 328 this); |
325 return true; | 329 return true; |
326 } | 330 } |
327 | 331 |
328 void FileHandlerSelectFileFunction::OnFilePathSelected( | 332 void FileBrowserHandlerInternalSelectFileFunction::OnFilePathSelected( |
329 bool success, | 333 bool success, |
330 const FilePath& full_path) { | 334 const FilePath& full_path) { |
331 if (!success) { | 335 if (!success) { |
332 Respond(false); | 336 Respond(false); |
333 return; | 337 return; |
334 } | 338 } |
335 | 339 |
336 full_path_ = full_path; | 340 full_path_ = full_path; |
337 | 341 |
338 // We have to open file system in order to create a FileEntry object for the | 342 // We have to open file system in order to create a FileEntry object for the |
339 // selected file path. | 343 // selected file path. |
340 BrowserContext::GetDefaultStoragePartition(profile_)-> | 344 BrowserContext::GetDefaultStoragePartition(profile_)-> |
341 GetFileSystemContext()->OpenFileSystem( | 345 GetFileSystemContext()->OpenFileSystem( |
342 source_url_.GetOrigin(), fileapi::kFileSystemTypeExternal, false, | 346 source_url_.GetOrigin(), fileapi::kFileSystemTypeExternal, false, |
343 base::Bind( | 347 base::Bind( |
344 &RunOpenFileSystemCallback, | 348 &RunOpenFileSystemCallback, |
345 base::Bind(&FileHandlerSelectFileFunction::OnFileSystemOpened, | 349 base::Bind(&FileBrowserHandlerInternalSelectFileFunction:: |
| 350 OnFileSystemOpened, |
346 this))); | 351 this))); |
347 }; | 352 }; |
348 | 353 |
349 void FileHandlerSelectFileFunction::OnFileSystemOpened( | 354 void FileBrowserHandlerInternalSelectFileFunction::OnFileSystemOpened( |
350 bool success, | 355 bool success, |
351 const std::string& file_system_name, | 356 const std::string& file_system_name, |
352 const GURL& file_system_root) { | 357 const GURL& file_system_root) { |
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 358 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
354 | 359 |
355 if (!success) { | 360 if (!success) { |
356 Respond(false); | 361 Respond(false); |
357 return; | 362 return; |
358 } | 363 } |
359 | 364 |
360 // Remember opened file system's parameters. | 365 // Remember opened file system's parameters. |
361 file_system_name_ = file_system_name; | 366 file_system_name_ = file_system_name; |
362 file_system_root_ = file_system_root; | 367 file_system_root_ = file_system_root; |
363 | 368 |
364 GrantPermissions(); | 369 GrantPermissions(); |
365 } | 370 } |
366 | 371 |
367 void FileHandlerSelectFileFunction::GrantPermissions() { | 372 void FileBrowserHandlerInternalSelectFileFunction::GrantPermissions() { |
368 fileapi::ExternalFileSystemMountPointProvider* external_provider = | 373 fileapi::ExternalFileSystemMountPointProvider* external_provider = |
369 BrowserContext::GetDefaultStoragePartition(profile_)-> | 374 BrowserContext::GetDefaultStoragePartition(profile_)-> |
370 GetFileSystemContext()->external_provider(); | 375 GetFileSystemContext()->external_provider(); |
371 DCHECK(external_provider); | 376 DCHECK(external_provider); |
372 | 377 |
373 external_provider->GetVirtualPath(full_path_, &virtual_path_); | 378 external_provider->GetVirtualPath(full_path_, &virtual_path_); |
374 DCHECK(!virtual_path_.empty()); | 379 DCHECK(!virtual_path_.empty()); |
375 | 380 |
376 // Grant access to this particular file to target extension. This will | 381 // Grant access to this particular file to target extension. This will |
377 // ensure that the target extension can access only this FS entry and | 382 // ensure that the target extension can access only this FS entry and |
(...skipping 15 matching lines...) Expand all Loading... |
393 | 398 |
394 // For drive files, we also have to grant permissions for drive cache paths | 399 // For drive files, we also have to grant permissions for drive cache paths |
395 // under which the selected path could be kept. | 400 // under which the selected path could be kept. |
396 scoped_ptr<std::vector<FilePath> > gdata_paths(new std::vector<FilePath>()); | 401 scoped_ptr<std::vector<FilePath> > gdata_paths(new std::vector<FilePath>()); |
397 gdata_paths->push_back(virtual_path_); | 402 gdata_paths->push_back(virtual_path_); |
398 | 403 |
399 drive::util::InsertDriveCachePathsPermissions( | 404 drive::util::InsertDriveCachePathsPermissions( |
400 profile(), | 405 profile(), |
401 gdata_paths.Pass(), | 406 gdata_paths.Pass(), |
402 &permissions_to_grant_, | 407 &permissions_to_grant_, |
403 base::Bind(&FileHandlerSelectFileFunction::OnGotPermissionsToGrant, | 408 base::Bind(&FileBrowserHandlerInternalSelectFileFunction:: |
| 409 OnGotPermissionsToGrant, |
404 this)); | 410 this)); |
405 } | 411 } |
406 | 412 |
407 void FileHandlerSelectFileFunction::OnGotPermissionsToGrant() { | 413 void FileBrowserHandlerInternalSelectFileFunction::OnGotPermissionsToGrant() { |
408 // At this point all needed permissions should be collected, so let's grant | 414 // At this point all needed permissions should be collected, so let's grant |
409 // them. | 415 // them. |
410 for (size_t i = 0; i < permissions_to_grant_.size(); i++) { | 416 for (size_t i = 0; i < permissions_to_grant_.size(); i++) { |
411 content::ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( | 417 content::ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( |
412 render_view_host()->GetProcess()->GetID(), | 418 render_view_host()->GetProcess()->GetID(), |
413 permissions_to_grant_[i].first, | 419 permissions_to_grant_[i].first, |
414 permissions_to_grant_[i].second); | 420 permissions_to_grant_[i].second); |
415 } | 421 } |
416 | 422 |
417 Respond(true); | 423 Respond(true); |
418 } | 424 } |
419 | 425 |
420 void FileHandlerSelectFileFunction::Respond(bool success) { | 426 void FileBrowserHandlerInternalSelectFileFunction::Respond(bool success) { |
421 scoped_ptr<SelectFile::Results::Result> result( | 427 scoped_ptr<SelectFile::Results::Result> result( |
422 new SelectFile::Results::Result()); | 428 new SelectFile::Results::Result()); |
423 result->success = success; | 429 result->success = success; |
424 | 430 |
425 // If the file was selected, add 'entry' object which will be later used to | 431 // If the file was selected, add 'entry' object which will be later used to |
426 // create a FileEntry instance for the selected file. | 432 // create a FileEntry instance for the selected file. |
427 if (success) { | 433 if (success) { |
428 result->entry.reset(new FileEntryInfo()); | 434 result->entry.reset(new FileEntryInfo()); |
429 result->entry->file_system_name = file_system_name_; | 435 result->entry->file_system_name = file_system_name_; |
430 result->entry->file_system_root = file_system_root_.spec(); | 436 result->entry->file_system_root = file_system_root_.spec(); |
431 result->entry->file_full_path = "/" + virtual_path_.value(); | 437 result->entry->file_full_path = "/" + virtual_path_.value(); |
432 result->entry->file_is_directory = false; | 438 result->entry->file_is_directory = false; |
433 } | 439 } |
434 | 440 |
435 results_ = SelectFile::Results::Create(*result); | 441 results_ = SelectFile::Results::Create(*result); |
436 SendResponse(true); | 442 SendResponse(true); |
437 } | 443 } |
OLD | NEW |