1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "libcef/browser/extensions/api/file_system/cef_file_system_delegate.h"
6
7 #include "libcef/browser/alloy/alloy_dialog_util.h"
8
9 #include "apps/saved_files_service.h"
10 #include "base/callback.h"
11 #include "base/callback_forward.h"
12 #include "base/files/file_path.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "extensions/common/api/file_system.h"
15 #include "extensions/common/extension.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17
18 using blink::mojom::FileChooserParams;
19
20 namespace extensions {
21 namespace cef {
22
23 CefFileSystemDelegate::CefFileSystemDelegate() = default;
24
25 CefFileSystemDelegate::~CefFileSystemDelegate() = default;
26
GetDefaultDirectory()27 base::FilePath CefFileSystemDelegate::GetDefaultDirectory() {
28 return base::FilePath();
29 }
30
GetManagedSaveAsDirectory(content::BrowserContext * browser_context,const Extension & extension)31 base::FilePath CefFileSystemDelegate::GetManagedSaveAsDirectory(
32 content::BrowserContext* browser_context,
33 const Extension& extension) {
34 return base::FilePath();
35 }
36
ShowSelectFileDialog(scoped_refptr<ExtensionFunction> extension_function,ui::SelectFileDialog::Type type,const base::FilePath & default_path,const ui::SelectFileDialog::FileTypeInfo * file_types,FileSystemDelegate::FilesSelectedCallback files_selected_callback,base::OnceClosure file_selection_canceled_callback)37 bool CefFileSystemDelegate::ShowSelectFileDialog(
38 scoped_refptr<ExtensionFunction> extension_function,
39 ui::SelectFileDialog::Type type,
40 const base::FilePath& default_path,
41 const ui::SelectFileDialog::FileTypeInfo* file_types,
42 FileSystemDelegate::FilesSelectedCallback files_selected_callback,
43 base::OnceClosure file_selection_canceled_callback) {
44 auto web_contents = extension_function->GetSenderWebContents();
45 if (!web_contents) {
46 return false;
47 }
48
49 absl::optional<FileChooserParams::Mode> mode;
50 switch (type) {
51 case ui::SelectFileDialog::Type::SELECT_UPLOAD_FOLDER:
52 mode = FileChooserParams::Mode::kUploadFolder;
53 break;
54 case ui::SelectFileDialog::Type::SELECT_SAVEAS_FILE:
55 mode = FileChooserParams::Mode::kSave;
56 break;
57 case ui::SelectFileDialog::Type::SELECT_OPEN_FILE:
58 mode = FileChooserParams::Mode::kOpen;
59 break;
60 case ui::SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE:
61 mode = FileChooserParams::Mode::kOpenMultiple;
62 break;
63 default:
64 NOTIMPLEMENTED();
65 return false;
66 }
67
68 FileChooserParams params;
69 params.mode = *mode;
70 params.default_file_name = default_path;
71 if (file_types) {
72 // A list of allowed extensions. For example, it might be
73 // { { "htm", "html" }, { "txt" } }
74 for (auto& vec : file_types->extensions) {
75 for (auto& ext : vec) {
76 params.accept_types.push_back(
77 alloy::FilePathTypeToString16(FILE_PATH_LITERAL(".") + ext));
78 }
79 }
80 }
81
82 alloy::RunFileChooser(
83 web_contents, params,
84 base::BindOnce(&CefFileSystemDelegate::FileDialogDismissed,
85 weak_ptr_factory_.GetWeakPtr(),
86 std::move(files_selected_callback),
87 std::move(file_selection_canceled_callback)));
88
89 return true;
90 }
91
FileDialogDismissed(FileSystemDelegate::FilesSelectedCallback files_selected_callback,base::OnceClosure file_selection_canceled_callback,int selected_accept_filter,const std::vector<base::FilePath> & file_paths)92 void CefFileSystemDelegate::FileDialogDismissed(
93 FileSystemDelegate::FilesSelectedCallback files_selected_callback,
94 base::OnceClosure file_selection_canceled_callback,
95 int selected_accept_filter,
96 const std::vector<base::FilePath>& file_paths) {
97 if (!file_paths.empty()) {
98 std::move(files_selected_callback).Run(file_paths);
99 } else {
100 std::move(file_selection_canceled_callback).Run();
101 }
102 }
103
ConfirmSensitiveDirectoryAccess(bool has_write_permission,const std::u16string & app_name,content::WebContents * web_contents,base::OnceClosure on_accept,base::OnceClosure on_cancel)104 void CefFileSystemDelegate::ConfirmSensitiveDirectoryAccess(
105 bool has_write_permission,
106 const std::u16string& app_name,
107 content::WebContents* web_contents,
108 base::OnceClosure on_accept,
109 base::OnceClosure on_cancel) {
110 NOTIMPLEMENTED();
111
112 // Run the cancel callback by default.
113 std::move(on_cancel).Run();
114 }
115
116 // Based on ChromeFileSystemDelegate::GetDescriptionIdForAcceptType.
GetDescriptionIdForAcceptType(const std::string & accept_type)117 int CefFileSystemDelegate::GetDescriptionIdForAcceptType(
118 const std::string& accept_type) {
119 if (accept_type == "image/*")
120 return IDS_IMAGE_FILES;
121 if (accept_type == "audio/*")
122 return IDS_AUDIO_FILES;
123 if (accept_type == "video/*")
124 return IDS_VIDEO_FILES;
125 return 0;
126 }
127
GetSavedFilesService(content::BrowserContext * browser_context)128 SavedFilesServiceInterface* CefFileSystemDelegate::GetSavedFilesService(
129 content::BrowserContext* browser_context) {
130 return apps::SavedFilesService::Get(browser_context);
131 }
132
133 } // namespace cef
134 } // namespace extensions
135