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 |