Use Chrome file dialogs on all platforms and runtimes (fixes issue #3314)

All file dialogs irrespective of source, platform and runtime will now be
routed through CefFileDialogManager and trigger CefDialogHandler callbacks
(see issue #3293).

Adds Chrome runtime support for CefBrowserHost::RunFileDialog and
CefDialogHandler callbacks.

Adds Alloy runtime support for internal GTK file and print dialogs on Linux
subject to the following limitations:

1. Internal GTK implementation:
   - Cannot be used with multi-threaded-message-loop because Chromium's
     internal GTK implementation is not thread-safe (does not use GDK threads).
   - Dialogs will not be modal to application windows when used with off-screen
     rendering due to lack of access to the client's top-level GtkWindow.
2. Cefclient CefDialogHandler implementation:
   - Cannot be used with Views because it requires a top-level GtkWindow.

Due to the above limitations no dialog implementation is currently provided for
Views + multi-threaded-message-loop on Linux. In cases where both
implementations are supported the cefclient version is now behind an optional
`--use-client-dialogs` command-line flag.

Expressly forbids multiple simultaneous file dialogs with the internal platform
implementation which uses modal dialogs. CefDialogHandler will still be notified
and can optionally handle each request without a modal dialog (see issue #3154).

Removes some RunFileDialog parameters that are not supported by the Chrome file
dialog implementation (selected_accept_filter parameter, cef_file_dialog_mode_t
overwrite/read-only flags).
This commit is contained in:
Marshall Greenblatt
2022-04-15 15:55:23 -04:00
parent edef01f579
commit 2ea7459a89
75 changed files with 1566 additions and 2231 deletions

View File

@@ -135,159 +135,6 @@ index f6098966f5b34..da78289b66155 100644
#endif
}
diff --git chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
index 86e16795ce43d..9053975ad42f6 100644
--- chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
+++ chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -21,6 +21,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/runtime.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_prefs.h"
@@ -62,6 +63,10 @@
#include "chromeos/lacros/lacros_service.h"
#endif
+#if BUILDFLAG(ENABLE_CEF)
+#include "cef/libcef/browser/alloy/alloy_dialog_util.h"
+#endif
+
namespace printing {
namespace {
@@ -414,16 +419,18 @@ void PdfPrinterHandler::SelectFile(const base::FilePath& default_filename,
service->GetRemote<crosapi::mojom::DriveIntegrationService>()
->GetMountPointPath(
base::BindOnce(&PdfPrinterHandler::OnSaveLocationReady,
- weak_ptr_factory_.GetWeakPtr(),
+ weak_ptr_factory_.GetWeakPtr(), initiator,
std::move(default_filename), prompt_user));
return;
}
#endif
- OnSaveLocationReady(default_filename, prompt_user, GetSaveLocation());
+ OnSaveLocationReady(initiator, default_filename, prompt_user,
+ GetSaveLocation());
}
void PdfPrinterHandler::OnSaveLocationReady(
+ content::WebContents* initiator,
const base::FilePath& default_filename,
bool prompt_user,
const base::FilePath& path) {
@@ -441,10 +448,27 @@ void PdfPrinterHandler::OnSaveLocationReady(
// If the directory is empty there is no reason to create it or use the
// default location.
if (path.empty()) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef::IsAlloyRuntimeEnabled()) {
+ ShowCefSaveAsDialog(initiator, default_filename, path);
+ return;
+ }
+#endif
OnDirectorySelected(default_filename, path);
return;
}
+ auto callback = base::BindOnce(&PdfPrinterHandler::OnDirectorySelected,
+ weak_ptr_factory_.GetWeakPtr(),
+ default_filename);
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef::IsAlloyRuntimeEnabled()) {
+ callback = base::BindOnce(&PdfPrinterHandler::ShowCefSaveAsDialog,
+ weak_ptr_factory_.GetWeakPtr(), initiator,
+ default_filename);
+ }
+#endif
+
// Get default download directory. This will be used as a fallback if the
// save directory does not exist.
DownloadPrefs* download_prefs = DownloadPrefs::FromBrowserContext(profile_);
@@ -452,8 +476,7 @@ void PdfPrinterHandler::OnSaveLocationReady(
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
base::BindOnce(&SelectSaveDirectory, path, default_path),
- base::BindOnce(&PdfPrinterHandler::OnDirectorySelected,
- weak_ptr_factory_.GetWeakPtr(), default_filename));
+ std::move(callback));
}
void PdfPrinterHandler::PostPrintToPdfTask() {
@@ -499,6 +522,36 @@ void PdfPrinterHandler::OnDirectorySelected(const base::FilePath& filename,
platform_util::GetTopLevel(preview_web_contents_->GetNativeView()), NULL);
}
+#if BUILDFLAG(ENABLE_CEF)
+
+void PdfPrinterHandler::ShowCefSaveAsDialog(content::WebContents* initiator,
+ const base::FilePath& filename,
+ const base::FilePath& directory) {
+ base::FilePath path = directory.Append(filename);
+
+ blink::mojom::FileChooserParams params;
+ params.mode = blink::mojom::FileChooserParams::Mode::kSave;
+ params.default_file_name = path;
+ params.accept_types.push_back(
+ alloy::FilePathTypeToString16(path.Extension()));
+
+ alloy::RunFileChooser(initiator, params,
+ base::BindOnce(&PdfPrinterHandler::SaveAsDialogDismissed,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PdfPrinterHandler::SaveAsDialogDismissed(
+ int selected_accept_filter,
+ const std::vector<base::FilePath>& file_paths) {
+ if (file_paths.size() == 1) {
+ FileSelected(file_paths[0], 0, nullptr);
+ } else {
+ FileSelectionCanceled(nullptr);
+ }
+}
+
+#endif // BUILDFLAG(ENABLE_CEF)
+
base::FilePath PdfPrinterHandler::GetSaveLocation() const {
#if BUILDFLAG(IS_CHROMEOS_ASH)
drive::DriveIntegrationService* drive_service =
diff --git chrome/browser/ui/webui/print_preview/pdf_printer_handler.h chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
index 46c8b1d08b075..1ee95cd7c3240 100644
--- chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
+++ chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/ui/webui/print_preview/printer_handler.h"
#include "ui/shell_dialogs/select_file_dialog.h"
@@ -95,10 +96,20 @@ class PdfPrinterHandler : public PrinterHandler,
void OnDirectorySelected(const base::FilePath& filename,
const base::FilePath& directory);
- void OnSaveLocationReady(const base::FilePath& default_filename,
+ void OnSaveLocationReady(content::WebContents* initiator,
+ const base::FilePath& default_filename,
bool prompt_user,
const base::FilePath& path);
+#if BUILDFLAG(ENABLE_CEF)
+ void ShowCefSaveAsDialog(content::WebContents* initiator,
+ const base::FilePath& filename,
+ const base::FilePath& directory);
+
+ void SaveAsDialogDismissed(int selected_accept_filter,
+ const std::vector<base::FilePath>& file_paths);
+#endif
+
// Return save location as the Drive mount or fetch from Download Preferences.
base::FilePath GetSaveLocation() const;
diff --git chrome/browser/ui/webui/print_preview/print_preview_ui.cc chrome/browser/ui/webui/print_preview/print_preview_ui.cc
index eba14d78d87ff..7901f000a44b5 100644
--- chrome/browser/ui/webui/print_preview/print_preview_ui.cc