Commit 1290cce0 authored by Satoshi Niwa's avatar Satoshi Niwa Committed by Commit Bot

SelectFileDialogExtension : Make it posssible to pass an Android window as owner window

Bug: 971499
Change-Id: Ifef681fbeccc902a80df145b61830c74ae6be7b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1670136Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Commit-Queue: Satoshi Niwa <niwa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#671990}
parent 3fc88fb8
...@@ -18,9 +18,11 @@ ...@@ -18,9 +18,11 @@
#include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h" #include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
#include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/ui/views/select_file_dialog_extension.h" #include "chrome/browser/ui/views/select_file_dialog_extension.h"
#include "chrome/common/chrome_isolated_world_ids.h" #include "chrome/common/chrome_isolated_world_ids.h"
#include "components/arc/arc_util.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
...@@ -29,6 +31,7 @@ ...@@ -29,6 +31,7 @@
#include "net/base/mime_util.h" #include "net/base/mime_util.h"
#include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h" #include "storage/browser/fileapi/file_system_url.h"
#include "ui/aura/window.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace arc { namespace arc {
...@@ -185,8 +188,12 @@ void ArcSelectFilesHandler::SelectFiles( ...@@ -185,8 +188,12 @@ void ArcSelectFilesHandler::SelectFiles(
bool show_android_picker_apps = bool show_android_picker_apps =
request->action_type == mojom::SelectFilesActionType::GET_CONTENT; request->action_type == mojom::SelectFilesActionType::GET_CONTENT;
dialog_holder_->SelectFile(dialog_type, default_path, &file_type_info, bool success =
request->task_id, show_android_picker_apps); dialog_holder_->SelectFile(dialog_type, default_path, &file_type_info,
request->task_id, show_android_picker_apps);
if (!success) {
std::move(callback_).Run(mojom::SelectFilesResult::New());
}
} }
void ArcSelectFilesHandler::FileSelected(const base::FilePath& path, void ArcSelectFilesHandler::FileSelected(const base::FilePath& path,
...@@ -301,19 +308,31 @@ SelectFileDialogHolder::~SelectFileDialogHolder() { ...@@ -301,19 +308,31 @@ SelectFileDialogHolder::~SelectFileDialogHolder() {
select_file_dialog_->ListenerDestroyed(); select_file_dialog_->ListenerDestroyed();
} }
void SelectFileDialogHolder::SelectFile( bool SelectFileDialogHolder::SelectFile(
ui::SelectFileDialog::Type type, ui::SelectFileDialog::Type type,
const base::FilePath& default_path, const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types, const ui::SelectFileDialog::FileTypeInfo* file_types,
int task_id, int task_id,
bool show_android_picker_apps) { bool show_android_picker_apps) {
aura::Window* owner_window = nullptr;
for (auto* window : ChromeLauncherController::instance()->GetArcWindows()) {
if (arc::GetWindowTaskId(window) == task_id) {
owner_window = window;
break;
}
}
if (!owner_window) {
LOG(ERROR) << "Can't find the ARC window for task ID : " << task_id;
return false;
}
select_file_dialog_->SelectFileWithFileManagerParams( select_file_dialog_->SelectFileWithFileManagerParams(
type, type,
/*title=*/base::string16(), default_path, file_types, /*title=*/base::string16(), default_path, file_types,
/*file_type_index=*/0, /*file_type_index=*/0,
/*default_extension=*/base::FilePath::StringType(), /*default_extension=*/base::FilePath::StringType(), owner_window,
/*owning_window=*/nullptr, /*params=*/nullptr, task_id, show_android_picker_apps);
/*params=*/nullptr, show_android_picker_apps); return true;
} }
void SelectFileDialogHolder::ExecuteJavaScript( void SelectFileDialogHolder::ExecuteJavaScript(
......
...@@ -82,7 +82,9 @@ class SelectFileDialogHolder { ...@@ -82,7 +82,9 @@ class SelectFileDialogHolder {
explicit SelectFileDialogHolder(ui::SelectFileDialog::Listener* listener); explicit SelectFileDialogHolder(ui::SelectFileDialog::Listener* listener);
virtual ~SelectFileDialogHolder(); virtual ~SelectFileDialogHolder();
virtual void SelectFile(ui::SelectFileDialog::Type type, // Obtains the owner window from |task_id| and opens the select file dialog
// with it. Returns false if the owner window is not found.
virtual bool SelectFile(ui::SelectFileDialog::Type type,
const base::FilePath& default_path, const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types, const ui::SelectFileDialog::FileTypeInfo* file_types,
int task_id, int task_id,
......
...@@ -27,6 +27,7 @@ using arc::mojom::SelectFilesActionType; ...@@ -27,6 +27,7 @@ using arc::mojom::SelectFilesActionType;
using arc::mojom::SelectFilesRequest; using arc::mojom::SelectFilesRequest;
using arc::mojom::SelectFilesRequestPtr; using arc::mojom::SelectFilesRequestPtr;
using testing::_; using testing::_;
using testing::Return;
using ui::SelectFileDialog; using ui::SelectFileDialog;
namespace arc { namespace arc {
...@@ -80,7 +81,7 @@ class MockSelectFileDialogHolder : public SelectFileDialogHolder { ...@@ -80,7 +81,7 @@ class MockSelectFileDialogHolder : public SelectFileDialogHolder {
: SelectFileDialogHolder(listener) {} : SelectFileDialogHolder(listener) {}
~MockSelectFileDialogHolder() override = default; ~MockSelectFileDialogHolder() override = default;
MOCK_METHOD5(SelectFile, MOCK_METHOD5(SelectFile,
void(ui::SelectFileDialog::Type type, bool(ui::SelectFileDialog::Type type,
const base::FilePath& default_path, const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types, const ui::SelectFileDialog::FileTypeInfo* file_types,
int task_id, int task_id,
...@@ -111,6 +112,8 @@ class ArcSelectFilesHandlerTest : public testing::Test { ...@@ -111,6 +112,8 @@ class ArcSelectFilesHandlerTest : public testing::Test {
mock_dialog_holder_ = mock_dialog_holder.get(); mock_dialog_holder_ = mock_dialog_holder.get();
arc_select_files_handler_->SetDialogHolderForTesting( arc_select_files_handler_->SetDialogHolderForTesting(
std::move(mock_dialog_holder)); std::move(mock_dialog_holder));
ON_CALL(*mock_dialog_holder_, SelectFile(_, _, _, _, _))
.WillByDefault(Return(true));
} }
void TearDown() override { void TearDown() override {
......
...@@ -161,18 +161,23 @@ void FindRuntimeContext(gfx::NativeWindow owner_window, ...@@ -161,18 +161,23 @@ void FindRuntimeContext(gfx::NativeWindow owner_window,
#endif #endif
} }
SelectFileDialogExtension::RoutingID GetRoutingID(
content::WebContents* web_contents,
int android_task_id) {
if (android_task_id != SelectFileDialogExtension::kAndroidTaskIdNone) {
return base::StringPrintf("android.%d", android_task_id);
} else if (web_contents) {
return base::StringPrintf(
"web.%d", web_contents->GetMainFrame()->GetFrameTreeNodeId());
}
LOG(ERROR) << "Unable to generate a RoutingID";
return "";
}
} // namespace } // namespace
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// static
SelectFileDialogExtension::RoutingID
SelectFileDialogExtension::GetRoutingIDFromWebContents(
content::WebContents* web_contents) {
return base::StringPrintf("web.%d",
web_contents->GetMainFrame()->GetFrameTreeNodeId());
}
// TODO(jamescook): Move this into a new file shell_dialogs_chromeos.cc // TODO(jamescook): Move this into a new file shell_dialogs_chromeos.cc
// static // static
SelectFileDialogExtension* SelectFileDialogExtension::Create( SelectFileDialogExtension* SelectFileDialogExtension::Create(
...@@ -302,6 +307,7 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams( ...@@ -302,6 +307,7 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams(
const base::FilePath::StringType& default_extension, const base::FilePath::StringType& default_extension,
gfx::NativeWindow owner_window, gfx::NativeWindow owner_window,
void* params, void* params,
int owner_android_task_id,
bool show_android_picker_apps) { bool show_android_picker_apps) {
if (owner_window_) { if (owner_window_) {
LOG(ERROR) << "File dialog already in use!"; LOG(ERROR) << "File dialog already in use!";
...@@ -313,7 +319,11 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams( ...@@ -313,7 +319,11 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams(
// The web contents to associate the dialog with. // The web contents to associate the dialog with.
content::WebContents* web_contents = NULL; content::WebContents* web_contents = NULL;
FindRuntimeContext(owner_window, &base_window, &web_contents);
// Obtain BaseWindow and WebContents if the owner window is browser.
if (owner_android_task_id == kAndroidTaskIdNone)
FindRuntimeContext(owner_window, &base_window, &web_contents);
if (web_contents) if (web_contents)
profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
...@@ -328,7 +338,7 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams( ...@@ -328,7 +338,7 @@ void SelectFileDialogExtension::SelectFileWithFileManagerParams(
// Check if we have another dialog opened for the contents. It's unlikely, but // Check if we have another dialog opened for the contents. It's unlikely, but
// possible. In such situation, discard this request. // possible. In such situation, discard this request.
RoutingID routing_id = GetRoutingIDFromWebContents(web_contents); RoutingID routing_id = GetRoutingID(web_contents, owner_android_task_id);
if (PendingExists(routing_id)) if (PendingExists(routing_id))
return; return;
...@@ -421,9 +431,10 @@ void SelectFileDialogExtension::SelectFileImpl( ...@@ -421,9 +431,10 @@ void SelectFileDialogExtension::SelectFileImpl(
const base::FilePath::StringType& default_extension, const base::FilePath::StringType& default_extension,
gfx::NativeWindow owner_window, gfx::NativeWindow owner_window,
void* params) { void* params) {
SelectFileWithFileManagerParams( SelectFileWithFileManagerParams(type, title, default_path, file_types,
type, title, default_path, file_types, file_type_index, default_extension, file_type_index, default_extension,
owner_window, params, false /* show_android_picker_apps */); owner_window, params, kAndroidTaskIdNone,
false /* show_android_picker_apps */);
} }
bool SelectFileDialogExtension::IsResizeable() const { bool SelectFileDialogExtension::IsResizeable() const {
......
...@@ -34,10 +34,10 @@ class SelectFileDialogExtension ...@@ -34,10 +34,10 @@ class SelectFileDialogExtension
public ExtensionDialogObserver { public ExtensionDialogObserver {
public: public:
// Opaque ID type for identifying the tab spawned each dialog, unique for // Opaque ID type for identifying the tab spawned each dialog, unique for
// every WebContents. // every WebContents or every Android task ID.
typedef std::string RoutingID; typedef std::string RoutingID;
static RoutingID GetRoutingIDFromWebContents(
content::WebContents* web_contents); static const int kAndroidTaskIdNone = -1;
static SelectFileDialogExtension* Create( static SelectFileDialogExtension* Create(
ui::SelectFileDialog::Listener* listener, ui::SelectFileDialog::Listener* listener,
...@@ -65,6 +65,10 @@ class SelectFileDialogExtension ...@@ -65,6 +65,10 @@ class SelectFileDialogExtension
content::RenderViewHost* GetRenderViewHost(); content::RenderViewHost* GetRenderViewHost();
// Call SelectFile with params specific to Chrome OS file manager. // Call SelectFile with params specific to Chrome OS file manager.
// |owner_android_task_id| is the Android task ID of the owner window if the
// owner is Android, or kAndroidTaskIdNone if the owner is browser.
// |show_android_picker_apps| determines whether to show Android picker apps
// in the select file dialog.
void SelectFileWithFileManagerParams( void SelectFileWithFileManagerParams(
Type type, Type type,
const base::string16& title, const base::string16& title,
...@@ -74,6 +78,7 @@ class SelectFileDialogExtension ...@@ -74,6 +78,7 @@ class SelectFileDialogExtension
const base::FilePath::StringType& default_extension, const base::FilePath::StringType& default_extension,
gfx::NativeWindow owning_window, gfx::NativeWindow owning_window,
void* params, void* params,
int owner_android_task_id,
bool show_android_picker_apps); bool show_android_picker_apps);
protected: protected:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment