| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/public/test/file_system_chooser_test_helpers.h" |
| |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "ui/shell_dialogs/select_file_dialog.h" |
| #include "ui/shell_dialogs/selected_file_info.h" |
| #include "url/gurl.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| class CancellingSelectFileDialog : public ui::SelectFileDialog { |
| public: |
| CancellingSelectFileDialog(SelectFileDialogParams* out_params, |
| Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) |
| : ui::SelectFileDialog(listener, std::move(policy)), |
| out_params_(out_params) {} |
| |
| protected: |
| void SelectFileImpl(Type type, |
| const std::u16string& title, |
| const base::FilePath& default_path, |
| const FileTypeInfo* file_types, |
| int file_type_index, |
| const base::FilePath::StringType& default_extension, |
| gfx::NativeWindow owning_window, |
| const GURL* caller) override { |
| if (out_params_) { |
| out_params_->type = type; |
| if (file_types) { |
| out_params_->file_types = *file_types; |
| } else { |
| out_params_->file_types = std::nullopt; |
| } |
| out_params_->owning_window = owning_window; |
| out_params_->file_type_index = file_type_index; |
| out_params_->default_path = default_path; |
| out_params_->title = title; |
| if (caller) { |
| out_params_->caller = *caller; |
| } else { |
| out_params_->caller = std::nullopt; |
| } |
| |
| // Free the pointer since output parameters should only be written to |
| // once. |
| out_params_ = nullptr; |
| } |
| listener_->FileSelectionCanceled(); |
| } |
| |
| #if BUILDFLAG(IS_ANDROID) |
| void SetAcceptTypes(std::vector<std::u16string> types) override { |
| if (out_params_) { |
| out_params_->accept_types = std::move(types); |
| } |
| } |
| #endif |
| |
| bool IsRunning(gfx::NativeWindow owning_window) const override { |
| return false; |
| } |
| void ListenerDestroyed() override { listener_ = nullptr; } |
| bool HasMultipleFileTypeChoicesImpl() override { return false; } |
| |
| private: |
| ~CancellingSelectFileDialog() override { |
| if (out_params_) { |
| out_params_ = nullptr; |
| } |
| } |
| raw_ptr<SelectFileDialogParams> out_params_; |
| }; |
| |
| class FakeSelectFileDialog : public ui::SelectFileDialog { |
| public: |
| FakeSelectFileDialog(std::vector<ui::SelectedFileInfo> result, |
| SelectFileDialogParams* out_params, |
| Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) |
| : ui::SelectFileDialog(listener, std::move(policy)), |
| result_(std::move(result)), |
| out_params_(out_params) {} |
| |
| protected: |
| void SelectFileImpl(Type type, |
| const std::u16string& title, |
| const base::FilePath& default_path, |
| const FileTypeInfo* file_types, |
| int file_type_index, |
| const base::FilePath::StringType& default_extension, |
| gfx::NativeWindow owning_window, |
| const GURL* caller) override { |
| if (out_params_) { |
| out_params_->type = type; |
| if (file_types) { |
| out_params_->file_types = *file_types; |
| } else { |
| out_params_->file_types = std::nullopt; |
| } |
| out_params_->owning_window = owning_window; |
| out_params_->file_type_index = file_type_index; |
| out_params_->default_path = default_path; |
| out_params_->title = title; |
| if (caller) { |
| out_params_->caller = *caller; |
| } else { |
| out_params_->caller = std::nullopt; |
| } |
| |
| // Clean up the output parameters; they should only be filled in once. |
| out_params_ = nullptr; |
| } |
| // The selected files are passed by reference to the listener. Ensure they |
| // outlive the dialog if it is immediately deleted by the listener. |
| std::vector<ui::SelectedFileInfo> result = std::move(result_); |
| result_.clear(); |
| if (result.size() == 1) { |
| listener_->FileSelected(result[0], 0); |
| } else { |
| listener_->MultiFilesSelected(result); |
| } |
| } |
| |
| bool IsRunning(gfx::NativeWindow owning_window) const override { |
| return false; |
| } |
| void ListenerDestroyed() override { listener_ = nullptr; } |
| bool HasMultipleFileTypeChoicesImpl() override { return false; } |
| |
| private: |
| ~FakeSelectFileDialog() override { |
| if (out_params_) { |
| out_params_ = nullptr; |
| } |
| } |
| std::vector<ui::SelectedFileInfo> result_; |
| raw_ptr<SelectFileDialogParams> out_params_; |
| }; |
| |
| class ObservableSelectFileDialog : public ui::SelectFileDialog { |
| public: |
| ObservableSelectFileDialog( |
| Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy, |
| base::WeakPtr<ObservableSelectFileDialogFactory::Observer> observer) |
| : ui::SelectFileDialog(listener, std::move(policy)), observer_(observer) { |
| observer_->WasCreated(); |
| } |
| |
| protected: |
| void SelectFileImpl(Type type, |
| const std::u16string& title, |
| const base::FilePath& default_path, |
| const FileTypeInfo* file_types, |
| int file_type_index, |
| const base::FilePath::StringType& default_extension, |
| gfx::NativeWindow owning_window, |
| const GURL* caller) override {} |
| |
| bool IsRunning(gfx::NativeWindow owning_window) const override { |
| return false; |
| } |
| void ListenerDestroyed() override { listener_ = nullptr; } |
| bool HasMultipleFileTypeChoicesImpl() override { return false; } |
| |
| private: |
| ~ObservableSelectFileDialog() override { |
| if (observer_) { |
| observer_->WasDestroyed(); |
| } |
| } |
| base::WeakPtr<ObservableSelectFileDialogFactory::Observer> observer_; |
| }; |
| |
| } // namespace |
| |
| SelectFileDialogParams::SelectFileDialogParams() = default; |
| SelectFileDialogParams::~SelectFileDialogParams() = default; |
| |
| CancellingSelectFileDialogFactory::CancellingSelectFileDialogFactory( |
| SelectFileDialogParams* out_params) |
| : out_params_(out_params) {} |
| |
| CancellingSelectFileDialogFactory::~CancellingSelectFileDialogFactory() { |
| out_params_ = nullptr; |
| } |
| |
| ui::SelectFileDialog* CancellingSelectFileDialogFactory::Create( |
| ui::SelectFileDialog::Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) { |
| return new CancellingSelectFileDialog(out_params_, listener, |
| std::move(policy)); |
| } |
| |
| FakeSelectFileDialogFactory::FakeSelectFileDialogFactory( |
| std::vector<base::FilePath> result, |
| SelectFileDialogParams* out_params) |
| : FakeSelectFileDialogFactory( |
| ui::FilePathListToSelectedFileInfoList(result), |
| out_params) {} |
| |
| FakeSelectFileDialogFactory::FakeSelectFileDialogFactory( |
| std::vector<ui::SelectedFileInfo> result, |
| SelectFileDialogParams* out_params) |
| : result_(std::move(result)), out_params_(out_params) {} |
| |
| FakeSelectFileDialogFactory::~FakeSelectFileDialogFactory() { |
| out_params_ = nullptr; |
| } |
| |
| ui::SelectFileDialog* FakeSelectFileDialogFactory::Create( |
| ui::SelectFileDialog::Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) { |
| return new FakeSelectFileDialog(result_, out_params_, listener, |
| std::move(policy)); |
| } |
| |
| ObservableSelectFileDialogFactory::ObservableSelectFileDialogFactory( |
| base::WeakPtr<Observer> observer) |
| : observer_(observer) {} |
| |
| ObservableSelectFileDialogFactory::~ObservableSelectFileDialogFactory() = |
| default; |
| |
| ui::SelectFileDialog* ObservableSelectFileDialogFactory::Create( |
| ui::SelectFileDialog::Listener* listener, |
| std::unique_ptr<ui::SelectFilePolicy> policy) { |
| return new ObservableSelectFileDialog(listener, std::move(policy), observer_); |
| } |
| |
| SelectFileDialogRecorder::SelectFileDialogRecorder() : weak_factory_(this) {} |
| void SelectFileDialogRecorder::WasCreated() { |
| CHECK_EQ(state, kNotCreated); |
| state = kCreated; |
| } |
| void SelectFileDialogRecorder::WasDestroyed() { |
| CHECK_EQ(state, kCreated); |
| state = kDestroyed; |
| } |
| |
| SelectFileDialogRecorder::~SelectFileDialogRecorder() = default; |
| |
| base::WeakPtr<SelectFileDialogRecorder> SelectFileDialogRecorder::GetWeakPtr() { |
| return weak_factory_.GetWeakPtr(); |
| } |
| } // namespace content |