1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/metrics/desktop_session_duration/touch_ui_controller_stats_tracker.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h"
#include "ui/base/pointer/touch_ui_controller.h"
// static
void TouchUIControllerStatsTracker::Initialize(
metrics::DesktopSessionDurationTracker* session_duration_tracker,
ui::TouchUiController* touch_ui_controller) {
static base::NoDestructor<TouchUIControllerStatsTracker> stats_tracker(
session_duration_tracker, touch_ui_controller);
}
TouchUIControllerStatsTracker::TouchUIControllerStatsTracker(
metrics::DesktopSessionDurationTracker* session_duration_tracker,
ui::TouchUiController* touch_ui_controller)
: touch_ui_controller_(touch_ui_controller) {
session_duration_tracker->AddObserver(this);
// If this instance is destroyed, |touch_mode_change_subscription_|'s
// destructor will unregister the callback. Hence Unretained is safe.
touch_mode_change_subscription_ = touch_ui_controller->RegisterCallback(
base::BindRepeating(&TouchUIControllerStatsTracker::TouchModeChanged,
base::Unretained(this)));
#if BUILDFLAG(IS_WIN)
tablet_mode_change_subscription_ =
touch_ui_controller->RegisterTabletModeCallback(
base::BindRepeating(&TouchUIControllerStatsTracker::TabletModeChanged,
base::Unretained(this)));
#endif // BUILDFLAG(IS_WIN)
}
TouchUIControllerStatsTracker::~TouchUIControllerStatsTracker() = default;
// static
const char TouchUIControllerStatsTracker::kSessionTouchDurationHistogramName[] =
"Session.TotalDuration.TouchMode";
#if BUILDFLAG(IS_WIN)
const char
TouchUIControllerStatsTracker::kSessionTabletDurationHistogramName[] =
"Session.TotalDuration.TabletMode";
#endif // BUILDFLAG(IS_WIN)
void TouchUIControllerStatsTracker::TouchModeChanged() {
if (session_start_time_.is_null()) {
return;
}
auto switch_time = base::TimeTicks::Now();
DCHECK_GE(switch_time, last_touch_mode_switch_in_session_);
// If we changed to non-touch mode, we were in touch mode in the span
// of time from last_touch_mode_switch_in_session_ to switch_time.
if (!touch_ui_controller_->touch_ui()) {
touch_mode_duration_in_session_ +=
switch_time - last_touch_mode_switch_in_session_;
}
last_touch_mode_switch_in_session_ = switch_time;
}
#if BUILDFLAG(IS_WIN)
void TouchUIControllerStatsTracker::TabletModeChanged() {
if (session_start_time_.is_null()) {
return;
}
auto switch_time = base::TimeTicks::Now();
DCHECK_GE(switch_time, last_tablet_mode_switch_in_session_);
// If we changed to desktop mode, we were in tablet mode in the span
// of time from last_tablet_mode_switch_in_session_ to switch_time.
if (!touch_ui_controller_->tablet_mode()) {
tablet_mode_duration_in_session_ +=
switch_time - last_tablet_mode_switch_in_session_;
}
last_tablet_mode_switch_in_session_ = switch_time;
}
#endif // BUILDFLAG(IS_WIN)
void TouchUIControllerStatsTracker::OnSessionStarted(
base::TimeTicks session_start) {
session_start_time_ = session_start;
last_touch_mode_switch_in_session_ = session_start_time_;
touch_mode_duration_in_session_ = base::TimeDelta();
#if BUILDFLAG(IS_WIN)
last_tablet_mode_switch_in_session_ = session_start_time_;
tablet_mode_duration_in_session_ = base::TimeDelta();
#endif // BUILDFLAG(IS_WIN)
}
void TouchUIControllerStatsTracker::OnSessionEnded(
base::TimeDelta session_length,
base::TimeTicks session_end) {
// If we end in touch mode, we must count the time from
// last_touch_mode_switch_in_session_ to session_end.
//
// |session_end| may be slightly less than
// |last_touch_mode_switch_in_session_| because an OnSessionEnded()
// call may happen slightly after the session end time. Assuming the
// difference is small, the touch mode time left unaccounted for is small.
// Accept this error and ignore this time. See crbug.com/1165462.
if (touch_ui_controller_->touch_ui() &&
session_end >= last_touch_mode_switch_in_session_) {
touch_mode_duration_in_session_ +=
session_end - last_touch_mode_switch_in_session_;
}
#if BUILDFLAG(IS_WIN)
if (touch_ui_controller_->tablet_mode() &&
session_end >= last_tablet_mode_switch_in_session_) {
tablet_mode_duration_in_session_ +=
session_end - last_tablet_mode_switch_in_session_;
}
#endif // BUILDFLAG(IS_WIN)
// The samples here correspond 1:1 with Session.TotalDuration, so the
// bucketing matches too.
base::UmaHistogramLongTimes(kSessionTouchDurationHistogramName,
touch_mode_duration_in_session_);
session_start_time_ = base::TimeTicks();
last_touch_mode_switch_in_session_ = base::TimeTicks();
touch_mode_duration_in_session_ = base::TimeDelta();
#if BUILDFLAG(IS_WIN)
base::UmaHistogramLongTimes(kSessionTabletDurationHistogramName,
tablet_mode_duration_in_session_);
last_tablet_mode_switch_in_session_ = base::TimeTicks();
tablet_mode_duration_in_session_ = base::TimeDelta();
#endif // BUILDFLAG(IS_WIN)
}
|