| 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 |