Commit 35ef33ad authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

Update autotestPrivate APIs for overview drag test

Update autotestPrivate.getAppWindowList to carry relevant
overview item info under overview mode. It would be used to
check whether an item is being dragged, whether a window
is closed as expected, and whether a window snapped.

Bug: 1007060
Change-Id: If7fdbcb77fa327d268f9edbfec7986cae0c52f47
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1914599Reviewed-by: default avatarJun Mukai <mukai@chromium.org>
Reviewed-by: default avatarToni Baržić <tbarzic@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715268}
parent 2d0443cb
...@@ -9,7 +9,14 @@ ...@@ -9,7 +9,14 @@
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/containers/flat_map.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h"
#include "ui/gfx/geometry/rect.h"
namespace aura {
class Window;
}
namespace ash { namespace ash {
...@@ -18,6 +25,20 @@ enum class OverviewAnimationState : int32_t { ...@@ -18,6 +25,20 @@ enum class OverviewAnimationState : int32_t {
kExitAnimationComplete, kExitAnimationComplete,
}; };
struct OverviewItemInfo {
// A window represented by an overview item.
aura::Window* window = nullptr;
// Screen bounds of an overview item.
gfx::Rect bounds_in_screen;
// Whether an overview item is being dragged.
bool is_dragged = false;
};
// Overview item info keyed by app windows.
using OverviewInfo = base::flat_map<aura::Window*, OverviewItemInfo>;
// Provides access to the limited functions of OverviewController for autotest // Provides access to the limited functions of OverviewController for autotest
// private API. // private API.
class ASH_EXPORT OverviewTestApi { class ASH_EXPORT OverviewTestApi {
...@@ -25,7 +46,7 @@ class ASH_EXPORT OverviewTestApi { ...@@ -25,7 +46,7 @@ class ASH_EXPORT OverviewTestApi {
OverviewTestApi(); OverviewTestApi();
~OverviewTestApi(); ~OverviewTestApi();
typedef base::OnceCallback<void(bool)> DoneCallback; using DoneCallback = base::OnceCallback<void(bool)>;
// Set the overview mode state to |start|. Calls |done_callback| when it is // Set the overview mode state to |start|. Calls |done_callback| when it is
// done. |done_callback| will be called with a boolean if the animation // done. |done_callback| will be called with a boolean if the animation
...@@ -33,6 +54,10 @@ class ASH_EXPORT OverviewTestApi { ...@@ -33,6 +54,10 @@ class ASH_EXPORT OverviewTestApi {
// |start|, it does nothing but invokes |done_callback| with true. // |start|, it does nothing but invokes |done_callback| with true.
void SetOverviewMode(bool start, DoneCallback done_callback); void SetOverviewMode(bool start, DoneCallback done_callback);
// Returns overview info for the current overview items if overview is
// started. Otherwise, returns base::nullopt;
base::Optional<OverviewInfo> GetOverviewInfo() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(OverviewTestApi); DISALLOW_COPY_AND_ASSIGN(OverviewTestApi);
}; };
......
...@@ -7,7 +7,11 @@ ...@@ -7,7 +7,11 @@
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/overview/overview_animation_state_waiter.h" #include "ash/wm/overview/overview_animation_state_waiter.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_item.h"
#include "ash/wm/overview/overview_session.h"
#include "base/callback.h" #include "base/callback.h"
#include "ui/views/widget/widget.h"
namespace ash { namespace ash {
...@@ -43,4 +47,24 @@ void OverviewTestApi::SetOverviewMode( ...@@ -43,4 +47,24 @@ void OverviewTestApi::SetOverviewMode(
waiter->Cancel(); waiter->Cancel();
} }
base::Optional<OverviewInfo> OverviewTestApi::GetOverviewInfo() const {
auto* overview_controller = Shell::Get()->overview_controller();
if (!overview_controller->InOverviewSession())
return base::nullopt;
OverviewInfo info;
for (const auto& grid :
overview_controller->overview_session()->grid_list()) {
for (const auto& overview_item : grid->window_list()) {
aura::Window* const app_window = overview_item->GetWindow();
info[app_window] = {
app_window,
overview_item->item_widget()->GetWindowBoundsInScreen(),
overview_item->IsDragItem(),
};
}
}
return info;
}
} // namespace ash } // namespace ash
...@@ -3116,6 +3116,9 @@ AutotestPrivateGetAppWindowListFunction::Run() { ...@@ -3116,6 +3116,9 @@ AutotestPrivateGetAppWindowListFunction::Run() {
// Use negative number to avoid potential collision with normal use if any. // Use negative number to avoid potential collision with normal use if any.
static int id_count = -10000; static int id_count = -10000;
base::Optional<ash::OverviewInfo> overview_info =
ash::OverviewTestApi().GetOverviewInfo();
auto window_list = ash::GetAppWindowList(); auto window_list = ash::GetAppWindowList();
std::vector<api::autotest_private::AppWindowInfo> result_list; std::vector<api::autotest_private::AppWindowInfo> result_list;
...@@ -3207,6 +3210,18 @@ AutotestPrivateGetAppWindowListFunction::Run() { ...@@ -3207,6 +3210,18 @@ AutotestPrivateGetAppWindowListFunction::Run() {
window_info.is_frame_visible = false; window_info.is_frame_visible = false;
} }
// Overview info.
if (overview_info.has_value()) {
auto it = overview_info->find(window);
if (it != overview_info->end()) {
window_info.overview_info =
std::make_unique<api::autotest_private::OverviewInfo>();
window_info.overview_info->bounds =
ToBoundsDictionary(it->second.bounds_in_screen);
window_info.overview_info->is_dragged = it->second.is_dragged;
}
}
result_list.emplace_back(std::move(window_info)); result_list.emplace_back(std::move(window_info));
} }
return RespondNow(ArgumentList( return RespondNow(ArgumentList(
......
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "ash/public/cpp/overview_test_api.h"
#include "ash/public/cpp/test/shell_test_api.h"
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/test/bind_test_util.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/arc/session/arc_session_manager.h" #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
...@@ -13,6 +16,7 @@ ...@@ -13,6 +16,7 @@
#include "chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h" #include "chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.h"
#include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
#include "chrome/browser/ui/browser_window.h"
#include "components/arc/arc_prefs.h" #include "components/arc/arc_prefs.h"
#include "components/arc/arc_util.h" #include "components/arc/arc_util.h"
#include "components/arc/session/connection_holder.h" #include "components/arc/session/connection_holder.h"
...@@ -28,6 +32,9 @@ ...@@ -28,6 +32,9 @@
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "ui/aura/window.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
using testing::_; using testing::_;
...@@ -107,6 +114,97 @@ IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, AutotestPrivateArcEnabled) { ...@@ -107,6 +114,97 @@ IN_PROC_BROWSER_TEST_F(AutotestPrivateApiTest, AutotestPrivateArcEnabled) {
arc::SetArcPlayStoreEnabledForProfile(profile(), false); arc::SetArcPlayStoreEnabledForProfile(profile(), false);
} }
class AutotestPrivateApiOverviewTest : public AutotestPrivateApiTest {
public:
AutotestPrivateApiOverviewTest() = default;
// AutotestPrivateApiTest:
void SetUpOnMainThread() override {
AutotestPrivateApiTest::SetUpOnMainThread();
// Create one additional browser window to make total of 2 windows.
CreateBrowser(browser()->profile());
// Enters tablet overview mode.
ash::ShellTestApi().SetTabletModeEnabledForTest(true);
base::RunLoop run_loop;
ash::OverviewTestApi().SetOverviewMode(
/*start=*/true, base::BindLambdaForTesting([&run_loop](bool finished) {
if (!finished)
ADD_FAILURE() << "Failed to enter overview.";
run_loop.Quit();
}));
run_loop.Run();
// We should get 2 overview items from the 2 browser windows.
ASSERT_EQ(2u, ash::OverviewTestApi().GetOverviewInfo()->size());
}
gfx::NativeWindow GetRootWindow() const {
return browser()->window()->GetNativeWindow()->GetRootWindow();
}
};
IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, Default) {
ASSERT_TRUE(
RunComponentExtensionTestWithArg("autotest_private", "overviewDefault"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, Drag) {
const ash::OverviewInfo info =
ash::OverviewTestApi().GetOverviewInfo().value();
const gfx::Point start_point =
info.begin()->second.bounds_in_screen.CenterPoint();
// Long press to pick up an overview item and drag it a bit.
ui::test::EventGenerator generator(GetRootWindow());
generator.set_current_screen_location(start_point);
generator.PressTouch();
ui::GestureEvent long_press(
start_point.x(), start_point.y(), 0, ui::EventTimeForNow(),
ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
generator.Dispatch(&long_press);
// 50 is arbitrary number of dip to move a bit to ensure the item is being
// dragged.
const gfx::Point end_point(start_point.x() + 50, start_point.y());
generator.MoveTouch(end_point);
ASSERT_TRUE(
RunComponentExtensionTestWithArg("autotest_private", "overviewDrag"))
<< message_;
}
IN_PROC_BROWSER_TEST_F(AutotestPrivateApiOverviewTest, LeftSnapped) {
const ash::OverviewInfo info =
ash::OverviewTestApi().GetOverviewInfo().value();
const gfx::Point start_point =
info.begin()->second.bounds_in_screen.CenterPoint();
const gfx::Point end_point(0, start_point.y());
// Long press to pick up an overview item, drag all the way to the left
// to snap it on left.
ui::test::EventGenerator generator(GetRootWindow());
generator.set_current_screen_location(start_point);
generator.PressTouch();
ui::GestureEvent long_press(
start_point.x(), start_point.y(), 0, ui::EventTimeForNow(),
ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
generator.Dispatch(&long_press);
generator.MoveTouch(end_point);
generator.ReleaseTouch();
ASSERT_TRUE(RunComponentExtensionTestWithArg("autotest_private",
"splitviewLeftSnapped"))
<< message_;
}
class AutotestPrivateWithPolicyApiTest : public AutotestPrivateApiTest { class AutotestPrivateWithPolicyApiTest : public AutotestPrivateApiTest {
public: public:
AutotestPrivateWithPolicyApiTest() {} AutotestPrivateWithPolicyApiTest() {}
......
...@@ -352,6 +352,13 @@ namespace autotestPrivate { ...@@ -352,6 +352,13 @@ namespace autotestPrivate {
Immersive Immersive
}; };
dictionary OverviewInfo {
// Bounds in screen of an OverviewItem.
Bounds bounds;
// Whether an OverviewItem is being dragged in overview.
boolean isDragged;
};
dictionary AppWindowInfo { dictionary AppWindowInfo {
// The identifier of the window. This shouldn't change across the time. // The identifier of the window. This shouldn't change across the time.
long id; long id;
...@@ -390,7 +397,7 @@ namespace autotestPrivate { ...@@ -390,7 +397,7 @@ namespace autotestPrivate {
// false. // false.
boolean targetVisibility; boolean targetVisibility;
// WM Releated stats // WM Releated states
boolean isActive; boolean isActive;
boolean hasFocus; boolean hasFocus;
boolean onActiveDesk; boolean onActiveDesk;
...@@ -407,6 +414,8 @@ namespace autotestPrivate { ...@@ -407,6 +414,8 @@ namespace autotestPrivate {
long captionButtonVisibleStatus; long captionButtonVisibleStatus;
DOMString? arcPackageName; DOMString? arcPackageName;
OverviewInfo? overviewInfo;
}; };
dictionary Accelerator { dictionary Accelerator {
......
...@@ -652,6 +652,7 @@ var defaultTests = [ ...@@ -652,6 +652,7 @@ var defaultTests = [
kLeftSnappedMask | kRightSnappedMask); kLeftSnappedMask | kRightSnappedMask);
chrome.test.assertEq('Normal', window.frameMode); chrome.test.assertEq('Normal', window.frameMode);
chrome.test.assertTrue(window.isFrameVisible); chrome.test.assertTrue(window.isFrameVisible);
chrome.test.assertFalse(window.hasOwnProperty('overviewInfo'));
var change = new Object(); var change = new Object();
change.eventType = 'WMEventFullscreen'; change.eventType = 'WMEventFullscreen';
...@@ -900,12 +901,67 @@ var arcPerformanceTracingTests = [ ...@@ -900,12 +901,67 @@ var arcPerformanceTracingTests = [
}, },
]; ];
var overviewTests = [
function getOverviewInfo() {
chrome.autotestPrivate.getAppWindowList(
chrome.test.callbackPass(function(list) {
chrome.test.assertEq(2, list.length);
list.forEach(window => {
chrome.test.assertTrue(window.hasOwnProperty('overviewInfo'));
var info = window.overviewInfo;
chrome.test.assertTrue(info.hasOwnProperty('bounds'));
chrome.test.assertEq(typeof info.bounds, 'object');
chrome.test.assertTrue(info.bounds.hasOwnProperty('left'));
chrome.test.assertTrue(info.bounds.hasOwnProperty('top'));
chrome.test.assertTrue(info.bounds.hasOwnProperty('width'));
chrome.test.assertTrue(info.bounds.hasOwnProperty('height'));
chrome.test.assertTrue(info.hasOwnProperty('isDragged'));
chrome.test.assertEq(false, info.isDragged);
});
}));
}
];
var overviewDragTests = [
function getOverviewItemInfos() {
chrome.autotestPrivate.getAppWindowList(
chrome.test.callbackPass(function(list) {
var draggedItemCount = 0;
list.forEach(window => {
var info = window.overviewInfo;
chrome.test.assertTrue(info.hasOwnProperty('isDragged'));
if (info.isDragged)
++draggedItemCount;
});
chrome.test.assertEq(1, draggedItemCount);
}));
}
];
var splitviewLeftSnappedTests = [
function getSplitViewControllerStateLeftSnapped() {
chrome.autotestPrivate.getAppWindowList(
chrome.test.callbackPass(function(list) {
var found = false;
list.forEach(window => {
if (window.stateType == 'LeftSnapped')
found = true;
});
chrome.test.assertTrue(found);
}));
}
];
var test_suites = { var test_suites = {
'default': defaultTests, 'default': defaultTests,
'arcEnabled': arcEnabledTests, 'arcEnabled': arcEnabledTests,
'enterprisePolicies': policyTests, 'enterprisePolicies': policyTests,
'arcPerformanceTracing': arcPerformanceTracingTests 'arcPerformanceTracing': arcPerformanceTracingTests,
'overviewDefault': overviewTests,
'overviewDrag': overviewDragTests,
'splitviewLeftSnapped': splitviewLeftSnappedTests
}; };
chrome.test.getConfig(function(config) { chrome.test.getConfig(function(config) {
......
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