summaryrefslogtreecommitdiff
path: root/chromium/ash/touch/touch_observer_hud_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ash/touch/touch_observer_hud_unittest.cc')
-rw-r--r--chromium/ash/touch/touch_observer_hud_unittest.cc597
1 files changed, 597 insertions, 0 deletions
diff --git a/chromium/ash/touch/touch_observer_hud_unittest.cc b/chromium/ash/touch/touch_observer_hud_unittest.cc
new file mode 100644
index 00000000000..90328a85667
--- /dev/null
+++ b/chromium/ash/touch/touch_observer_hud_unittest.cc
@@ -0,0 +1,597 @@
+// Copyright (c) 2013 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/touch/touch_observer_hud.h"
+
+#include "ash/ash_switches.h"
+#include "ash/display/display_manager.h"
+#include "ash/root_window_controller.h"
+#include "ash/screen_ash.h"
+#include "ash/shell.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/display_manager_test_api.h"
+#include "ash/touch/touch_hud_debug.h"
+#include "ash/touch/touch_hud_projection.h"
+#include "base/command_line.h"
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace internal {
+
+class TouchHudTestBase : public test::AshTestBase {
+ public:
+ TouchHudTestBase() {}
+ virtual ~TouchHudTestBase() {}
+
+ virtual void SetUp() OVERRIDE {
+ test::AshTestBase::SetUp();
+
+ // Initialize display infos. They should be initialized after Ash
+ // environment is set up, i.e., after test::AshTestBase::SetUp().
+ internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()).
+ SetFirstDisplayAsInternalDisplay();
+ external_display_id_ = 10;
+ mirrored_display_id_ = 11;
+
+ internal_display_info_ =
+ CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
+ external_display_info_ =
+ CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
+ mirrored_display_info_ =
+ CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
+ }
+
+ gfx::Display GetPrimaryDisplay() {
+ return Shell::GetScreen()->GetPrimaryDisplay();
+ }
+
+ const gfx::Display& GetSecondaryDisplay() {
+ return ScreenAsh::GetSecondaryDisplay();
+ }
+
+ void SetupSingleDisplay() {
+ display_info_list_.clear();
+ display_info_list_.push_back(internal_display_info_);
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void SetupDualDisplays() {
+ display_info_list_.clear();
+ display_info_list_.push_back(internal_display_info_);
+ display_info_list_.push_back(external_display_info_);
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void SetInternalAsPrimary() {
+ const gfx::Display& internal_display =
+ GetDisplayManager()->GetDisplayForId(internal_display_id_);
+ GetDisplayController()->SetPrimaryDisplay(internal_display);
+ }
+
+ void SetExternalAsPrimary() {
+ const gfx::Display& external_display =
+ GetDisplayManager()->GetDisplayForId(external_display_id_);
+ GetDisplayController()->SetPrimaryDisplay(external_display);
+ }
+
+ void MirrorDisplays() {
+ DCHECK_EQ(2U, display_info_list_.size());
+ DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+ DCHECK_EQ(external_display_id_, display_info_list_[1].id());
+ display_info_list_[1] = mirrored_display_info_;
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void UnmirrorDisplays() {
+ DCHECK_EQ(2U, display_info_list_.size());
+ DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+ DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
+ display_info_list_[1] = external_display_info_;
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void RemoveInternalDisplay() {
+ DCHECK_LT(0U, display_info_list_.size());
+ DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
+ display_info_list_.erase(display_info_list_.begin());
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void RemoveExternalDisplay() {
+ DCHECK_EQ(2U, display_info_list_.size());
+ display_info_list_.pop_back();
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void AddInternalDisplay() {
+ DCHECK_EQ(0U, display_info_list_.size());
+ display_info_list_.push_back(internal_display_info_);
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ void AddExternalDisplay() {
+ DCHECK_EQ(1U, display_info_list_.size());
+ display_info_list_.push_back(external_display_info_);
+ GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
+ }
+
+ int64 internal_display_id() const {
+ return internal_display_id_;
+ }
+
+ int64 external_display_id() const {
+ return external_display_id_;
+ }
+
+ protected:
+ DisplayManager* GetDisplayManager() {
+ return Shell::GetInstance()->display_manager();
+ }
+
+ DisplayController* GetDisplayController() {
+ return Shell::GetInstance()->display_controller();
+ }
+
+ const gfx::Display& GetInternalDisplay() {
+ return GetDisplayManager()->GetDisplayForId(internal_display_id_);
+ }
+
+ const gfx::Display& GetExternalDisplay() {
+ return GetDisplayManager()->GetDisplayForId(external_display_id_);
+ }
+
+ aura::Window* GetInternalRootWindow() {
+ return GetDisplayController()->GetRootWindowForDisplayId(
+ internal_display_id_);
+ }
+
+ aura::Window* GetExternalRootWindow() {
+ return GetDisplayController()->GetRootWindowForDisplayId(
+ external_display_id_);
+ }
+
+ aura::Window* GetPrimaryRootWindow() {
+ const gfx::Display& display = GetPrimaryDisplay();
+ return GetDisplayController()->GetRootWindowForDisplayId(display.id());
+ }
+
+ aura::Window* GetSecondaryRootWindow() {
+ const gfx::Display& display = GetSecondaryDisplay();
+ return GetDisplayController()->GetRootWindowForDisplayId(display.id());
+ }
+
+ internal::RootWindowController* GetInternalRootController() {
+ aura::Window* root = GetInternalRootWindow();
+ return GetRootWindowController(root);
+ }
+
+ internal::RootWindowController* GetExternalRootController() {
+ aura::Window* root = GetExternalRootWindow();
+ return GetRootWindowController(root);
+ }
+
+ internal::RootWindowController* GetPrimaryRootController() {
+ aura::Window* root = GetPrimaryRootWindow();
+ return GetRootWindowController(root);
+ }
+
+ internal::RootWindowController* GetSecondaryRootController() {
+ aura::Window* root = GetSecondaryRootWindow();
+ return GetRootWindowController(root);
+ }
+
+ DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
+ DisplayInfo info(id, base::StringPrintf("x-%" PRId64, id), false);
+ info.SetBounds(bounds);
+ return info;
+ }
+
+ aura::Window* GetRootWindowForTouchHud(internal::TouchObserverHUD* hud) {
+ return hud->root_window_;
+ }
+
+ views::Widget* GetWidgetForTouchHud(internal::TouchObserverHUD* hud) {
+ return hud->widget_;
+ }
+
+ int64 internal_display_id_;
+ int64 external_display_id_;
+ int64 mirrored_display_id_;
+ DisplayInfo internal_display_info_;
+ DisplayInfo external_display_info_;
+ DisplayInfo mirrored_display_info_;
+
+ std::vector<DisplayInfo> display_info_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchHudTestBase);
+};
+
+class TouchHudDebugTest : public TouchHudTestBase {
+ public:
+ TouchHudDebugTest() {}
+ virtual ~TouchHudDebugTest() {}
+
+ virtual void SetUp() OVERRIDE {
+ // Add ash-touch-hud flag to enable debug touch HUD. This flag should be set
+ // before Ash environment is set up, i.e., before TouchHudTestBase::SetUp().
+ CommandLine::ForCurrentProcess()->AppendSwitch(
+ ash::switches::kAshTouchHud);
+
+ TouchHudTestBase::SetUp();
+ }
+
+ void CheckInternalDisplay() {
+ EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
+ GetInternalTouchHudDebug());
+ EXPECT_EQ(internal_display_id(), GetInternalTouchHudDebug()->display_id());
+ EXPECT_EQ(GetInternalRootWindow(),
+ GetRootWindowForTouchHud(GetInternalTouchHudDebug()));
+ EXPECT_EQ(GetInternalRootWindow(),
+ GetWidgetForTouchHud(GetInternalTouchHudDebug())->
+ GetNativeView()->GetRootWindow());
+ EXPECT_EQ(GetInternalDisplay().size(),
+ GetWidgetForTouchHud(GetInternalTouchHudDebug())->
+ GetWindowBoundsInScreen().size());
+ }
+
+ void CheckExternalDisplay() {
+ EXPECT_NE(static_cast<internal::TouchHudDebug*>(NULL),
+ GetExternalTouchHudDebug());
+ EXPECT_EQ(external_display_id(), GetExternalTouchHudDebug()->display_id());
+ EXPECT_EQ(GetExternalRootWindow(),
+ GetRootWindowForTouchHud(GetExternalTouchHudDebug()));
+ EXPECT_EQ(GetExternalRootWindow(),
+ GetWidgetForTouchHud(GetExternalTouchHudDebug())->
+ GetNativeView()->GetRootWindow());
+ EXPECT_EQ(GetExternalDisplay().size(),
+ GetWidgetForTouchHud(GetExternalTouchHudDebug())->
+ GetWindowBoundsInScreen().size());
+ }
+
+ private:
+ internal::TouchHudDebug* GetInternalTouchHudDebug() {
+ return GetInternalRootController()->touch_hud_debug();
+ }
+
+ internal::TouchHudDebug* GetExternalTouchHudDebug() {
+ return GetExternalRootController()->touch_hud_debug();
+ }
+
+ internal::TouchHudDebug* GetPrimaryTouchHudDebug() {
+ return GetPrimaryRootController()->touch_hud_debug();
+ }
+
+ internal::TouchHudDebug* GetSecondaryTouchHudDebug() {
+ return GetSecondaryRootController()->touch_hud_debug();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(TouchHudDebugTest);
+};
+
+class TouchHudProjectionTest : public TouchHudTestBase {
+ public:
+ TouchHudProjectionTest() {}
+ virtual ~TouchHudProjectionTest() {}
+
+ void EnableTouchHudProjection() {
+ Shell::GetInstance()->SetTouchHudProjectionEnabled(true);
+ }
+
+ void DisableTouchHudProjection() {
+ Shell::GetInstance()->SetTouchHudProjectionEnabled(false);
+ }
+
+ internal::TouchHudProjection* GetInternalTouchHudProjection() {
+ return GetInternalRootController()->touch_hud_projection();
+ }
+
+ int GetInternalTouchPointsCount() {
+ return GetInternalTouchHudProjection()->points_.size();
+ }
+
+ void SendTouchEventToInternalHud(ui::EventType type,
+ const gfx::Point& location,
+ int touch_id) {
+ ui::TouchEvent event(type, location, touch_id, event_time);
+ GetInternalTouchHudProjection()->OnTouchEvent(&event);
+
+ // Advance time for next event.
+ event_time += base::TimeDelta::FromMilliseconds(100);
+ }
+
+ private:
+ base::TimeDelta event_time;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchHudProjectionTest);
+};
+
+// Checks if debug touch HUD is correctly initialized for a single display.
+TEST_F(TouchHudDebugTest, SingleDisplay) {
+ // Setup a single display setting.
+ SetupSingleDisplay();
+
+ // Check if touch HUD is set correctly and associated with appropriate
+ // display.
+ CheckInternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly initialized for two displays.
+TEST_F(TouchHudDebugTest, DualDisplays) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Check if touch HUDs are set correctly and associated with appropriate
+ // displays.
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when primary display is
+// changed.
+TEST_F(TouchHudDebugTest, SwapPrimaryDisplay) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Set the primary display to the external one.
+ SetExternalAsPrimary();
+
+ // Check if displays' touch HUDs are not swapped as root windows are.
+ EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+
+ // Set the primary display back to the internal one.
+ SetInternalAsPrimary();
+
+ // Check if displays' touch HUDs are not swapped back as root windows are.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when displays are mirrored.
+TEST_F(TouchHudDebugTest, MirrorDisplays) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Mirror displays.
+ MirrorDisplays();
+
+ // Check if the internal display is intact.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ CheckInternalDisplay();
+
+ // Unmirror displays.
+ UnmirrorDisplays();
+
+ // Check if external display is added back correctly.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when displays are mirrored
+// after setting the external display as the primary one.
+TEST_F(TouchHudDebugTest, SwapPrimaryThenMirrorDisplays) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Set the primary display to the external one.
+ SetExternalAsPrimary();
+
+ // Mirror displays.
+ MirrorDisplays();
+
+ // Check if the internal display is set as the primary one.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ CheckInternalDisplay();
+
+ // Unmirror displays.
+ UnmirrorDisplays();
+
+ // Check if the external display is added back as the primary display and
+ // touch HUDs are set correctly.
+ EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when the external display,
+// which is the secondary one, is removed.
+TEST_F(TouchHudDebugTest, RemoveSecondaryDisplay) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Remove external display which is the secondary one.
+ RemoveExternalDisplay();
+
+ // Check if the internal display is intact.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ CheckInternalDisplay();
+
+ // Add external display back.
+ AddExternalDisplay();
+
+ // Check if displays' touch HUDs are set correctly.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when the external display,
+// which is set as the primary display, is removed.
+TEST_F(TouchHudDebugTest, RemovePrimaryDisplay) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a dual display setting.
+ SetupDualDisplays();
+
+ // Set the primary display to the external one.
+ SetExternalAsPrimary();
+
+ // Remove the external display which is the primary display.
+ RemoveExternalDisplay();
+
+ // Check if the internal display is set as the primary one.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ CheckInternalDisplay();
+
+ // Add the external display back.
+ AddExternalDisplay();
+
+ // Check if the external display is set as primary and touch HUDs are set
+ // correctly.
+ EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
+ EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
+ CheckInternalDisplay();
+ CheckExternalDisplay();
+}
+
+// Checks if debug touch HUDs are correctly handled when all displays are
+// removed.
+TEST_F(TouchHudDebugTest, Headless) {
+ if (!SupportsMultipleDisplays())
+ return;
+
+ // Setup a single display setting.
+ SetupSingleDisplay();
+
+ // Remove the only display which is the internal one.
+ RemoveInternalDisplay();
+
+ // Add the internal display back.
+ AddInternalDisplay();
+
+ // Check if the display's touch HUD is set correctly.
+ EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
+ CheckInternalDisplay();
+}
+
+// Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
+// and touch-released events.
+TEST_F(TouchHudProjectionTest, TouchMoveRelease) {
+ SetupSingleDisplay();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+
+ EnableTouchHudProjection();
+ EXPECT_NE(static_cast<internal::TouchHudProjection*>(NULL),
+ GetInternalTouchHudProjection());
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ // Disabling projection touch HUD shoud remove it without crashing.
+ DisableTouchHudProjection();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+}
+
+// Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
+// and touch-cancelled events.
+TEST_F(TouchHudProjectionTest, TouchMoveCancel) {
+ SetupSingleDisplay();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+
+ EnableTouchHudProjection();
+ EXPECT_NE(static_cast<internal::TouchHudProjection*>(NULL),
+ GetInternalTouchHudProjection());
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ // Disabling projection touch HUD shoud remove it without crashing.
+ DisableTouchHudProjection();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+}
+
+// Checks projection touch HUD with two simultaneous touches.
+TEST_F(TouchHudProjectionTest, DoubleTouch) {
+ SetupSingleDisplay();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+
+ EnableTouchHudProjection();
+ EXPECT_NE(static_cast<internal::TouchHudProjection*>(NULL),
+ GetInternalTouchHudProjection());
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
+ EXPECT_EQ(2, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(2, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
+ EXPECT_EQ(2, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ // Disabling projection touch HUD shoud remove it without crashing.
+ DisableTouchHudProjection();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+}
+
+// Checks if turning off touch HUD projection while touching the screen is
+// handled correctly.
+TEST_F(TouchHudProjectionTest, DisableWhileTouching) {
+ SetupSingleDisplay();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+
+ EnableTouchHudProjection();
+ EXPECT_NE(static_cast<internal::TouchHudProjection*>(NULL),
+ GetInternalTouchHudProjection());
+ EXPECT_EQ(0, GetInternalTouchPointsCount());
+
+ SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
+ EXPECT_EQ(1, GetInternalTouchPointsCount());
+
+ // Disabling projection touch HUD shoud remove it without crashing.
+ DisableTouchHudProjection();
+ EXPECT_EQ(NULL, GetInternalTouchHudProjection());
+}
+
+} // namespace internal
+} // namespace ash