Commit 1e9ed1e1 authored by David Black's avatar David Black Committed by Commit Bot

Add drag-and-drop to holding space views.

This CL:
* Adds drag-and-drop behavior to holding space views
* Adds a new base class for holding space browsertests
* Adds browsertests to verify drag-and-drop behavior

Still TODO:
* Add drag image

Bug: 1124581
Change-Id: I4a2e7fe63b26b10b7a7563adcfe7569d095ea7fb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2392263
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarAhmed Mehfooz <amehfooz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805094}
parent cc7f24d2
......@@ -2367,6 +2367,7 @@ static_library("test_support") {
"//ash/public/cpp/external_arc:*",
]
public = [
"public/cpp/holding_space/holding_space_test_api.h",
"public/cpp/test/accessibility_controller_test_api.h",
"public/cpp/test/assistant_test_api.h",
]
......@@ -2447,6 +2448,7 @@ static_library("test_support") {
"shelf/test/widget_animation_waiter.cc",
"shelf/test/widget_animation_waiter.h",
"shell_test_api.cc",
"system/holding_space/holding_space_test_api.cc",
"system/message_center/test_notifier_settings_controller.cc",
"system/message_center/test_notifier_settings_controller.h",
"system/palette/palette_tray_test_api.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_PUBLIC_CPP_HOLDING_SPACE_HOLDING_SPACE_TEST_API_H_
#define ASH_PUBLIC_CPP_HOLDING_SPACE_HOLDING_SPACE_TEST_API_H_
#include <vector>
#include "ash/ash_export.h"
namespace aura {
class Window;
} // namespace aura
namespace views {
class View;
} // namespace views
namespace ash {
class HoldingSpaceTray;
// Utility class to facilitate easier testing of holding space. This API mainly
// exists to workaround //ash dependency restrictions in browser tests.
class ASH_EXPORT HoldingSpaceTestApi {
public:
HoldingSpaceTestApi();
HoldingSpaceTestApi(const HoldingSpaceTestApi&) = delete;
HoldingSpaceTestApi& operator=(const HoldingSpaceTestApi&) = delete;
~HoldingSpaceTestApi();
// Returns the root window that newly created windows should be added to.
static aura::Window* GetRootWindowForNewWindows();
// Shows holding space UI. This is a no-op if it's already showing.
void Show();
// Closes holding space UI. This is a no-op if it's already closed.
void Close();
// Returns true if holding space UI is showing, false otherwise.
bool IsShowing();
// Returns the collection of pinned file chips in holding space UI.
// If holding space UI is not visible, an empty collection is returned.
std::vector<views::View*> GetPinnedFileChips();
// Returns the collection of screenshot views in holding space UI.
// If holding space UI is not visible, an empty collection is returned.
std::vector<views::View*> GetScreenshotViews();
private:
HoldingSpaceTray* holding_space_tray_ = nullptr;
};
} // namespace ash
#endif // ASH_PUBLIC_CPP_HOLDING_SPACE_HOLDING_SPACE_TEST_API_H_
file://ash/public/cpp/holding_space/OWNERS
amehfooz@chromium.org
\ No newline at end of file
......@@ -13,14 +13,18 @@
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/unified/unified_system_tray_view.h"
#include "ash/system/user/rounded_image_view.h"
#include "ui/gfx/canvas.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/metadata/metadata_impl_macros.h"
#include "ui/views/vector_icons.h"
namespace ash {
......@@ -34,7 +38,7 @@ HoldingSpaceItemChipView::HoldingSpaceItemChipView(const HoldingSpaceItem* item)
image_ =
AddChildView(std::make_unique<tray::RoundedImageView>(kTrayItemSize / 2));
label_ = AddChildView(std::make_unique<views::Label>());
label_ = AddChildView(std::make_unique<views::Label>(item_->text()));
label_->SetElideBehavior(gfx::ELIDE_MIDDLE);
layout->SetFlexForView(label_, 1);
......@@ -46,24 +50,39 @@ HoldingSpaceItemChipView::HoldingSpaceItemChipView(const HoldingSpaceItem* item)
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
SetBackground(views::CreateRoundedRectBackground(
AshColorProvider::Get()->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive),
kHoldingSpaceChipCornerRadius));
GetViewAccessibility().OverrideName(item_->text());
SetFocusBehavior(FocusBehavior::ALWAYS);
SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER);
set_ink_drop_visible_opacity(ShelfConfig::Get()->GetInkDropVisibleOpacity());
set_notify_enter_exit_on_child(true);
// Ink drop layers should be clipped to match the corner radius of this view.
views::InstallRoundRectHighlightPathGenerator(this, gfx::Insets(),
kHoldingSpaceChipCornerRadius);
Update();
}
HoldingSpaceItemChipView::~HoldingSpaceItemChipView() = default;
const char* HoldingSpaceItemChipView::GetClassName() const {
return "HoldingSpaceItemChipView";
}
SkColor HoldingSpaceItemChipView::GetInkDropBaseColor() const {
return ShelfConfig::Get()->GetInkDropBaseColor();
}
int HoldingSpaceItemChipView::GetDragOperations(const gfx::Point& point) {
return ui::DragDropTypes::DRAG_COPY;
}
void HoldingSpaceItemChipView::WriteDragData(const gfx::Point& point,
ui::OSExchangeData* data) {
data->SetFilename(item_->file_path());
}
void HoldingSpaceItemChipView::OnMouseEvent(ui::MouseEvent* event) {
switch (event->type()) {
case ui::ET_MOUSE_ENTERED:
......@@ -78,22 +97,6 @@ void HoldingSpaceItemChipView::OnMouseEvent(ui::MouseEvent* event) {
views::InkDropHostView::OnMouseEvent(event);
}
void HoldingSpaceItemChipView::OnPaint(gfx::Canvas* canvas) {
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setStyle(cc::PaintFlags::kFill_Style);
const AshColorProvider* color_provider = AshColorProvider::Get();
SkColor color = color_provider->GetControlsLayerColor(
AshColorProvider::ControlsLayerType::kControlBackgroundColorInactive);
flags.setColor(color);
canvas->DrawRoundRect(GetContentsBounds(), kHoldingSpaceChipCornerRadius,
flags);
views::InkDropHostView::OnPaint(canvas);
}
void HoldingSpaceItemChipView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
if (sender == pin_) {
......@@ -120,7 +123,9 @@ void HoldingSpaceItemChipView::AddPinButton() {
void HoldingSpaceItemChipView::Update() {
image_->SetImage(item_->image().image_skia(), {kTrayItemSize, kTrayItemSize});
label_->SetText(item_->text());
}
BEGIN_METADATA(HoldingSpaceItemChipView, views::InkDropHostView)
END_METADATA
} // namespace ash
......@@ -8,6 +8,7 @@
#include "ash/ash_export.h"
#include "ui/views/animation/ink_drop_host_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/metadata/metadata_header_macros.h"
namespace views {
class Label;
......@@ -27,16 +28,18 @@ class RoundedImageView;
class ASH_EXPORT HoldingSpaceItemChipView : public views::InkDropHostView,
public views::ButtonListener {
public:
METADATA_HEADER(HoldingSpaceItemChipView);
explicit HoldingSpaceItemChipView(const HoldingSpaceItem* item);
HoldingSpaceItemChipView(const HoldingSpaceItemChipView&) = delete;
HoldingSpaceItemChipView& operator=(const HoldingSpaceItemChipView&) = delete;
~HoldingSpaceItemChipView() override;
// views::InkDropHostView:
const char* GetClassName() const override;
SkColor GetInkDropBaseColor() const override;
int GetDragOperations(const gfx::Point& point) override;
void WriteDragData(const gfx::Point& point, ui::OSExchangeData*) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnPaint(gfx::Canvas* canvas) override;
// views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
......
......@@ -8,7 +8,10 @@
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/user/rounded_image_view.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/metadata/metadata_impl_macros.h"
namespace ash {
......@@ -20,6 +23,7 @@ HoldingSpaceScreenshotView::HoldingSpaceScreenshotView(
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
GetViewAccessibility().OverrideName(item_->text());
SetFocusBehavior(FocusBehavior::ALWAYS);
image_ =
......@@ -30,12 +34,20 @@ HoldingSpaceScreenshotView::HoldingSpaceScreenshotView(
HoldingSpaceScreenshotView::~HoldingSpaceScreenshotView() = default;
const char* HoldingSpaceScreenshotView::GetClassName() const {
return "HoldingSpaceScreenshotView";
int HoldingSpaceScreenshotView::GetDragOperations(const gfx::Point& point) {
return ui::DragDropTypes::DRAG_COPY;
}
void HoldingSpaceScreenshotView::WriteDragData(const gfx::Point& point,
ui::OSExchangeData* data) {
data->SetFilename(item_->file_path());
}
void HoldingSpaceScreenshotView::Update() {
image_->SetImage(item_->image().image_skia(), kHoldingSpaceScreenshotSize);
}
BEGIN_METADATA(HoldingSpaceScreenshotView, views::View)
END_METADATA
} // namespace ash
......@@ -6,6 +6,7 @@
#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_SCREENSHOT_VIEW_H_
#include "ash/ash_export.h"
#include "ui/views/metadata/metadata_header_macros.h"
#include "ui/views/view.h"
namespace ash {
......@@ -18,6 +19,8 @@ class RoundedImageView;
class ASH_EXPORT HoldingSpaceScreenshotView : public views::View {
public:
METADATA_HEADER(HoldingSpaceScreenshotView);
explicit HoldingSpaceScreenshotView(const HoldingSpaceItem* item);
HoldingSpaceScreenshotView(const HoldingSpaceScreenshotView&) = delete;
HoldingSpaceScreenshotView& operator=(const HoldingSpaceScreenshotView&) =
......@@ -25,7 +28,8 @@ class ASH_EXPORT HoldingSpaceScreenshotView : public views::View {
~HoldingSpaceScreenshotView() override;
// views::View:
const char* GetClassName() const override;
int GetDragOperations(const gfx::Point& point) override;
void WriteDragData(const gfx::Point& point, ui::OSExchangeData*) override;
private:
void Update();
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/public/cpp/holding_space/holding_space_test_api.h"
#include "ash/drag_drop/drag_drop_controller.h"
#include "ash/public/cpp/test/shell_test_api.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/system/holding_space/holding_space_item_chip_view.h"
#include "ash/system/holding_space/holding_space_screenshot_view.h"
#include "ash/system/holding_space/holding_space_tray.h"
#include "ash/system/status_area_widget.h"
#include "ui/aura/window.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
namespace ash {
namespace {
// Helpers ---------------------------------------------------------------------
// Finds all descendents of `parent` matching a specific class.
template <typename T>
void FindDescendentsOfClass(views::View* parent,
std::vector<views::View*>* descendents) {
if (parent) {
for (auto* child : parent->children()) {
if (child->GetClassName() == T::kViewClassName)
descendents->push_back(child);
FindDescendentsOfClass<T>(child, descendents);
}
}
}
// Performs a tap on the specified `view`.
void TapOn(const views::View* view) {
ui::test::EventGenerator event_generator(Shell::GetRootWindowForNewWindows());
event_generator.MoveTouch(view->GetBoundsInScreen().CenterPoint());
event_generator.PressTouch();
event_generator.ReleaseTouch();
}
} // namespace
// HoldingSpaceTestApi ---------------------------------------------------------
HoldingSpaceTestApi::HoldingSpaceTestApi()
: holding_space_tray_(Shelf::ForWindow(Shell::GetRootWindowForNewWindows())
->shelf_widget()
->status_area_widget()
->holding_space_tray()) {
// Holding space tests perform drag/drop so we need to disable blocking.
auto* drag_drop_controller = ShellTestApi().drag_drop_controller();
drag_drop_controller->set_should_block_during_drag_drop(false);
}
HoldingSpaceTestApi::~HoldingSpaceTestApi() {
if (!Shell::HasInstance())
return;
// Enable blocking during drag/drop that was disabled for holding space tests.
auto* drag_drop_controller = ShellTestApi().drag_drop_controller();
drag_drop_controller->set_should_block_during_drag_drop(true);
}
// static
aura::Window* HoldingSpaceTestApi::GetRootWindowForNewWindows() {
return Shell::GetRootWindowForNewWindows();
}
void HoldingSpaceTestApi::Show() {
if (!IsShowing())
TapOn(holding_space_tray_);
}
void HoldingSpaceTestApi::Close() {
if (IsShowing())
TapOn(holding_space_tray_);
}
bool HoldingSpaceTestApi::IsShowing() {
return holding_space_tray_ && holding_space_tray_->GetBubbleView() &&
holding_space_tray_->GetBubbleView()->GetVisible();
}
std::vector<views::View*> HoldingSpaceTestApi::GetPinnedFileChips() {
std::vector<views::View*> chips;
FindDescendentsOfClass<HoldingSpaceItemChipView>(
holding_space_tray_->GetBubbleView(), &chips);
return chips;
}
std::vector<views::View*> HoldingSpaceTestApi::GetScreenshotViews() {
std::vector<views::View*> screenshots;
FindDescendentsOfClass<HoldingSpaceScreenshotView>(
holding_space_tray_->GetBubbleView(), &screenshots);
return screenshots;
}
} // namespace ash
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("browser_tests") {
testonly = true
defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
sources = [
"//chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc",
"//chrome/browser/ui/ash/holding_space/holding_space_keyed_service_browsertest.cc",
"//chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc",
]
deps = [
":test_support",
"//ash:test_support",
"//ash/public/cpp",
"//base/test:test_support",
"//chrome/browser",
"//chrome/browser/chromeos",
"//chrome/browser/extensions",
"//chrome/browser/ui",
"//chrome/test:test_support_ui",
"//content/test:test_support",
"//ui/aura",
"//ui/base",
"//ui/events:test_support",
"//ui/views",
]
}
source_set("test_support") {
testonly = true
sources = [
"//chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.cc",
"//chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h",
]
deps = [
"//ash:test_support",
"//ash/public/cpp",
"//base/test:test_support",
"//chrome/browser/extensions",
"//chrome/test:test_support_ui",
"//ui/views",
]
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h"
#include <string>
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/holding_space/holding_space_controller.h"
#include "ash/public/cpp/holding_space/holding_space_image.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_model.h"
#include "ash/public/cpp/holding_space/holding_space_test_api.h"
#include "base/bind_helpers.h"
#include "base/unguessable_token.h"
#include "chrome/browser/extensions/component_loader.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/view.h"
namespace ash {
namespace {
// Helpers ---------------------------------------------------------------------
// Creates a file at `root_path` with the specified `extension`, returning the
// path of the created file.
base::FilePath CreateFile(const base::FilePath& root_path,
const std::string& extension) {
const base::FilePath file_path = root_path.Append(base::StringPrintf(
"%s.%s", base::UnguessableToken::Create().ToString().c_str(),
extension.c_str()));
{
base::ScopedAllowBlockingForTesting allow_blocking;
if (!base::CreateDirectory(file_path.DirName())) {
ADD_FAILURE() << "Failed to create parent directory.";
return base::FilePath();
}
if (!base::WriteFile(file_path, /*content=*/std::string())) {
ADD_FAILURE() << "Filed to write file contents.";
return base::FilePath();
}
}
return file_path;
}
// Creates a .txt file at `root_path` and returns the path of the created file.
base::FilePath CreateTextFile(const base::FilePath& root_path) {
return CreateFile(root_path, "txt");
}
// Creates a .png file at `root_path` and returns the path of the created file.
base::FilePath CreateImageFile(const base::FilePath& root_path) {
return CreateFile(root_path, "png");
}
} // namespace
// HoldingSpaceBrowserTestBase -------------------------------------------------
HoldingSpaceBrowserTestBase::HoldingSpaceBrowserTestBase() {
scoped_feature_list_.InitAndEnableFeature(features::kTemporaryHoldingSpace);
}
HoldingSpaceBrowserTestBase::~HoldingSpaceBrowserTestBase() = default;
// static
aura::Window* HoldingSpaceBrowserTestBase::GetRootWindowForNewWindows() {
return HoldingSpaceTestApi::GetRootWindowForNewWindows();
}
void HoldingSpaceBrowserTestBase::Show() {
test_api_->Show();
}
void HoldingSpaceBrowserTestBase::Close() {
test_api_->Close();
}
bool HoldingSpaceBrowserTestBase::IsShowing() {
return test_api_->IsShowing();
}
HoldingSpaceItem* HoldingSpaceBrowserTestBase::AddPinnedFile() {
auto item = HoldingSpaceItem::CreateFileBackedItem(
HoldingSpaceItem::Type::kPinnedFile,
/*file_path=*/CreateTextFile(scoped_temp_dir_.GetPath()),
/*file_system_url=*/GURL(),
/*image=*/
std::make_unique<HoldingSpaceImage>(
/*placeholder=*/gfx::ImageSkia(),
/*async_bitmap_resolver=*/base::DoNothing()));
auto* item_ptr = item.get();
HoldingSpaceController::Get()->model()->AddItem(std::move(item));
return item_ptr;
}
HoldingSpaceItem* HoldingSpaceBrowserTestBase::AddScreenshotFile() {
auto item = HoldingSpaceItem::CreateFileBackedItem(
HoldingSpaceItem::Type::kScreenshot,
/*file_path=*/CreateImageFile(scoped_temp_dir_.GetPath()),
/*file_system_url=*/GURL(),
/*image=*/
std::make_unique<HoldingSpaceImage>(
/*placeholder=*/gfx::ImageSkia(),
/*async_bitmap_resolver=*/base::DoNothing()));
auto* item_ptr = item.get();
HoldingSpaceController::Get()->model()->AddItem(std::move(item));
return item_ptr;
}
std::vector<views::View*> HoldingSpaceBrowserTestBase::GetPinnedFileChips() {
return test_api_->GetPinnedFileChips();
}
std::vector<views::View*> HoldingSpaceBrowserTestBase::GetScreenshotViews() {
return test_api_->GetScreenshotViews();
}
void HoldingSpaceBrowserTestBase::SetUpInProcessBrowserTestFixture() {
InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
extensions::ComponentLoader::EnableBackgroundExtensionsForTesting();
}
void HoldingSpaceBrowserTestBase::SetUpOnMainThread() {
InProcessBrowserTest::SetUpOnMainThread();
ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
test_api_ = std::make_unique<HoldingSpaceTestApi>();
}
} // namespace ash
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_ASH_HOLDING_SPACE_HOLDING_SPACE_BROWSERTEST_BASE_H_
#define CHROME_BROWSER_UI_ASH_HOLDING_SPACE_HOLDING_SPACE_BROWSERTEST_BASE_H_
#include <memory>
#include <vector>
#include "base/files/scoped_temp_dir.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/test/base/in_process_browser_test.h"
namespace aura {
class Window;
} // namespace aura
namespace views {
class View;
} // namespace views
namespace ash {
class HoldingSpaceItem;
class HoldingSpaceTestApi;
// Base class for holding space browser tests.
class HoldingSpaceBrowserTestBase : public InProcessBrowserTest {
public:
HoldingSpaceBrowserTestBase();
~HoldingSpaceBrowserTestBase() override;
// Returns the root window that newly created windows should be added to.
static aura::Window* GetRootWindowForNewWindows();
// Shows holding space UI. This is a no-op if it's already showing.
void Show();
// Closes holding space UI. This is a no-op if it's already closed.
void Close();
// Returns true if holding space UI is showing, false otherwise.
bool IsShowing();
// Adds and returns an arbitrary pinned file to the holding space.
HoldingSpaceItem* AddPinnedFile();
// Adds and returns an arbitrary screenshot file to the holding space.
HoldingSpaceItem* AddScreenshotFile();
// Returns the collection of pinned file chips in holding space UI.
// If holding space UI is not visible, an empty collection is returned.
std::vector<views::View*> GetPinnedFileChips();
// Returns the collection of screenshot views in holding space UI.
// If holding space UI is not visible, an empty collection is returned.
std::vector<views::View*> GetScreenshotViews();
private:
// InProcessBrowserTest:
void SetUpInProcessBrowserTestFixture() override;
void SetUpOnMainThread() override;
base::test::ScopedFeatureList scoped_feature_list_;
base::ScopedTempDir scoped_temp_dir_;
std::unique_ptr<HoldingSpaceTestApi> test_api_;
};
} // namespace ash
#endif // CHROME_BROWSER_UI_ASH_HOLDING_SPACE_HOLDING_SPACE_BROWSERTEST_BASE_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/ash/holding_space/holding_space_browsertest_base.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "base/test/bind_test_util.h"
#include "content/public/test/browser_test.h"
#include "ui/aura/window.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
namespace ash {
namespace {
// Helpers ---------------------------------------------------------------------
// Performs a mouse drag between `from` and `to`.
void MouseDrag(const views::View* from, const views::View* to) {
auto* root_window = HoldingSpaceBrowserTestBase::GetRootWindowForNewWindows();
ui::test::EventGenerator event_generator(root_window);
event_generator.MoveMouseTo(from->GetBoundsInScreen().CenterPoint());
event_generator.PressLeftButton();
event_generator.MoveMouseTo(to->GetBoundsInScreen().CenterPoint());
event_generator.ReleaseLeftButton();
}
// DropTargetView --------------------------------------------------------------
class DropTargetView : public views::WidgetDelegateView {
public:
DropTargetView(const DropTargetView&) = delete;
DropTargetView& operator=(const DropTargetView&) = delete;
~DropTargetView() override = default;
static DropTargetView* Create(aura::Window* context) {
return new DropTargetView(context);
}
const base::FilePath& copied_file_path() const { return copied_file_path_; }
private:
explicit DropTargetView(aura::Window* context) { InitWidget(context); }
// views::WidgetDelegateView:
bool GetDropFormats(
int* formats,
std::set<ui::ClipboardFormatType>* format_types) override {
*formats = ui::OSExchangeData::FILE_NAME;
return true;
}
bool CanDrop(const ui::OSExchangeData& data) override { return true; }
int OnDragUpdated(const ui::DropTargetEvent& event) override {
return ui::DragDropTypes::DRAG_COPY;
}
int OnPerformDrop(const ui::DropTargetEvent& event) override {
EXPECT_TRUE(event.data().GetFilename(&copied_file_path_));
return ui::DragDropTypes::DRAG_COPY;
}
void InitWidget(aura::Window* context) {
views::Widget::InitParams params;
params.accept_events = true;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.context = context;
params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
params.wants_mouse_events_when_inactive = true;
views::Widget* widget = new views::Widget();
widget->Init(std::move(params));
}
base::FilePath copied_file_path_;
};
} // namespace
// Tests -----------------------------------------------------------------------
using HoldingSpaceUiBrowserTest = HoldingSpaceBrowserTestBase;
// Verifies that drag-and-drop of holding space items works.
IN_PROC_BROWSER_TEST_F(HoldingSpaceUiBrowserTest, DragAndDrop) {
HoldingSpaceItem* const pinned_file = AddPinnedFile();
HoldingSpaceItem* const screenshot_file = AddScreenshotFile();
Show();
ASSERT_TRUE(IsShowing());
std::vector<views::View*> chips = GetPinnedFileChips();
ASSERT_EQ(1u, chips.size());
std::vector<views::View*> screenshots = GetScreenshotViews();
ASSERT_EQ(1u, screenshots.size());
auto* drop_target_view = DropTargetView::Create(GetRootWindowForNewWindows());
drop_target_view->GetWidget()->SetBounds(gfx::Rect(0, 0, 100, 100));
drop_target_view->GetWidget()->ShowInactive();
MouseDrag(/*from=*/chips[0], /*to=*/drop_target_view);
EXPECT_EQ(pinned_file->file_path(), drop_target_view->copied_file_path());
MouseDrag(/*from=*/screenshots[0], /*to=*/drop_target_view);
EXPECT_EQ(screenshot_file->file_path(), drop_target_view->copied_file_path());
drop_target_view->GetWidget()->Close();
}
} // namespace ash
......@@ -1588,6 +1588,7 @@ if (!is_android) {
"//chrome/browser/chromeos:test_support",
"//chrome/browser/media/router:test_support",
"//chrome/browser/resources/chromeos/accessibility:browser_tests",
"//chrome/browser/ui/ash/holding_space:browser_tests",
"//chrome/services/file_util/public/cpp:browser_tests",
"//chromeos:test_support",
"//chromeos/components/drivefs:test_support",
......@@ -1620,8 +1621,6 @@ if (!is_android) {
"../browser/policy/suggested_content_policy_browsertest.cc",
"../browser/policy/system_features_policy_browsertest.cc",
"../browser/renderer_context_menu/quick_answers_menu_observer_browsertest.cc",
"../browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc",
"../browser/ui/ash/holding_space/holding_space_keyed_service_browsertest.cc",
"../browser/ui/webui/nearby_share/nearby_share_dialog_ui_browsertest.cc",
]
}
......
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