Commit c3431932 authored by bruthig's avatar bruthig Committed by Commit bot

Added metrics to track the time between task switches done via Alt+Tab and Alt+Shift+Tab.

TEST=TaskSwitchMetricsRecorderTest.VerifyTaskSwitchesForWindowCycleControllerAreRecorded

BUG=478946

Review URL: https://codereview.chromium.org/1126333005

Cr-Commit-Position: refs/heads/master@{#330099}
parent ab125670
......@@ -13,12 +13,17 @@ namespace {
const char kShelfHistogramName[] =
"Ash.Shelf.TimeBetweenNavigateToTaskSwitches";
const char kAcceleratorWindowCycleHistogramName[] =
"Ash.WindowCycleController.TimeBetweenTaskSwitches";
// Returns the histogram name for the given |task_switch_source|.
const char* GetHistogramName(
TaskSwitchMetricsRecorder::TaskSwitchSource task_switch_source) {
switch (task_switch_source) {
case TaskSwitchMetricsRecorder::kShelf:
return kShelfHistogramName;
case TaskSwitchMetricsRecorder::kWindowCycleController:
return kAcceleratorWindowCycleHistogramName;
}
NOTREACHED();
return nullptr;
......
......@@ -23,7 +23,9 @@ class ASH_EXPORT TaskSwitchMetricsRecorder {
// a task switch. Note this is not necessarily comprehensive of all sources.
enum TaskSwitchSource {
// All task switches caused by shelf buttons, not including sub-menus.
kShelf
kShelf,
// Task switches caused by the WindowCycleController (ie Alt+Tab).
kWindowCycleController
};
TaskSwitchMetricsRecorder();
......
......@@ -62,6 +62,21 @@ void TaskSwitchMetricsRecorderTest::TearDown() {
} // namespace
// Verifies that the TaskSwitchMetricsRecorder::kWindowCycleController source
// adds data to the Ash.WindowCycleController.TimeBetweenTaskSwitches histogram.
TEST_F(TaskSwitchMetricsRecorderTest,
VerifyTaskSwitchesForWindowCycleControllerAreRecorded) {
const std::string kHistogramName =
"Ash.WindowCycleController.TimeBetweenTaskSwitches";
OnTaskSwitch(TaskSwitchMetricsRecorder::kWindowCycleController);
OnTaskSwitch(TaskSwitchMetricsRecorder::kWindowCycleController);
histogram_tester_->ExpectTotalCount(kHistogramName, 1);
OnTaskSwitch(TaskSwitchMetricsRecorder::kWindowCycleController);
histogram_tester_->ExpectTotalCount(kHistogramName, 2);
}
// Verifies that the TaskSwitchMetricsRecorder::kShelf source adds data to the
// Ash.Shelf.TimeBetweenNavigateToTaskSwitches histogram.
TEST_F(TaskSwitchMetricsRecorderTest,
......
......@@ -149,6 +149,10 @@ class ASH_EXPORT UserMetricsRecorder {
// Records an Ash owned user action.
void RecordUserMetricsAction(ash::UserMetricsAction action);
TaskSwitchMetricsRecorder& task_switch_metrics_recorder() {
return task_switch_metrics_recorder_;
}
private:
friend class test::UserMetricsRecorderTestAPI;
......
......@@ -4,11 +4,13 @@
#include "ash/wm/window_cycle_controller.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/session/session_state_delegate.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/window_cycle_list.h"
#include "base/metrics/histogram.h"
#include "ui/aura/window.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
......@@ -16,6 +18,12 @@ namespace ash {
namespace {
// Returns the most recently active window from the |window_list| or nullptr
// if the list is empty.
aura::Window* GetActiveWindow(const MruWindowTracker::WindowList& window_list) {
return window_list.empty() ? nullptr : window_list[0];
}
// Filter to watch for the termination of a keyboard gesture to cycle through
// multiple windows.
class WindowCycleEventFilter : public ui::EventHandler {
......@@ -77,8 +85,12 @@ void WindowCycleController::HandleCycleWindow(Direction direction) {
}
void WindowCycleController::StartCycling() {
window_cycle_list_.reset(new WindowCycleList(ash::Shell::GetInstance()->
mru_window_tracker()->BuildMruWindowList()));
MruWindowTracker::WindowList window_list =
Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList();
active_window_before_window_cycle_ = GetActiveWindow(window_list);
window_cycle_list_.reset(new WindowCycleList(window_list));
event_handler_.reset(new WindowCycleEventFilter());
cycle_start_time_ = base::Time::Now();
Shell::GetInstance()->metrics()->RecordUserMetricsAction(UMA_WINDOW_CYCLE);
......@@ -94,10 +106,23 @@ void WindowCycleController::Step(Direction direction) {
void WindowCycleController::StopCycling() {
window_cycle_list_.reset();
aura::Window* active_window_after_window_cycle = GetActiveWindow(
Shell::GetInstance()->mru_window_tracker()->BuildMruWindowList());
// Remove our key event filter.
event_handler_.reset();
UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowCycleController.CycleTime",
base::Time::Now() - cycle_start_time_);
if (active_window_after_window_cycle != nullptr &&
active_window_before_window_cycle_ != active_window_after_window_cycle) {
Shell::GetInstance()
->metrics()
->task_switch_metrics_recorder()
.OnTaskSwitch(TaskSwitchMetricsRecorder::kWindowCycleController);
}
active_window_before_window_cycle_ = nullptr;
}
} // namespace ash
......@@ -14,6 +14,10 @@ namespace ui {
class EventHandler;
}
namespace aura {
class Window;
} // namespace aura
namespace ash {
class WindowCycleList;
......@@ -63,6 +67,10 @@ class ASH_EXPORT WindowCycleController {
scoped_ptr<WindowCycleList> window_cycle_list_;
// Tracks what Window was active when starting to cycle and used to determine
// if the active Window changed in when ending cycling.
aura::Window* active_window_before_window_cycle_ = nullptr;
// Event handler to watch for release of alt key.
scoped_ptr<ui::EventHandler> event_handler_;
......
......@@ -916,6 +916,16 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary>
</histogram>
<histogram name="Ash.WindowCycleController.TimeBetweenTaskSwitches"
units="seconds">
<owner>tdanderson@google.com</owner>
<owner>bruthig@google.com</owner>
<summary>
The number of seconds between task switches triggered by the next window and
previous window accelerator keys (ie Alt+Tab, Alt+Shift+Tab).
</summary>
</histogram>
<histogram name="Ash.WindowSelector.ArrowKeyPresses">
<owner>flackr@chromium.org</owner>
<owner>tdanderson@chromium.org</owner>
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