From 44f75f1a6bc4da8ea136e7b08db64c5cdd03ac3e Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 4 Mar 2022 13:56:30 -0500 Subject: [PATCH] alloy: Fix PDF download 'With your changes' (fixes issue #3169) --- .../file_system/cef_file_system_delegate.cc | 73 +++++++++++++++++-- .../file_system/cef_file_system_delegate.h | 10 +++ 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/libcef/browser/extensions/api/file_system/cef_file_system_delegate.cc b/libcef/browser/extensions/api/file_system/cef_file_system_delegate.cc index 07d59607a..f3283f85b 100644 --- a/libcef/browser/extensions/api/file_system/cef_file_system_delegate.cc +++ b/libcef/browser/extensions/api/file_system/cef_file_system_delegate.cc @@ -4,12 +4,18 @@ #include "libcef/browser/extensions/api/file_system/cef_file_system_delegate.h" +#include "libcef/browser/alloy/alloy_dialog_util.h" + #include "apps/saved_files_service.h" #include "base/callback.h" #include "base/callback_forward.h" #include "base/files/file_path.h" +#include "chrome/grit/generated_resources.h" #include "extensions/common/api/file_system.h" #include "extensions/common/extension.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using blink::mojom::FileChooserParams; namespace extensions { namespace cef { @@ -35,15 +41,66 @@ bool CefFileSystemDelegate::ShowSelectFileDialog( const ui::SelectFileDialog::FileTypeInfo* file_types, FileSystemDelegate::FilesSelectedCallback files_selected_callback, base::OnceClosure file_selection_canceled_callback) { - NOTIMPLEMENTED(); + auto web_contents = extension_function->GetSenderWebContents(); + if (!web_contents) { + return false; + } - // Run the cancel callback by default. - std::move(file_selection_canceled_callback).Run(); + absl::optional mode; + switch (type) { + case ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER: + mode = FileChooserParams::Mode::kUploadFolder; + break; + case ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE: + mode = FileChooserParams::Mode::kSave; + break; + case ui::SelectFileDialog::Type::SELECT_OPEN_FILE: + mode = FileChooserParams::Mode::kOpen; + break; + case ui::SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE: + mode = FileChooserParams::Mode::kOpenMultiple; + break; + default: + NOTIMPLEMENTED(); + return false; + } + + FileChooserParams params; + params.mode = *mode; + params.default_file_name = default_path; + if (file_types) { + // A list of allowed extensions. For example, it might be + // { { "htm", "html" }, { "txt" } } + for (auto& vec : file_types->extensions) { + for (auto& ext : vec) { + params.accept_types.push_back( + alloy::FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext)); + } + } + } + + alloy::RunFileChooser( + web_contents, params, + base::BindOnce(&CefFileSystemDelegate::FileDialogDismissed, + weak_ptr_factory_.GetWeakPtr(), + std::move(files_selected_callback), + std::move(file_selection_canceled_callback))); - // Return true since this isn't a disallowed call, just not implemented. return true; } +void CefFileSystemDelegate::FileDialogDismissed( + FileSystemDelegate::FilesSelectedCallback files_selected_callback, + base::OnceClosure file_selection_canceled_callback, + int selected_accept_filter, + const std::vector& file_paths) { + if (!file_paths.empty()) { + std::move(files_selected_callback).Run(file_paths); + } else { + std::move(file_selection_canceled_callback).Run(); + } +} + void CefFileSystemDelegate::ConfirmSensitiveDirectoryAccess( bool has_write_permission, const std::u16string& app_name, @@ -56,9 +113,15 @@ void CefFileSystemDelegate::ConfirmSensitiveDirectoryAccess( std::move(on_cancel).Run(); } +// Based on ChromeFileSystemDelegate::GetDescriptionIdForAcceptType. int CefFileSystemDelegate::GetDescriptionIdForAcceptType( const std::string& accept_type) { - NOTIMPLEMENTED(); + if (accept_type == "image/*") + return IDS_IMAGE_FILES; + if (accept_type == "audio/*") + return IDS_AUDIO_FILES; + if (accept_type == "video/*") + return IDS_VIDEO_FILES; return 0; } diff --git a/libcef/browser/extensions/api/file_system/cef_file_system_delegate.h b/libcef/browser/extensions/api/file_system/cef_file_system_delegate.h index 910c6e106..1d469ff70 100644 --- a/libcef/browser/extensions/api/file_system/cef_file_system_delegate.h +++ b/libcef/browser/extensions/api/file_system/cef_file_system_delegate.h @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "extensions/browser/api/execute_code_function.h" #include "extensions/browser/api/file_system/file_system_delegate.h" #include "extensions/browser/extension_function.h" @@ -50,6 +51,15 @@ class CefFileSystemDelegate : public FileSystemDelegate { int GetDescriptionIdForAcceptType(const std::string& accept_type) override; SavedFilesServiceInterface* GetSavedFilesService( content::BrowserContext* browser_context) override; + + private: + void FileDialogDismissed( + FileSystemDelegate::FilesSelectedCallback files_selected_callback, + base::OnceClosure file_selection_canceled_callback, + int selected_accept_filter, + const std::vector& file_paths); + + base::WeakPtrFactory weak_ptr_factory_{this}; }; } // namespace cef