blob: 48ecde3580d7ee0eef44a8d714c4d3777e397662 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/metrics/desktop_task_switch_metric_recorder.h"
#include <memory>
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/test/metrics/user_action_tester.h"
#include "ui/aura/client/window_types.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer_type.h"
#include "ui/events/test/event_generator.h"
#include "ui/wm/public/activation_client.h"
using wm::ActivationChangeObserver;
namespace ash {
namespace {
const char kDesktopTaskSwitchUserAction[] = "Desktop_SwitchTask";
// Test fixture for the DesktopTaskSwitchMetricsRecorder class. NOTE: This
// fixture extends AshTestBase so that the UserMetricsRecorder instance required
// by the test target can be obtained through Shell::Get()->metrics() and the
// test target is not the same instance as the one owned by the
// UserMetricsRecorder instance.
class DesktopTaskSwitchMetricRecorderTest : public AshTestBase {
public:
DesktopTaskSwitchMetricRecorderTest();
DesktopTaskSwitchMetricRecorderTest(
const DesktopTaskSwitchMetricRecorderTest&) = delete;
DesktopTaskSwitchMetricRecorderTest& operator=(
const DesktopTaskSwitchMetricRecorderTest&) = delete;
~DesktopTaskSwitchMetricRecorderTest() override;
// AshTestBase:
void SetUp() override;
void TearDown() override;
// Resets the recorded user action counts.
void ResetActionCounts();
// Returns the number of times the "Desktop_SwitchTask" user action was
// recorded.
int GetActionCount() const;
// Creates a positionable window such that
// window_util::IsWindowUserPositionable(...) would return true.
std::unique_ptr<aura::Window> CreatePositionableWindow() const;
// Creates a non-positionable window such that
// window_util::IsWindowUserPositionable(...) would return false.
std::unique_ptr<aura::Window> CreateNonPositionableWindow() const;
// Wrapper to notify the test target's OnWindowActivated(...) method that
// |window| was activated due to an INPUT_EVENT.
void ActiveTaskWindowWithUserInput(aura::Window* window);
protected:
// Records UMA user action counts.
std::unique_ptr<base::UserActionTester> user_action_tester_;
// The test target.
std::unique_ptr<DesktopTaskSwitchMetricRecorder> metrics_recorder_;
};
DesktopTaskSwitchMetricRecorderTest::DesktopTaskSwitchMetricRecorderTest() =
default;
DesktopTaskSwitchMetricRecorderTest::~DesktopTaskSwitchMetricRecorderTest() =
default;
void DesktopTaskSwitchMetricRecorderTest::SetUp() {
AshTestBase::SetUp();
metrics_recorder_ = std::make_unique<DesktopTaskSwitchMetricRecorder>();
user_action_tester_ = std::make_unique<base::UserActionTester>();
}
void DesktopTaskSwitchMetricRecorderTest::TearDown() {
user_action_tester_.reset();
metrics_recorder_.reset();
AshTestBase::TearDown();
}
void DesktopTaskSwitchMetricRecorderTest::ActiveTaskWindowWithUserInput(
aura::Window* window) {
metrics_recorder_->OnWindowActivated(
ActivationChangeObserver::ActivationReason::INPUT_EVENT, window, nullptr);
}
void DesktopTaskSwitchMetricRecorderTest::ResetActionCounts() {
user_action_tester_->ResetCounts();
}
int DesktopTaskSwitchMetricRecorderTest::GetActionCount() const {
return user_action_tester_->GetActionCount(kDesktopTaskSwitchUserAction);
}
std::unique_ptr<aura::Window>
DesktopTaskSwitchMetricRecorderTest::CreatePositionableWindow() const {
std::unique_ptr<aura::Window> window = std::make_unique<aura::Window>(
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate());
window->SetType(aura::client::WINDOW_TYPE_NORMAL);
window->Init(ui::LAYER_NOT_DRAWN);
return window;
}
std::unique_ptr<aura::Window>
DesktopTaskSwitchMetricRecorderTest::CreateNonPositionableWindow() const {
std::unique_ptr<aura::Window> window = std::make_unique<aura::Window>(
aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate());
window->SetType(aura::client::WINDOW_TYPE_UNKNOWN);
window->Init(ui::LAYER_NOT_DRAWN);
return window;
}
// Verify user action is recorded when a positionable window is activated given
// that a null window was activated last.
TEST_F(DesktopTaskSwitchMetricRecorderTest,
ActivatePositionableWindowWhenNullWindowWasActivatedLast) {
std::unique_ptr<aura::Window> null_window;
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
ActiveTaskWindowWithUserInput(null_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(positionable_window.get());
EXPECT_EQ(1, GetActionCount());
}
// Verify user action is recorded whena positionable window is activated given
// a different positionable window was activated last.
TEST_F(
DesktopTaskSwitchMetricRecorderTest,
ActivatePositionableWindowWhenADifferentPositionableWindowWasActivatedLast) {
std::unique_ptr<aura::Window> positionable_window_1 =
CreatePositionableWindow();
std::unique_ptr<aura::Window> positionable_window_2 =
CreatePositionableWindow();
ActiveTaskWindowWithUserInput(positionable_window_1.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(positionable_window_2.get());
EXPECT_EQ(1, GetActionCount());
}
// Verify user action is not recorded when a positionable window is activated
// given the same positionable window was activated last.
TEST_F(
DesktopTaskSwitchMetricRecorderTest,
ActivatePositionableWindowWhenTheSamePositionableWindowWasActivatedLast) {
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
ActiveTaskWindowWithUserInput(positionable_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(positionable_window.get());
EXPECT_EQ(0, GetActionCount());
}
// Verify user action is recorded when a positionable window is activated given
// a non-positionable window was activated last.
TEST_F(DesktopTaskSwitchMetricRecorderTest,
ActivatePositionableWindowWhenANonPositionableWindowWasActivatedLast) {
std::unique_ptr<aura::Window> non_positionable_window =
CreateNonPositionableWindow();
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
ActiveTaskWindowWithUserInput(non_positionable_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(positionable_window.get());
EXPECT_EQ(1, GetActionCount());
}
// Verify user action is not recorded when a non-positionable window is
// activated between two activations of the same positionable window.
TEST_F(DesktopTaskSwitchMetricRecorderTest,
ActivateNonPositionableWindowBetweenTwoPositionableWindowActivations) {
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
std::unique_ptr<aura::Window> non_positionable_window =
CreateNonPositionableWindow();
ActiveTaskWindowWithUserInput(positionable_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(non_positionable_window.get());
EXPECT_EQ(0, GetActionCount());
ActiveTaskWindowWithUserInput(positionable_window.get());
EXPECT_EQ(0, GetActionCount());
}
// Verify user action is not recorded when a null window is activated.
TEST_F(DesktopTaskSwitchMetricRecorderTest, ActivateNullWindow) {
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
std::unique_ptr<aura::Window> null_window;
ActiveTaskWindowWithUserInput(positionable_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(null_window.get());
EXPECT_EQ(0, GetActionCount());
}
// Verify user action is not recorded when a non-positionable window is
// activated.
TEST_F(DesktopTaskSwitchMetricRecorderTest, ActivateNonPositionableWindow) {
std::unique_ptr<aura::Window> positionable_window =
CreatePositionableWindow();
std::unique_ptr<aura::Window> non_positionable_window =
CreateNonPositionableWindow();
ActiveTaskWindowWithUserInput(positionable_window.get());
ResetActionCounts();
ActiveTaskWindowWithUserInput(non_positionable_window.get());
EXPECT_EQ(0, GetActionCount());
}
// Verify user action is not recorded when the ActivationReason is not an
// INPUT_EVENT.
TEST_F(DesktopTaskSwitchMetricRecorderTest,
ActivatePositionableWindowWithNonInputEventReason) {
std::unique_ptr<aura::Window> positionable_window_1 =
CreatePositionableWindow();
std::unique_ptr<aura::Window> positionable_window_2 =
CreatePositionableWindow();
ActiveTaskWindowWithUserInput(positionable_window_1.get());
ResetActionCounts();
metrics_recorder_->OnWindowActivated(
ActivationChangeObserver::ActivationReason::ACTIVATION_CLIENT,
positionable_window_2.get(), nullptr);
EXPECT_EQ(0, GetActionCount());
}
// Test fixture to test the integration of the DesktopTaskSwitchMetricsRecorder
// class with ash::Shell environment.
class DesktopTaskSwitchMetricRecorderWithShellIntegrationTest
: public AshTestBase {
public:
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest();
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest(
const DesktopTaskSwitchMetricRecorderWithShellIntegrationTest&) = delete;
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest& operator=(
const DesktopTaskSwitchMetricRecorderWithShellIntegrationTest&) = delete;
~DesktopTaskSwitchMetricRecorderWithShellIntegrationTest() override;
// AshTestBase:
void SetUp() override;
void TearDown() override;
// Returns the number of times the "Desktop_SwitchTask" user action was
// recorded.
int GetActionCount() const;
// Creates a positionable window with the given |bounds| such that
// window_util::IsWindowUserPositionable(...) would return true.
aura::Window* CreatePositionableWindowInShellWithBounds(
const gfx::Rect& bounds);
protected:
// Records UMA user action counts.
std::unique_ptr<base::UserActionTester> user_action_tester_;
// Delegate used when creating new windows using the
// CreatePositionableWindowInShellWithBounds(...) method.
aura::test::TestWindowDelegate test_window_delegate_;
};
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest() = default;
DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::
~DesktopTaskSwitchMetricRecorderWithShellIntegrationTest() = default;
void DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::SetUp() {
AshTestBase::SetUp();
user_action_tester_ = std::make_unique<base::UserActionTester>();
}
void DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::TearDown() {
user_action_tester_.reset();
AshTestBase::TearDown();
}
int DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::GetActionCount()
const {
return user_action_tester_->GetActionCount(kDesktopTaskSwitchUserAction);
}
aura::Window* DesktopTaskSwitchMetricRecorderWithShellIntegrationTest::
CreatePositionableWindowInShellWithBounds(const gfx::Rect& bounds) {
return CreateTestWindowInShellWithDelegate(&test_window_delegate_, 0, bounds);
}
// Verify a user action is recorded when a positionable window is activated by
// a INPUT_EVENT.
TEST_F(DesktopTaskSwitchMetricRecorderWithShellIntegrationTest,
ActivatePositionableWindowWithInputEvent) {
aura::Window* positionable_window =
CreatePositionableWindowInShellWithBounds(gfx::Rect(0, 0, 10, 10));
ui::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
event_generator.MoveMouseToCenterOf(positionable_window);
event_generator.ClickLeftButton();
EXPECT_EQ(1, GetActionCount());
}
// Verify a user action is not recorded when a positionable window is activated
// by a non INPUT_EVENT.
TEST_F(DesktopTaskSwitchMetricRecorderWithShellIntegrationTest,
ActivatePositionableWindowWithNonInputEvent) {
aura::Window* positionable_window =
CreatePositionableWindowInShellWithBounds(gfx::Rect(0, 0, 10, 10));
Shell::Get()->activation_client()->ActivateWindow(positionable_window);
EXPECT_EQ(0, GetActionCount());
}
} // namespace
} // namespace ash