blob: 229fc41b992a09c525b5325aa352f135b7cfb5b7 [file] [log] [blame]
// 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