Add SelectFileDialogExtension::SelectFileWithFileManagerParams
This allows us to pass show_android_picker_apps (a ChromeOS-specific
param) to SelectFileDialogExtension (SelectFileDialog impl for ChromeOS)
without modifying common SelectFileDialog interface.
Related discussion:
https://docs.google.com/a/google.com/document/d/1wy9b_VEi4mj1BU3LcI7ebMdDnlhwYnzgPqSt-hn7xow/edit?disco=AAAAC1VaFP4
BUG=b:130204519
TEST=unit_tests --gtest_filter="FileManagerUrlUtilTest.*
Change-Id: Ie39ced3c092ecaeee644b41f79fd89f0751fa734
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1564355
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Sam McNally <sammc@chromium.org>
Commit-Queue: Satoshi Niwa <niwa@chromium.org>
Auto-Submit: Satoshi Niwa <niwa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#655152}
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc
index 02dc656..59778376 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc
@@ -171,7 +171,12 @@
BuildFileTypeInfo(request, &file_type_info);
base::FilePath default_path = GetInitialFilePath(request);
- dialog_holder_->SelectFile(dialog_type, default_path, &file_type_info);
+ // Android picker apps should be shown in GET_CONTENT mode.
+ bool show_android_picker_apps =
+ request->action_type == mojom::SelectFilesActionType::GET_CONTENT;
+
+ dialog_holder_->SelectFile(dialog_type, default_path, &file_type_info,
+ show_android_picker_apps);
}
void ArcSelectFilesHandler::FileSelected(const base::FilePath& path,
@@ -274,14 +279,15 @@
void SelectFileDialogHolder::SelectFile(
ui::SelectFileDialog::Type type,
const base::FilePath& default_path,
- const ui::SelectFileDialog::FileTypeInfo* file_types) {
- select_file_dialog_->SelectFile(
+ const ui::SelectFileDialog::FileTypeInfo* file_types,
+ bool show_android_picker_apps) {
+ select_file_dialog_->SelectFileWithFileManagerParams(
type,
/*title=*/base::string16(), default_path, file_types,
/*file_type_index=*/0,
/*default_extension=*/base::FilePath::StringType(),
/*owning_window=*/nullptr,
- /*params=*/nullptr);
+ /*params=*/nullptr, show_android_picker_apps);
}
void SelectFileDialogHolder::ExecuteJavaScript(
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h
index 513daad..236baae 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h
+++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h
@@ -82,7 +82,8 @@
virtual void SelectFile(ui::SelectFileDialog::Type type,
const base::FilePath& default_path,
- const ui::SelectFileDialog::FileTypeInfo* file_types);
+ const ui::SelectFileDialog::FileTypeInfo* file_types,
+ bool show_android_picker_apps);
virtual void ExecuteJavaScript(
const std::string& script,
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc
index c0062b5..16975f2 100644
--- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc
+++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc
@@ -69,10 +69,11 @@
explicit MockSelectFileDialogHolder(ui::SelectFileDialog::Listener* listener)
: SelectFileDialogHolder(listener) {}
~MockSelectFileDialogHolder() override = default;
- MOCK_METHOD3(SelectFile,
+ MOCK_METHOD4(SelectFile,
void(ui::SelectFileDialog::Type type,
const base::FilePath& default_path,
- const ui::SelectFileDialog::FileTypeInfo* file_types));
+ const ui::SelectFileDialog::FileTypeInfo* file_types,
+ bool show_android_picker_apps));
MOCK_METHOD2(ExecuteJavaScript,
void(const std::string&, JavaScriptResultCallback));
};
@@ -110,12 +111,15 @@
void CallSelectFilesAndCheckDialogType(
SelectFilesActionType request_action_type,
bool request_allow_multiple,
- SelectFileDialog::Type expected_dialog_type) {
+ SelectFileDialog::Type expected_dialog_type,
+ bool expected_show_android_picker_apps) {
SelectFilesRequestPtr request = SelectFilesRequest::New();
request->action_type = request_action_type;
request->allow_multiple = request_allow_multiple;
- EXPECT_CALL(*mock_dialog_holder_, SelectFile(expected_dialog_type, _, _))
+ EXPECT_CALL(*mock_dialog_holder_,
+ SelectFile(expected_dialog_type, _, _,
+ expected_show_android_picker_apps))
.Times(1);
SelectFilesCallback callback;
@@ -150,18 +154,21 @@
TEST_F(ArcSelectFilesHandlerTest, SelectFiles_DialogType) {
CallSelectFilesAndCheckDialogType(SelectFilesActionType::GET_CONTENT, false,
- SelectFileDialog::SELECT_OPEN_FILE);
+ SelectFileDialog::SELECT_OPEN_FILE, true);
CallSelectFilesAndCheckDialogType(SelectFilesActionType::GET_CONTENT, true,
- SelectFileDialog::SELECT_OPEN_MULTI_FILE);
+ SelectFileDialog::SELECT_OPEN_MULTI_FILE,
+ true);
CallSelectFilesAndCheckDialogType(SelectFilesActionType::OPEN_DOCUMENT, false,
- SelectFileDialog::SELECT_OPEN_FILE);
+ SelectFileDialog::SELECT_OPEN_FILE, false);
CallSelectFilesAndCheckDialogType(SelectFilesActionType::OPEN_DOCUMENT, true,
- SelectFileDialog::SELECT_OPEN_MULTI_FILE);
- CallSelectFilesAndCheckDialogType(SelectFilesActionType::OPEN_DOCUMENT_TREE,
- false,
- SelectFileDialog::SELECT_EXISTING_FOLDER);
+ SelectFileDialog::SELECT_OPEN_MULTI_FILE,
+ false);
+ CallSelectFilesAndCheckDialogType(
+ SelectFilesActionType::OPEN_DOCUMENT_TREE, false,
+ SelectFileDialog::SELECT_EXISTING_FOLDER, false);
CallSelectFilesAndCheckDialogType(SelectFilesActionType::CREATE_DOCUMENT,
- true, SelectFileDialog::SELECT_SAVEAS_FILE);
+ true, SelectFileDialog::SELECT_SAVEAS_FILE,
+ false);
}
TEST_F(ArcSelectFilesHandlerTest, SelectFiles_FileTypeInfo) {
@@ -179,8 +186,9 @@
EXPECT_CALL(
*mock_dialog_holder_,
- SelectFile(
- _, _, testing::Pointee(FileTypeInfoMatcher(expected_file_type_info))))
+ SelectFile(_, _,
+ testing::Pointee(FileTypeInfoMatcher(expected_file_type_info)),
+ _))
.Times(1);
base::MockCallback<SelectFilesCallback> callback;
@@ -199,7 +207,7 @@
"/special/arc-documents-provider/testing.provider/doc:root");
EXPECT_CALL(*mock_dialog_holder_,
- SelectFile(_, FilePathMatcher(expected_file_path), _))
+ SelectFile(_, FilePathMatcher(expected_file_path), _, _))
.Times(1);
base::MockCallback<SelectFilesCallback> callback;
diff --git a/chrome/browser/chromeos/file_manager/url_util.cc b/chrome/browser/chromeos/file_manager/url_util.cc
index 63ccb8b..37e65f5c 100644
--- a/chrome/browser/chromeos/file_manager/url_util.cc
+++ b/chrome/browser/chromeos/file_manager/url_util.cc
@@ -78,7 +78,8 @@
const std::string& target_name,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
- const base::FilePath::StringType& default_extension) {
+ const base::FilePath::StringType& default_extension,
+ bool show_android_picker_apps) {
base::DictionaryValue arg_value;
arg_value.SetString("type", GetDialogTypeAsString(type));
arg_value.SetString("title", title);
@@ -86,6 +87,7 @@
arg_value.SetString("selectionURL", selection_url.spec());
arg_value.SetString("targetName", target_name);
arg_value.SetString("defaultExtension", default_extension);
+ arg_value.SetBoolean("showAndroidPickerApps", show_android_picker_apps);
if (file_types) {
auto types_list = std::make_unique<base::ListValue>();
diff --git a/chrome/browser/chromeos/file_manager/url_util.h b/chrome/browser/chromeos/file_manager/url_util.h
index f531582..8666925 100644
--- a/chrome/browser/chromeos/file_manager/url_util.h
+++ b/chrome/browser/chromeos/file_manager/url_util.h
@@ -29,7 +29,8 @@
const std::string& target_name,
const ui::SelectFileDialog::FileTypeInfo* file_types,
int file_type_index,
- const base::FilePath::StringType& default_extension);
+ const base::FilePath::StringType& default_extension,
+ bool show_android_picker_apps);
} // namespace util
} // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/url_util_unittest.cc b/chrome/browser/chromeos/file_manager/url_util_unittest.cc
index 5a0463e..ed054f9e 100644
--- a/chrome/browser/chromeos/file_manager/url_util_unittest.cc
+++ b/chrome/browser/chromeos/file_manager/url_util_unittest.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chromeos/constants/chromeos_features.h"
@@ -38,17 +39,6 @@
return pretty_json;
}
-base::Value MakeSimpleDictionary(
- std::vector<std::pair<std::string, std::string>> entries) {
- std::vector<std::pair<std::string, std::unique_ptr<base::Value>>> storage;
- storage.reserve(entries.size());
- for (auto& entry : entries) {
- storage.emplace_back(std::move(entry.first), std::make_unique<base::Value>(
- std::move(entry.second)));
- }
- return base::Value(std::move(storage));
-}
-
TEST(FileManagerUrlUtilTest, GetFileManagerMainPageUrl) {
EXPECT_EQ("chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/main.html",
GetFileManagerMainPageUrl().spec());
@@ -61,7 +51,9 @@
GURL("filesystem:chrome-extension://abc/Downloads/foo.txt"), "foo.txt",
nullptr, // No file types
0, // Hence no file type index.
- FILE_PATH_LITERAL("txt"));
+ FILE_PATH_LITERAL("txt"),
+ false // show_android_picker_apps
+ );
EXPECT_EQ(extensions::kExtensionScheme, url.scheme());
EXPECT_EQ("hhaomjibdihmijegdhdafkllkbggdgoj", url.host());
EXPECT_EQ("/main.html", url.path());
@@ -69,21 +61,25 @@
EXPECT_TRUE(url.query().find("+") == std::string::npos);
EXPECT_TRUE(url.query().find("%20") != std::string::npos);
// With DriveFS, Drive is always allowed where native paths are.
- EXPECT_EQ(MakeSimpleDictionary({
- {"allowedPaths",
- base::FeatureList::IsEnabled(chromeos::features::kDriveFs)
- ? "nativeOrDrivePath"
- : "nativePath"},
- {"currentDirectoryURL",
- "filesystem:chrome-extension://abc/Downloads/"},
- {"defaultExtension", "txt"},
- {"selectionURL",
- "filesystem:chrome-extension://abc/Downloads/foo.txt"},
- {"targetName", "foo.txt"},
- {"title", "some title"},
- {"type", "open-file"},
- }),
- ParseJsonQueryString(url.query()));
+ std::string allowed_paths =
+ base::FeatureList::IsEnabled(chromeos::features::kDriveFs)
+ ? "nativeOrDrivePath"
+ : "nativePath";
+ EXPECT_EQ(base::StringPrintf(
+ "{\n"
+ " \"allowedPaths\": \"%s\",\n"
+ " \"currentDirectoryURL\": "
+ "\"filesystem:chrome-extension://abc/Downloads/\",\n"
+ " \"defaultExtension\": \"txt\",\n"
+ " \"selectionURL\": "
+ "\"filesystem:chrome-extension://abc/Downloads/foo.txt\",\n"
+ " \"showAndroidPickerApps\": false,\n"
+ " \"targetName\": \"foo.txt\",\n"
+ " \"title\": \"some title\",\n"
+ " \"type\": \"open-file\"\n"
+ "}\n",
+ allowed_paths.c_str()),
+ PrettyPrintEscapedJson(url.query()));
}
TEST(FileManagerUrlUtilTest,
@@ -105,14 +101,14 @@
file_types.allowed_paths = ui::SelectFileDialog::FileTypeInfo::ANY_PATH;
const GURL url = GetFileManagerMainPageUrlWithParams(
- ui::SelectFileDialog::SELECT_OPEN_FILE,
- base::UTF8ToUTF16("some title"),
+ ui::SelectFileDialog::SELECT_OPEN_FILE, base::UTF8ToUTF16("some title"),
GURL("filesystem:chrome-extension://abc/Downloads/"),
- GURL("filesystem:chrome-extension://abc/Downloads/foo.txt"),
- "foo.txt",
+ GURL("filesystem:chrome-extension://abc/Downloads/foo.txt"), "foo.txt",
&file_types,
1, // The file type index is 1-based.
- FILE_PATH_LITERAL("txt"));
+ FILE_PATH_LITERAL("txt"),
+ true // show_android_picker_apps
+ );
EXPECT_EQ(extensions::kExtensionScheme, url.scheme());
EXPECT_EQ("hhaomjibdihmijegdhdafkllkbggdgoj", url.host());
EXPECT_EQ("/main.html", url.path());
@@ -129,6 +125,7 @@
" \"includeAllFiles\": false,\n"
" \"selectionURL\": "
"\"filesystem:chrome-extension://abc/Downloads/foo.txt\",\n"
+ " \"showAndroidPickerApps\": true,\n"
" \"targetName\": \"foo.txt\",\n"
" \"title\": \"some title\",\n"
" \"type\": \"open-file\",\n"
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 8c93be1..509ecbc 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -293,46 +293,7 @@
return NULL;
}
-bool SelectFileDialogExtension::IsResizeable() const {
- DCHECK(extension_dialog_.get());
- return extension_dialog_->CanResize();
-}
-
-void SelectFileDialogExtension::NotifyListener() {
- if (!listener_)
- return;
- switch (selection_type_) {
- case CANCEL:
- listener_->FileSelectionCanceled(params_);
- break;
- case SINGLE_FILE:
- listener_->FileSelectedWithExtraInfo(selection_files_[0],
- selection_index_,
- params_);
- break;
- case MULTIPLE_FILES:
- listener_->MultiFilesSelectedWithExtraInfo(selection_files_, params_);
- break;
- default:
- NOTREACHED();
- break;
- }
-}
-
-void SelectFileDialogExtension::AddPending(RoutingID routing_id) {
- PendingDialog::GetInstance()->Add(routing_id, this);
-}
-
-// static
-bool SelectFileDialogExtension::PendingExists(RoutingID routing_id) {
- return PendingDialog::GetInstance()->Find(routing_id).get() != NULL;
-}
-
-bool SelectFileDialogExtension::HasMultipleFileTypeChoicesImpl() {
- return has_multiple_file_type_choices_;
-}
-
-void SelectFileDialogExtension::SelectFileImpl(
+void SelectFileDialogExtension::SelectFileWithFileManagerParams(
Type type,
const base::string16& title,
const base::FilePath& default_path,
@@ -340,7 +301,8 @@
int file_type_index,
const base::FilePath::StringType& default_extension,
gfx::NativeWindow owner_window,
- void* params) {
+ void* params,
+ bool show_android_picker_apps) {
if (owner_window_) {
LOG(ERROR) << "File dialog already in use!";
return;
@@ -422,14 +384,9 @@
GURL file_manager_url =
file_manager::util::GetFileManagerMainPageUrlWithParams(
- type,
- title,
- current_directory_url,
- selection_url,
- default_path.BaseName().value(),
- file_types,
- file_type_index,
- default_extension);
+ type, title, current_directory_url, selection_url,
+ default_path.BaseName().value(), file_types, file_type_index,
+ default_extension, show_android_picker_apps);
ExtensionDialog* dialog = ExtensionDialog::Show(
file_manager_url,
@@ -451,3 +408,55 @@
routing_id_ = routing_id;
owner_window_ = owner_window;
}
+
+void SelectFileDialogExtension::SelectFileImpl(
+ Type type,
+ const base::string16& title,
+ const base::FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const base::FilePath::StringType& default_extension,
+ gfx::NativeWindow owner_window,
+ void* params) {
+ SelectFileWithFileManagerParams(
+ type, title, default_path, file_types, file_type_index, default_extension,
+ owner_window, params, false /* show_android_picker_apps */);
+}
+
+bool SelectFileDialogExtension::IsResizeable() const {
+ DCHECK(extension_dialog_.get());
+ return extension_dialog_->CanResize();
+}
+
+void SelectFileDialogExtension::NotifyListener() {
+ if (!listener_)
+ return;
+ switch (selection_type_) {
+ case CANCEL:
+ listener_->FileSelectionCanceled(params_);
+ break;
+ case SINGLE_FILE:
+ listener_->FileSelectedWithExtraInfo(selection_files_[0],
+ selection_index_, params_);
+ break;
+ case MULTIPLE_FILES:
+ listener_->MultiFilesSelectedWithExtraInfo(selection_files_, params_);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void SelectFileDialogExtension::AddPending(RoutingID routing_id) {
+ PendingDialog::GetInstance()->Add(routing_id, this);
+}
+
+// static
+bool SelectFileDialogExtension::PendingExists(RoutingID routing_id) {
+ return PendingDialog::GetInstance()->Find(routing_id).get() != NULL;
+}
+
+bool SelectFileDialogExtension::HasMultipleFileTypeChoicesImpl() {
+ return has_multiple_file_type_choices_;
+}
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.h b/chrome/browser/ui/views/select_file_dialog_extension.h
index 3145aff..af9a221 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.h
+++ b/chrome/browser/ui/views/select_file_dialog_extension.h
@@ -64,6 +64,18 @@
// For testing, so we can inject JavaScript into the contained view.
content::RenderViewHost* GetRenderViewHost();
+ // Call SelectFile with params specific to Chrome OS file manager.
+ void SelectFileWithFileManagerParams(
+ Type type,
+ const base::string16& title,
+ const base::FilePath& default_path,
+ const FileTypeInfo* file_types,
+ int file_type_index,
+ const base::FilePath::StringType& default_extension,
+ gfx::NativeWindow owning_window,
+ void* params,
+ bool show_android_picker_apps);
+
protected:
// SelectFileDialog implementation.
void SelectFileImpl(Type type,