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