| 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 #include "chrome/browser/extensions/api/file_system/file_system_api.h" | 5 #include "chrome/browser/extensions/api/file_system/file_system_api.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 using fileapi::IsolatedContext; | 33 using fileapi::IsolatedContext; |
| 34 | 34 |
| 35 const char kInvalidParameters[] = "Invalid parameters"; | 35 const char kInvalidParameters[] = "Invalid parameters"; |
| 36 const char kSecurityError[] = "Security error"; | 36 const char kSecurityError[] = "Security error"; |
| 37 const char kInvalidCallingPage[] = "Invalid calling page"; | 37 const char kInvalidCallingPage[] = "Invalid calling page"; |
| 38 const char kUserCancelled[] = "User cancelled"; | 38 const char kUserCancelled[] = "User cancelled"; |
| 39 const char kWritableFileError[] = "Invalid file for writing"; | 39 const char kWritableFileError[] = "Invalid file for writing"; |
| 40 const char kRequiresFileSystemWriteError[] = | 40 const char kRequiresFileSystemWriteError[] = |
| 41 "Operation requires fileSystemWrite permission"; | 41 "Operation requires fileSystemWrite permission"; |
| 42 const char kUnknownChooseFileType[] = "Unknown type"; | 42 const char kUnknownChooseEntryType[] = "Unknown type"; |
| 43 | 43 |
| 44 const char kOpenFileOption[] = "openFile"; | 44 const char kOpenFileOption[] = "openFile"; |
| 45 const char kOpenWritableFileOption[] ="openWritableFile"; | 45 const char kOpenWritableFileOption[] ="openWritableFile"; |
| 46 const char kSaveFileOption[] = "saveFile"; | 46 const char kSaveFileOption[] = "saveFile"; |
| 47 | 47 |
| 48 namespace file_system = extensions::api::file_system; | 48 namespace file_system = extensions::api::file_system; |
| 49 namespace ChooseFile = file_system::ChooseFile; | 49 namespace ChooseEntry = file_system::ChooseEntry; |
| 50 | 50 |
| 51 namespace { | 51 namespace { |
| 52 | 52 |
| 53 struct RewritePair { | 53 struct RewritePair { |
| 54 int path_key; | 54 int path_key; |
| 55 const char* output; | 55 const char* output; |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 const RewritePair g_rewrite_pairs[] = { | 58 const RewritePair g_rewrite_pairs[] = { |
| 59 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 dict->SetString("baseName", registered_name); | 274 dict->SetString("baseName", registered_name); |
| 275 SendResponse(true); | 275 SendResponse(true); |
| 276 } | 276 } |
| 277 | 277 |
| 278 void FileSystemEntryFunction::HandleWritableFileError() { | 278 void FileSystemEntryFunction::HandleWritableFileError() { |
| 279 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 279 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 280 error_ = kWritableFileError; | 280 error_ = kWritableFileError; |
| 281 SendResponse(false); | 281 SendResponse(false); |
| 282 } | 282 } |
| 283 | 283 |
| 284 bool FileSystemGetWritableFileEntryFunction::RunImpl() { | 284 bool FileSystemGetWritableEntryFunction::RunImpl() { |
| 285 std::string filesystem_name; | 285 std::string filesystem_name; |
| 286 std::string filesystem_path; | 286 std::string filesystem_path; |
| 287 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); | 287 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); |
| 288 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); | 288 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); |
| 289 | 289 |
| 290 if (!HasFileSystemWritePermission()) { | 290 if (!HasFileSystemWritePermission()) { |
| 291 error_ = kRequiresFileSystemWriteError; | 291 error_ = kRequiresFileSystemWriteError; |
| 292 return false; | 292 return false; |
| 293 } | 293 } |
| 294 | 294 |
| 295 FilePath path; | 295 FilePath path; |
| 296 if (!GetFilePathOfFileEntry(filesystem_name, filesystem_path, | 296 if (!GetFilePathOfFileEntry(filesystem_name, filesystem_path, |
| 297 render_view_host_, &path, &error_)) | 297 render_view_host_, &path, &error_)) |
| 298 return false; | 298 return false; |
| 299 | 299 |
| 300 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, | 300 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
| 301 base::Bind(&FileSystemGetWritableFileEntryFunction::CheckWritableFile, | 301 base::Bind(&FileSystemGetWritableEntryFunction::CheckWritableFile, |
| 302 this, path)); | 302 this, path)); |
| 303 return true; | 303 return true; |
| 304 } | 304 } |
| 305 | 305 |
| 306 bool FileSystemIsWritableFileEntryFunction::RunImpl() { | 306 bool FileSystemIsWritableEntryFunction::RunImpl() { |
| 307 std::string filesystem_name; | 307 std::string filesystem_name; |
| 308 std::string filesystem_path; | 308 std::string filesystem_path; |
| 309 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); | 309 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &filesystem_name)); |
| 310 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); | 310 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &filesystem_path)); |
| 311 | 311 |
| 312 std::string filesystem_id; | 312 std::string filesystem_id; |
| 313 if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id)) { | 313 if (!fileapi::CrackIsolatedFileSystemName(filesystem_name, &filesystem_id)) { |
| 314 error_ = kInvalidParameters; | 314 error_ = kInvalidParameters; |
| 315 return false; | 315 return false; |
| 316 } | 316 } |
| 317 | 317 |
| 318 content::ChildProcessSecurityPolicy* policy = | 318 content::ChildProcessSecurityPolicy* policy = |
| 319 content::ChildProcessSecurityPolicy::GetInstance(); | 319 content::ChildProcessSecurityPolicy::GetInstance(); |
| 320 int renderer_id = render_view_host_->GetProcess()->GetID(); | 320 int renderer_id = render_view_host_->GetProcess()->GetID(); |
| 321 bool is_writable = policy->CanReadWriteFileSystem(renderer_id, | 321 bool is_writable = policy->CanReadWriteFileSystem(renderer_id, |
| 322 filesystem_id); | 322 filesystem_id); |
| 323 | 323 |
| 324 SetResult(base::Value::CreateBooleanValue(is_writable)); | 324 SetResult(base::Value::CreateBooleanValue(is_writable)); |
| 325 return true; | 325 return true; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Handles showing a dialog to the user to ask for the filename for a file to | 328 // Handles showing a dialog to the user to ask for the filename for a file to |
| 329 // save or open. | 329 // save or open. |
| 330 class FileSystemChooseFileFunction::FilePicker | 330 class FileSystemChooseEntryFunction::FilePicker |
| 331 : public ui::SelectFileDialog::Listener { | 331 : public ui::SelectFileDialog::Listener { |
| 332 public: | 332 public: |
| 333 FilePicker(FileSystemChooseFileFunction* function, | 333 FilePicker(FileSystemChooseEntryFunction* function, |
| 334 content::WebContents* web_contents, | 334 content::WebContents* web_contents, |
| 335 const FilePath& suggested_name, | 335 const FilePath& suggested_name, |
| 336 const ui::SelectFileDialog::FileTypeInfo& file_type_info, | 336 const ui::SelectFileDialog::FileTypeInfo& file_type_info, |
| 337 ui::SelectFileDialog::Type picker_type, | 337 ui::SelectFileDialog::Type picker_type, |
| 338 EntryType entry_type) | 338 EntryType entry_type) |
| 339 : suggested_name_(suggested_name), | 339 : suggested_name_(suggested_name), |
| 340 entry_type_(entry_type), | 340 entry_type_(entry_type), |
| 341 function_(function) { | 341 function_(function) { |
| 342 select_file_dialog_ = ui::SelectFileDialog::Create( | 342 select_file_dialog_ = ui::SelectFileDialog::Create( |
| 343 this, new ChromeSelectFilePolicy(web_contents)); | 343 this, new ChromeSelectFilePolicy(web_contents)); |
| 344 gfx::NativeWindow owning_window = web_contents ? | 344 gfx::NativeWindow owning_window = web_contents ? |
| 345 platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL; | 345 platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL; |
| 346 | 346 |
| 347 if (g_skip_picker_for_test) { | 347 if (g_skip_picker_for_test) { |
| 348 if (g_path_to_be_picked_for_test) { | 348 if (g_path_to_be_picked_for_test) { |
| 349 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 349 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 350 base::Bind( | 350 base::Bind( |
| 351 &FileSystemChooseFileFunction::FilePicker::FileSelected, | 351 &FileSystemChooseEntryFunction::FilePicker::FileSelected, |
| 352 base::Unretained(this), *g_path_to_be_picked_for_test, 1, | 352 base::Unretained(this), *g_path_to_be_picked_for_test, 1, |
| 353 static_cast<void*>(NULL))); | 353 static_cast<void*>(NULL))); |
| 354 } else { | 354 } else { |
| 355 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 355 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 356 base::Bind( | 356 base::Bind( |
| 357 &FileSystemChooseFileFunction::FilePicker:: | 357 &FileSystemChooseEntryFunction::FilePicker:: |
| 358 FileSelectionCanceled, | 358 FileSelectionCanceled, |
| 359 base::Unretained(this), static_cast<void*>(NULL))); | 359 base::Unretained(this), static_cast<void*>(NULL))); |
| 360 } | 360 } |
| 361 return; | 361 return; |
| 362 } | 362 } |
| 363 | 363 |
| 364 select_file_dialog_->SelectFile(picker_type, | 364 select_file_dialog_->SelectFile(picker_type, |
| 365 string16(), | 365 string16(), |
| 366 suggested_name, | 366 suggested_name, |
| 367 &file_type_info, 0, FILE_PATH_LITERAL(""), | 367 &file_type_info, 0, FILE_PATH_LITERAL(""), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 382 virtual void FileSelectionCanceled(void* params) OVERRIDE { | 382 virtual void FileSelectionCanceled(void* params) OVERRIDE { |
| 383 function_->FileSelectionCanceled(); | 383 function_->FileSelectionCanceled(); |
| 384 delete this; | 384 delete this; |
| 385 } | 385 } |
| 386 | 386 |
| 387 FilePath suggested_name_; | 387 FilePath suggested_name_; |
| 388 | 388 |
| 389 EntryType entry_type_; | 389 EntryType entry_type_; |
| 390 | 390 |
| 391 scoped_refptr<ui::SelectFileDialog> select_file_dialog_; | 391 scoped_refptr<ui::SelectFileDialog> select_file_dialog_; |
| 392 scoped_refptr<FileSystemChooseFileFunction> function_; | 392 scoped_refptr<FileSystemChooseEntryFunction> function_; |
| 393 | 393 |
| 394 DISALLOW_COPY_AND_ASSIGN(FilePicker); | 394 DISALLOW_COPY_AND_ASSIGN(FilePicker); |
| 395 }; | 395 }; |
| 396 | 396 |
| 397 bool FileSystemChooseFileFunction::ShowPicker( | 397 bool FileSystemChooseEntryFunction::ShowPicker( |
| 398 const FilePath& suggested_name, | 398 const FilePath& suggested_name, |
| 399 const ui::SelectFileDialog::FileTypeInfo& file_type_info, | 399 const ui::SelectFileDialog::FileTypeInfo& file_type_info, |
| 400 ui::SelectFileDialog::Type picker_type, | 400 ui::SelectFileDialog::Type picker_type, |
| 401 EntryType entry_type) { | 401 EntryType entry_type) { |
| 402 ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile()); | 402 ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile()); |
| 403 DCHECK(registry); | 403 DCHECK(registry); |
| 404 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( | 404 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost( |
| 405 render_view_host()); | 405 render_view_host()); |
| 406 if (!shell_window) { | 406 if (!shell_window) { |
| 407 error_ = kInvalidCallingPage; | 407 error_ = kInvalidCallingPage; |
| 408 return false; | 408 return false; |
| 409 } | 409 } |
| 410 | 410 |
| 411 // The file picker will hold a reference to this function instance, preventing | 411 // The file picker will hold a reference to this function instance, preventing |
| 412 // its destruction (and subsequent sending of the function response) until the | 412 // its destruction (and subsequent sending of the function response) until the |
| 413 // user has selected a file or cancelled the picker. At that point, the picker | 413 // user has selected a file or cancelled the picker. At that point, the picker |
| 414 // will delete itself, which will also free the function instance. | 414 // will delete itself, which will also free the function instance. |
| 415 new FilePicker(this, shell_window->web_contents(), suggested_name, | 415 new FilePicker(this, shell_window->web_contents(), suggested_name, |
| 416 file_type_info, picker_type, entry_type); | 416 file_type_info, picker_type, entry_type); |
| 417 return true; | 417 return true; |
| 418 } | 418 } |
| 419 | 419 |
| 420 // static | 420 // static |
| 421 void FileSystemChooseFileFunction::SkipPickerAndAlwaysSelectPathForTest( | 421 void FileSystemChooseEntryFunction::SkipPickerAndAlwaysSelectPathForTest( |
| 422 FilePath* path) { | 422 FilePath* path) { |
| 423 g_skip_picker_for_test = true; | 423 g_skip_picker_for_test = true; |
| 424 g_path_to_be_picked_for_test = path; | 424 g_path_to_be_picked_for_test = path; |
| 425 } | 425 } |
| 426 | 426 |
| 427 // static | 427 // static |
| 428 void FileSystemChooseFileFunction::SkipPickerAndAlwaysCancelForTest() { | 428 void FileSystemChooseEntryFunction::SkipPickerAndAlwaysCancelForTest() { |
| 429 g_skip_picker_for_test = true; | 429 g_skip_picker_for_test = true; |
| 430 g_path_to_be_picked_for_test = NULL; | 430 g_path_to_be_picked_for_test = NULL; |
| 431 } | 431 } |
| 432 | 432 |
| 433 // static | 433 // static |
| 434 void FileSystemChooseFileFunction::StopSkippingPickerForTest() { | 434 void FileSystemChooseEntryFunction::StopSkippingPickerForTest() { |
| 435 g_skip_picker_for_test = false; | 435 g_skip_picker_for_test = false; |
| 436 } | 436 } |
| 437 | 437 |
| 438 void FileSystemChooseFileFunction::FileSelected(const FilePath& path, | 438 void FileSystemChooseEntryFunction::FileSelected(const FilePath& path, |
| 439 EntryType entry_type) { | 439 EntryType entry_type) { |
| 440 if (entry_type == WRITABLE) { | 440 if (entry_type == WRITABLE) { |
| 441 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, | 441 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, |
| 442 base::Bind(&FileSystemChooseFileFunction::CheckWritableFile, | 442 base::Bind(&FileSystemChooseEntryFunction::CheckWritableFile, |
| 443 this, path)); | 443 this, path)); |
| 444 return; | 444 return; |
| 445 } | 445 } |
| 446 | 446 |
| 447 // Don't need to check the file, it's for reading. | 447 // Don't need to check the file, it's for reading. |
| 448 RegisterFileSystemAndSendResponse(path, READ_ONLY); | 448 RegisterFileSystemAndSendResponse(path, READ_ONLY); |
| 449 } | 449 } |
| 450 | 450 |
| 451 void FileSystemChooseFileFunction::FileSelectionCanceled() { | 451 void FileSystemChooseEntryFunction::FileSelectionCanceled() { |
| 452 error_ = kUserCancelled; | 452 error_ = kUserCancelled; |
| 453 SendResponse(false); | 453 SendResponse(false); |
| 454 } | 454 } |
| 455 | 455 |
| 456 void FileSystemChooseFileFunction::BuildFileTypeInfo( | 456 void FileSystemChooseEntryFunction::BuildFileTypeInfo( |
| 457 ui::SelectFileDialog::FileTypeInfo* file_type_info, | 457 ui::SelectFileDialog::FileTypeInfo* file_type_info, |
| 458 const FilePath::StringType& suggested_extension, | 458 const FilePath::StringType& suggested_extension, |
| 459 const AcceptOptions* accepts, | 459 const AcceptOptions* accepts, |
| 460 const bool* acceptsAllTypes) { | 460 const bool* acceptsAllTypes) { |
| 461 file_type_info->include_all_files = true; | 461 file_type_info->include_all_files = true; |
| 462 if (acceptsAllTypes) | 462 if (acceptsAllTypes) |
| 463 file_type_info->include_all_files = *acceptsAllTypes; | 463 file_type_info->include_all_files = *acceptsAllTypes; |
| 464 | 464 |
| 465 bool need_suggestion = !file_type_info->include_all_files && | 465 bool need_suggestion = !file_type_info->include_all_files && |
| 466 !suggested_extension.empty(); | 466 !suggested_extension.empty(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 } | 488 } |
| 489 | 489 |
| 490 // If there's nothing in our accepted extension list or we couldn't find the | 490 // If there's nothing in our accepted extension list or we couldn't find the |
| 491 // suggested extension required, then default to accepting all types. | 491 // suggested extension required, then default to accepting all types. |
| 492 if (file_type_info->extensions.empty() || need_suggestion) | 492 if (file_type_info->extensions.empty() || need_suggestion) |
| 493 file_type_info->include_all_files = true; | 493 file_type_info->include_all_files = true; |
| 494 } | 494 } |
| 495 | 495 |
| 496 void FileSystemChooseFileFunction::BuildSuggestion( | 496 void FileSystemChooseEntryFunction::BuildSuggestion( |
| 497 const std::string *opt_name, | 497 const std::string *opt_name, |
| 498 FilePath* suggested_name, | 498 FilePath* suggested_name, |
| 499 FilePath::StringType* suggested_extension) { | 499 FilePath::StringType* suggested_extension) { |
| 500 if (opt_name) { | 500 if (opt_name) { |
| 501 *suggested_name = FilePath::FromUTF8Unsafe(*opt_name); | 501 *suggested_name = FilePath::FromUTF8Unsafe(*opt_name); |
| 502 | 502 |
| 503 // Don't allow any path components; shorten to the base name. This should | 503 // Don't allow any path components; shorten to the base name. This should |
| 504 // result in a relative path, but in some cases may not. Clear the | 504 // result in a relative path, but in some cases may not. Clear the |
| 505 // suggestion for safety if this is the case. | 505 // suggestion for safety if this is the case. |
| 506 *suggested_name = suggested_name->BaseName(); | 506 *suggested_name = suggested_name->BaseName(); |
| 507 if (suggested_name->IsAbsolute()) | 507 if (suggested_name->IsAbsolute()) |
| 508 *suggested_name = FilePath(); | 508 *suggested_name = FilePath(); |
| 509 | 509 |
| 510 *suggested_extension = suggested_name->Extension(); | 510 *suggested_extension = suggested_name->Extension(); |
| 511 if (!suggested_extension->empty()) | 511 if (!suggested_extension->empty()) |
| 512 suggested_extension->erase(suggested_extension->begin()); // drop the . | 512 suggested_extension->erase(suggested_extension->begin()); // drop the . |
| 513 } | 513 } |
| 514 } | 514 } |
| 515 | 515 |
| 516 bool FileSystemChooseFileFunction::RunImpl() { | 516 bool FileSystemChooseEntryFunction::RunImpl() { |
| 517 scoped_ptr<ChooseFile::Params> params(ChooseFile::Params::Create(*args_)); | 517 scoped_ptr<ChooseEntry::Params> params(ChooseEntry::Params::Create(*args_)); |
| 518 EXTENSION_FUNCTION_VALIDATE(params.get()); | 518 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 519 | 519 |
| 520 FilePath suggested_name; | 520 FilePath suggested_name; |
| 521 ui::SelectFileDialog::FileTypeInfo file_type_info; | 521 ui::SelectFileDialog::FileTypeInfo file_type_info; |
| 522 EntryType entry_type = READ_ONLY; | 522 EntryType entry_type = READ_ONLY; |
| 523 ui::SelectFileDialog::Type picker_type = | 523 ui::SelectFileDialog::Type picker_type = |
| 524 ui::SelectFileDialog::SELECT_OPEN_FILE; | 524 ui::SelectFileDialog::SELECT_OPEN_FILE; |
| 525 | 525 |
| 526 file_system::ChooseFileOptions* options = params->options.get(); | 526 file_system::ChooseEntryOptions* options = params->options.get(); |
| 527 if (options) { | 527 if (options) { |
| 528 if (options->type.get()) { | 528 if (options->type.get()) { |
| 529 if (*options->type == kOpenWritableFileOption) { | 529 if (*options->type == kOpenWritableFileOption) { |
| 530 entry_type = WRITABLE; | 530 entry_type = WRITABLE; |
| 531 } else if (*options->type == kSaveFileOption) { | 531 } else if (*options->type == kSaveFileOption) { |
| 532 entry_type = WRITABLE; | 532 entry_type = WRITABLE; |
| 533 picker_type = ui::SelectFileDialog::SELECT_SAVEAS_FILE; | 533 picker_type = ui::SelectFileDialog::SELECT_SAVEAS_FILE; |
| 534 } else if (*options->type != kOpenFileOption) { | 534 } else if (*options->type != kOpenFileOption) { |
| 535 error_ = kUnknownChooseFileType; | 535 error_ = kUnknownChooseEntryType; |
| 536 return false; | 536 return false; |
| 537 } | 537 } |
| 538 } | 538 } |
| 539 | 539 |
| 540 FilePath::StringType suggested_extension; | 540 FilePath::StringType suggested_extension; |
| 541 BuildSuggestion(options->suggested_name.get(), &suggested_name, | 541 BuildSuggestion(options->suggested_name.get(), &suggested_name, |
| 542 &suggested_extension); | 542 &suggested_extension); |
| 543 | 543 |
| 544 BuildFileTypeInfo(&file_type_info, suggested_extension, | 544 BuildFileTypeInfo(&file_type_info, suggested_extension, |
| 545 options->accepts.get(), options->accepts_all_types.get()); | 545 options->accepts.get(), options->accepts_all_types.get()); |
| 546 } | 546 } |
| 547 | 547 |
| 548 if (entry_type == WRITABLE && !HasFileSystemWritePermission()) { | 548 if (entry_type == WRITABLE && !HasFileSystemWritePermission()) { |
| 549 error_ = kRequiresFileSystemWriteError; | 549 error_ = kRequiresFileSystemWriteError; |
| 550 return false; | 550 return false; |
| 551 } | 551 } |
| 552 | 552 |
| 553 return ShowPicker(suggested_name, file_type_info, picker_type, entry_type); | 553 return ShowPicker(suggested_name, file_type_info, picker_type, entry_type); |
| 554 } | 554 } |
| 555 | 555 |
| 556 } // namespace extensions | 556 } // namespace extensions |
| OLD | NEW |