Commit 280c46f3 authored by Jia's avatar Jia Committed by Commit Bot

Add user and video activity observers to idle event notifier.

This cl adds ui::UserActivityObserver and
viz::mojom::VideoDetectorObserver to listen to relevant events when
generating idle events.

See https://docs.google.com/document/d/123eFd0rUTu0140V6hJKkkWmpqibdIfM-zTtUR5a2qaQ/edit#
for more detail.

Bug: 784232
Change-Id: I64bae608ea7500406197c3219f26599962256adc
Reviewed-on: https://chromium-review.googlesource.com/780480Reviewed-by: default avatarEmily Stark <estark@chromium.org>
Reviewed-by: default avatarenne <enne@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarRenjie Liu <renjieliu@chromium.org>
Commit-Queue: Jia Meng <jiameng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#519864}
parent 1be35973
......@@ -24,6 +24,7 @@ include_rules = [
"+media/mojo/interfaces", # For platform verification mojom interface.
"+mojo/edk/embedder",
"+services/device/public",
"+services/viz/public/interfaces",
# Chromeos should not use ozone directly, it must go through mojo as ozone
# does not run in process in mus.
"-ui/ozone/public",
......
......@@ -9,20 +9,46 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager/idle.pb.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
namespace chromeos {
namespace power {
namespace ml {
IdleEventNotifier::IdleEventNotifier(const base::TimeDelta& idle_delay)
: idle_delay_(idle_delay), clock_(std::make_unique<base::DefaultClock>()) {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(
this);
IdleEventNotifier::ActivityData::ActivityData() = default;
IdleEventNotifier::ActivityData::ActivityData(base::Time last_activity_time,
base::Time earliest_activity_time)
: last_activity_time(last_activity_time),
earliest_activity_time(earliest_activity_time) {}
IdleEventNotifier::ActivityData::ActivityData(const ActivityData& input_data) {
last_activity_time = input_data.last_activity_time;
earliest_activity_time = input_data.earliest_activity_time;
last_user_activity_time = input_data.last_user_activity_time;
last_mouse_time = input_data.last_mouse_time;
last_key_time = input_data.last_key_time;
}
IdleEventNotifier::IdleEventNotifier(
PowerManagerClient* power_client,
viz::mojom::VideoDetectorObserverRequest request)
: clock_(std::make_unique<base::DefaultClock>()),
power_client_(power_client),
binding_(this, std::move(request)) {
DCHECK(power_client_);
power_client_->AddObserver(this);
ui::UserActivityDetector* detector = ui::UserActivityDetector::Get();
DCHECK(detector);
detector->AddObserver(this);
}
IdleEventNotifier::~IdleEventNotifier() {
chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
this);
power_client_->RemoveObserver(this);
ui::UserActivityDetector* detector = ui::UserActivityDetector::Get();
DCHECK(detector);
detector->RemoveObserver(this);
}
void IdleEventNotifier::SetClockForTesting(
......@@ -45,7 +71,7 @@ void IdleEventNotifier::LidEventReceived(
const base::TimeTicks& /* timestamp */) {
// Ignore lid-close event, as we will observe suspend signal.
if (state == chromeos::PowerManagerClient::LidState::OPEN) {
last_activity_time_ = clock_->Now();
UpdateActivityData(ActivityType::USER_OTHER);
ResetIdleDelayTimer();
}
}
......@@ -54,8 +80,7 @@ void IdleEventNotifier::PowerChanged(
const power_manager::PowerSupplyProperties& proto) {
if (external_power_ != proto.external_power()) {
external_power_ = proto.external_power();
last_activity_time_ = clock_->Now();
// Power change is a user activity, so reset timer.
UpdateActivityData(ActivityType::USER_OTHER);
ResetIdleDelayTimer();
}
}
......@@ -63,10 +88,10 @@ void IdleEventNotifier::PowerChanged(
void IdleEventNotifier::SuspendImminent(
power_manager::SuspendImminent::Reason reason) {
if (idle_delay_timer_.IsRunning()) {
// This means the user hasn't been idle for more than kModelStartDelaySec.
// Regardless of the reason of suspend, we won't be emitting any idle event
// now or following SuspendDone.
// We stop the timer to prevent it from resuming in SuspendDone.
// This means the user hasn't been idle for more than idle_delay. Regardless
// of the reason of suspend, we won't be emitting any idle event now or
// following SuspendDone. We stop the timer to prevent it from resuming in
// SuspendDone.
idle_delay_timer_.Stop();
}
}
......@@ -75,20 +100,80 @@ void IdleEventNotifier::SuspendDone(const base::TimeDelta& sleep_duration) {
// TODO(jiameng): consider check sleep_duration to decide whether to log
// event.
DCHECK(!idle_delay_timer_.IsRunning());
last_activity_time_ = clock_->Now();
// SuspendDone is triggered by user opening the lid (or other user
// activities).
UpdateActivityData(ActivityType::USER_OTHER);
ResetIdleDelayTimer();
}
void IdleEventNotifier::OnUserActivity(const ui::Event* event) {
if (!event)
return;
// Get the type of activity first then reset timer.
ActivityType type = ActivityType::USER_OTHER;
if (event->IsKeyEvent()) {
type = ActivityType::KEY;
} else if (event->IsMouseEvent() || event->IsTouchEvent()) {
type = ActivityType::MOUSE;
}
UpdateActivityData(type);
ResetIdleDelayTimer();
}
void IdleEventNotifier::OnVideoActivityStarted() {
video_playing_ = true;
UpdateActivityData(ActivityType::VIDEO);
}
void IdleEventNotifier::OnVideoActivityEnded() {
video_playing_ = false;
UpdateActivityData(ActivityType::VIDEO);
ResetIdleDelayTimer();
}
void IdleEventNotifier::ResetIdleDelayTimer() {
// According to the policy, if there's video playing we should never dim or
// turn off the screen (or transition to any other lower energy state).
if (video_playing_)
return;
idle_delay_timer_.Start(FROM_HERE, idle_delay_, this,
&IdleEventNotifier::OnIdleDelayTimeout);
}
void IdleEventNotifier::OnIdleDelayTimeout() {
ActivityData activity_data;
activity_data.last_activity_time = last_activity_time_;
if (video_playing_)
return;
for (auto& observer : observers_)
observer.OnIdleEventObserved(activity_data);
observer.OnIdleEventObserved(data_);
data_ = {};
}
void IdleEventNotifier::UpdateActivityData(ActivityType type) {
base::Time now = clock_->Now();
data_.last_activity_time = now;
if (data_.earliest_activity_time == base::Time()) {
data_.earliest_activity_time = now;
}
if (type == ActivityType::VIDEO)
return;
// All other activity is user-initiated.
data_.last_user_activity_time = now;
switch (type) {
case ActivityType::KEY:
data_.last_key_time = now;
break;
case ActivityType::MOUSE:
data_.last_mouse_time = now;
break;
default:
// We don't track other activity types.
return;
}
}
} // namespace ml
......
......@@ -14,6 +14,9 @@
#include "base/timer/timer.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "chromeos/dbus/power_manager_client.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/viz/public/interfaces/compositing/video_detector_observer.mojom.h"
#include "ui/base/user_activity/user_activity_observer.h"
namespace base {
class Clock;
......@@ -27,11 +30,37 @@ namespace ml {
// event is generated. An idle event is generated when the idle period reaches
// |idle_delay_|. No further idle events will be generated until user becomes
// active again, followed by an idle period of |idle_delay_|.
class IdleEventNotifier : public PowerManagerClient::Observer {
class IdleEventNotifier : public PowerManagerClient::Observer,
public ui::UserActivityObserver,
public viz::mojom::VideoDetectorObserver {
public:
struct ActivityData {
// Last activity time.
ActivityData();
ActivityData(base::Time last_activity_time,
base::Time earliest_activity_time);
ActivityData(const ActivityData& input_data);
// Last activity time. This is the activity that triggers idle event.
base::Time last_activity_time;
// Earliest activity time of a *sequence* of activities: whose idle period
// gap is smaller than |idle_delay_|. This value will be the same as
// |last_activity_time| if the earlier activity happened more than
// |idle_delay_| ago.
base::Time earliest_activity_time;
// Last user activity time of the sequence of activities ending in the last
// activity. It could be different from |last_activity_time| if the last
// activity is not a user activity (e.g. video). It is unset (i.e. 0) if
// there is no user activity before the idle event is fired.
base::Time last_user_activity_time;
// Last mouse/key event time of the sequence of activities ending in the
// last activity. It is unset (i.e. 0) if there is no mouse/key activity
// before the idle event.
base::Time last_mouse_time;
base::Time last_key_time;
};
class Observer {
......@@ -43,7 +72,8 @@ class IdleEventNotifier : public PowerManagerClient::Observer {
virtual ~Observer() {}
};
explicit IdleEventNotifier(const base::TimeDelta& idle_delay);
IdleEventNotifier(PowerManagerClient* power_client,
viz::mojom::VideoDetectorObserverRequest request);
~IdleEventNotifier() override;
// Set test clock so that we can check activity time.
......@@ -60,6 +90,13 @@ class IdleEventNotifier : public PowerManagerClient::Observer {
void SuspendImminent(power_manager::SuspendImminent::Reason reason) override;
void SuspendDone(const base::TimeDelta& sleep_duration) override;
// ui::UserActivityObserver overrides:
void OnUserActivity(const ui::Event* event) override;
// viz::mojom::VideoDetectorObserver overrides:
void OnVideoActivityStarted() override;
void OnVideoActivityEnded() override;
const base::TimeDelta& idle_delay() const { return idle_delay_; }
void set_idle_delay(const base::TimeDelta& delay) { idle_delay_ = delay; }
......@@ -67,26 +104,40 @@ class IdleEventNotifier : public PowerManagerClient::Observer {
FRIEND_TEST_ALL_PREFIXES(IdleEventNotifierTest, CheckInitialValues);
friend class IdleEventNotifierTest;
enum class ActivityType {
USER_OTHER, // All other user-related activities.
KEY,
MOUSE,
VIDEO,
};
// Resets |idle_delay_timer_|, it's called when a new activity is observed.
void ResetIdleDelayTimer();
// Called when |idle_delay_timer_| expires.
void OnIdleDelayTimeout();
base::TimeDelta idle_delay_;
// Updates all activity-related timestamps.
void UpdateActivityData(ActivityType type);
base::TimeDelta idle_delay_ = base::TimeDelta::FromSeconds(10);
// It is base::DefaultClock, but will be set to a mock clock for tests.
std::unique_ptr<base::Clock> clock_;
base::OneShotTimer idle_delay_timer_;
PowerManagerClient* power_client_; // not owned.
// Last-received external power state. Changes are treated as user activity.
base::Optional<power_manager::PowerSupplyProperties_ExternalPower>
external_power_;
base::ObserverList<Observer> observers_;
// Time of last activity, which may be a user or non-user activity (e.g.
// video).
base::Time last_activity_time_;
ActivityData data_;
// Whether video is playing.
bool video_playing_ = false;
mojo::Binding<viz::mojom::VideoDetectorObserver> binding_;
DISALLOW_COPY_AND_ASSIGN(IdleEventNotifier);
};
......
......@@ -9,11 +9,14 @@
#include "base/memory/ptr_util.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/clock.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/idle.pb.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
namespace chromeos {
namespace power {
......@@ -21,11 +24,13 @@ namespace ml {
namespace {
// TODO(jiameng): we will add more fields to ActivityData, hence we define an
// equality comparison below for tests.
bool operator==(const IdleEventNotifier::ActivityData& x,
const IdleEventNotifier::ActivityData& y) {
return x.last_activity_time == y.last_activity_time;
return x.last_activity_time == y.last_activity_time &&
x.earliest_activity_time == y.earliest_activity_time &&
x.last_user_activity_time == y.last_user_activity_time &&
x.last_mouse_time == y.last_mouse_time &&
x.last_key_time == y.last_key_time;
}
class TestObserver : public IdleEventNotifier::Observer {
......@@ -59,9 +64,9 @@ class IdleEventNotifierTest : public testing::Test {
: task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::TestMockTimeTaskRunner::Type::kBoundToThread)),
scoped_context_(task_runner_.get()) {
chromeos::DBusThreadManager::Initialize();
idle_event_notifier_ =
std::make_unique<IdleEventNotifier>(base::TimeDelta::FromSeconds(1));
viz::mojom::VideoDetectorObserverPtr observer;
idle_event_notifier_ = std::make_unique<IdleEventNotifier>(
&power_client_, mojo::MakeRequest(&observer));
idle_event_notifier_->SetClockForTesting(task_runner_->GetMockClock());
idle_event_notifier_->AddObserver(&test_observer_);
ac_power_.set_external_power(
......@@ -71,9 +76,7 @@ class IdleEventNotifierTest : public testing::Test {
}
~IdleEventNotifierTest() override {
// Destroy idle event notifier before DBusThreadManager is shut down.
idle_event_notifier_.reset();
chromeos::DBusThreadManager::Shutdown();
}
protected:
......@@ -92,6 +95,8 @@ class IdleEventNotifierTest : public testing::Test {
std::unique_ptr<IdleEventNotifier> idle_event_notifier_;
power_manager::PowerSupplyProperties ac_power_;
power_manager::PowerSupplyProperties disconnected_power_;
FakePowerManagerClient power_client_;
ui::UserActivityDetector user_activity_detector_;
private:
DISALLOW_COPY_AND_ASSIGN(IdleEventNotifierTest);
......@@ -109,14 +114,15 @@ TEST_F(IdleEventNotifierTest, LidOpenEventReceived) {
base::Time now = task_runner_->Now();
idle_event_notifier_->LidEventReceived(
chromeos::PowerManagerClient::LidState::OPEN, base::TimeTicks::Now());
FastForwardAndCheckResults(1, {now});
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
FastForwardAndCheckResults(1, data);
}
// Lid-closed event will not trigger any future idle event to be generated.
TEST_F(IdleEventNotifierTest, LidClosedEventReceived) {
idle_event_notifier_->LidEventReceived(
chromeos::PowerManagerClient::LidState::CLOSED, base::TimeTicks::Now());
IdleEventNotifier::ActivityData expected_activity_data;
FastForwardAndCheckResults(0, {});
}
......@@ -126,7 +132,9 @@ TEST_F(IdleEventNotifierTest, LidClosedEventReceived) {
TEST_F(IdleEventNotifierTest, PowerChangedFirstSet) {
base::Time now = task_runner_->Now();
idle_event_notifier_->PowerChanged(ac_power_);
FastForwardAndCheckResults(1, {now});
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
FastForwardAndCheckResults(1, data);
}
// PowerChanged signal is received but source isn't changed, so it won't trigger
......@@ -134,9 +142,11 @@ TEST_F(IdleEventNotifierTest, PowerChangedFirstSet) {
TEST_F(IdleEventNotifierTest, PowerSourceNotChanged) {
base::Time now = task_runner_->Now();
idle_event_notifier_->PowerChanged(ac_power_);
FastForwardAndCheckResults(1, {now});
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
FastForwardAndCheckResults(1, data);
idle_event_notifier_->PowerChanged(ac_power_);
FastForwardAndCheckResults(1, {now});
FastForwardAndCheckResults(1, data);
}
// PowerChanged signal is received and source is changed, so it will trigger
......@@ -144,11 +154,15 @@ TEST_F(IdleEventNotifierTest, PowerSourceNotChanged) {
TEST_F(IdleEventNotifierTest, PowerSourceChanged) {
base::Time now_1 = task_runner_->Now();
idle_event_notifier_->PowerChanged(ac_power_);
FastForwardAndCheckResults(1, {now_1});
IdleEventNotifier::ActivityData data_1(now_1, now_1);
data_1.last_user_activity_time = now_1;
FastForwardAndCheckResults(1, data_1);
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(100));
base::Time now_2 = task_runner_->Now();
idle_event_notifier_->PowerChanged(disconnected_power_);
FastForwardAndCheckResults(2, {now_2});
IdleEventNotifier::ActivityData data_2(now_2, now_2);
data_2.last_user_activity_time = now_2;
FastForwardAndCheckResults(2, data_2);
}
// SuspendImminent will not trigger any future idle event.
......@@ -165,7 +179,105 @@ TEST_F(IdleEventNotifierTest, SuspendImminent) {
TEST_F(IdleEventNotifierTest, SuspendDone) {
base::Time now = task_runner_->Now();
idle_event_notifier_->SuspendDone(base::TimeDelta::FromSeconds(1));
FastForwardAndCheckResults(1, {now});
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
FastForwardAndCheckResults(1, data);
}
TEST_F(IdleEventNotifierTest, UserActivityKey) {
base::Time now = task_runner_->Now();
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
idle_event_notifier_->OnUserActivity(&key_event);
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
data.last_key_time = now;
FastForwardAndCheckResults(1, data);
}
TEST_F(IdleEventNotifierTest, UserActivityMouse) {
base::Time now = task_runner_->Now();
ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0),
gfx::Point(0, 0), base::TimeTicks(), 0, 0);
idle_event_notifier_->OnUserActivity(&mouse_event);
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
data.last_mouse_time = now;
FastForwardAndCheckResults(1, data);
}
TEST_F(IdleEventNotifierTest, UserActivityOther) {
base::Time now = task_runner_->Now();
ui::GestureEvent gesture_event(0, 0, 0, base::TimeTicks(),
ui::GestureEventDetails(ui::ET_GESTURE_TAP));
idle_event_notifier_->OnUserActivity(&gesture_event);
IdleEventNotifier::ActivityData data(now, now);
data.last_user_activity_time = now;
FastForwardAndCheckResults(1, data);
}
// Two consecutive activities separated by 2sec only. Only 1 idle event with
// different timestamps for the two activities.
TEST_F(IdleEventNotifierTest, TwoQuickUserActivities) {
base::Time now_1 = task_runner_->Now();
ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0),
gfx::Point(0, 0), base::TimeTicks(), 0, 0);
idle_event_notifier_->OnUserActivity(&mouse_event);
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
base::Time now_2 = task_runner_->Now();
ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
idle_event_notifier_->OnUserActivity(&key_event);
IdleEventNotifier::ActivityData data(now_2, now_1);
data.last_user_activity_time = now_2;
data.last_mouse_time = now_1;
data.last_key_time = now_2;
FastForwardAndCheckResults(1, data);
}
TEST_F(IdleEventNotifierTest, ActivityWhileVideoPlaying) {
ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0),
gfx::Point(0, 0), base::TimeTicks(), 0, 0);
idle_event_notifier_->OnVideoActivityStarted();
idle_event_notifier_->OnUserActivity(&mouse_event);
FastForwardAndCheckResults(0, {});
}
// Activity is observed when video isn't playing, it will start idle timer. But
// before timer expires, video starts playing. So when timer expires, no idle
// event will be generated.
TEST_F(IdleEventNotifierTest, ActivityBeforeVideoStarts) {
ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0),
gfx::Point(0, 0), base::TimeTicks(), 0, 0);
idle_event_notifier_->OnUserActivity(&mouse_event);
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
idle_event_notifier_->OnVideoActivityStarted();
FastForwardAndCheckResults(0, {});
}
// An activity is observed when video is playing. No idle timer will be
// triggered but last user activity time will be recorded. Video then stops
// playing that will trigger timer to start.
TEST_F(IdleEventNotifierTest, ActivityAfterVideoStarts) {
ui::MouseEvent mouse_event(ui::ET_MOUSE_EXITED, gfx::Point(0, 0),
gfx::Point(0, 0), base::TimeTicks(), 0, 0);
base::Time now_1 = task_runner_->Now();
idle_event_notifier_->OnVideoActivityStarted();
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
base::Time now_2 = task_runner_->Now();
idle_event_notifier_->OnUserActivity(&mouse_event);
task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2));
base::Time now_3 = task_runner_->Now();
idle_event_notifier_->OnVideoActivityEnded();
IdleEventNotifier::ActivityData data(now_3, now_1);
data.last_user_activity_time = now_2;
data.last_mouse_time = now_2;
FastForwardAndCheckResults(1, data);
}
} // namespace ml
......
......@@ -31,6 +31,7 @@ class TestingUserActivityLoggerDelegate : public UserActivityLoggerDelegate {
const std::vector<UserActivityEvent>& events() const { return events_; }
// UserActivityLoggerDelegate overrides:
void LogActivity(const UserActivityEvent& event) override {
events_.push_back(event);
}
......@@ -44,7 +45,6 @@ class TestingUserActivityLoggerDelegate : public UserActivityLoggerDelegate {
class UserActivityLoggerTest : public testing::Test {
public:
UserActivityLoggerTest() : activity_logger_(&delegate_) {}
~UserActivityLoggerTest() override = default;
protected:
......@@ -69,10 +69,11 @@ class UserActivityLoggerTest : public testing::Test {
// UserActivityEvent.
TEST_F(UserActivityLoggerTest, LogAfterIdleEvent) {
// Trigger an idle event.
ReportIdleEvent({base::Time::Now()});
base::Time now = base::Time::UnixEpoch();
ReportIdleEvent({now, now});
ReportUserActivity(nullptr);
const auto& events = GetEvents();
const std::vector<UserActivityEvent>& events = GetEvents();
ASSERT_EQ(1U, events.size());
UserActivityEvent::Event expected_event;
......@@ -85,7 +86,8 @@ TEST_F(UserActivityLoggerTest, LogAfterIdleEvent) {
TEST_F(UserActivityLoggerTest, LogBeforeIdleEvent) {
ReportUserActivity(nullptr);
// Trigger an idle event.
ReportIdleEvent({base::Time::Now()});
base::Time now = base::Time::UnixEpoch();
ReportIdleEvent({now, now});
EXPECT_EQ(0U, GetEvents().size());
}
......@@ -95,11 +97,12 @@ TEST_F(UserActivityLoggerTest, LogBeforeIdleEvent) {
TEST_F(UserActivityLoggerTest, LogSecondEvent) {
ReportUserActivity(nullptr);
// Trigger an idle event.
ReportIdleEvent({base::Time::Now()});
base::Time now = base::Time::UnixEpoch();
ReportIdleEvent({now, now});
// Another user event.
ReportUserActivity(nullptr);
const auto& events = GetEvents();
const std::vector<UserActivityEvent>& events = GetEvents();
ASSERT_EQ(1U, events.size());
UserActivityEvent::Event expected_event;
......@@ -111,16 +114,18 @@ TEST_F(UserActivityLoggerTest, LogSecondEvent) {
// Log multiple events.
TEST_F(UserActivityLoggerTest, LogMultipleEvents) {
// Trigger an idle event.
ReportIdleEvent({base::Time::Now()});
base::Time now = base::Time::UnixEpoch();
ReportIdleEvent({now, now});
// First user event.
ReportUserActivity(nullptr);
// Trigger an idle event.
ReportIdleEvent({base::Time::Now()});
now = base::Time::UnixEpoch();
ReportIdleEvent({now, now});
// Second user event.
ReportUserActivity(nullptr);
const auto& events = GetEvents();
const std::vector<UserActivityEvent>& events = GetEvents();
ASSERT_EQ(2U, events.size());
UserActivityEvent::Event expected_event;
......
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