#ifndef CHROME_BROWSER_ASH_POWER_ML_IDLE_EVENT_NOTIFIER_H_
#define CHROME_BROWSER_ASH_POWER_ML_IDLE_EVENT_NOTIFIER_H_
#include <memory>
#include <optional>
#include "base/gtest_prod_util.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "chrome/browser/ash/power/ml/boot_clock.h"
#include "chrome/browser/ash/power/ml/user_activity_event.pb.h"
#include "chromeos/dbus/power/power_manager_client.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "services/viz/public/mojom/compositing/video_detector_observer.mojom.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/base/user_activity/user_activity_observer.h"
namespace ash {
namespace power {
namespace ml {
class RecentEventsCounter;
using TimeOfDay = base::TimeDelta;
class IdleEventNotifier : public chromeos::PowerManagerClient::Observer,
public ui::UserActivityObserver,
public viz::mojom::VideoDetectorObserver {
public:
static constexpr base::TimeDelta kIdleDelay = base::Seconds(30);
static constexpr auto kUserInputEventsDuration = base::Hours(1);
static constexpr int kNumUserInputEventsBuckets =
kUserInputEventsDuration.InMinutes();
struct ActivityData {
ActivityData();
ActivityData(const ActivityData& input_data);
UserActivityEvent_Features_DayOfWeek last_activity_day =
UserActivityEvent_Features_DayOfWeek_SUN;
TimeOfDay last_activity_time_of_day;
std::optional<TimeOfDay> last_user_activity_time_of_day;
base::TimeDelta recent_time_active;
std::optional<base::TimeDelta> time_since_last_key;
std::optional<base::TimeDelta> time_since_last_mouse;
std::optional<base::TimeDelta> time_since_last_touch;
base::TimeDelta video_playing_time;
std::optional<base::TimeDelta> time_since_video_ended;
bool is_video_playing = false;
int key_events_in_last_hour = 0;
int mouse_events_in_last_hour = 0;
int touch_events_in_last_hour = 0;
};
IdleEventNotifier(
chromeos::PowerManagerClient* power_client,
ui::UserActivityDetector* detector,
mojo::PendingReceiver<viz::mojom::VideoDetectorObserver> receiver);
IdleEventNotifier(const IdleEventNotifier&) = delete;
IdleEventNotifier& operator=(const IdleEventNotifier&) = delete;
~IdleEventNotifier() override;
void LidEventReceived(chromeos::PowerManagerClient::LidState state,
base::TimeTicks timestamp) override;
void PowerChanged(const power_manager::PowerSupplyProperties& proto) override;
void SuspendDone(base::TimeDelta sleep_duration) override;
void OnUserActivity(const ui::Event* event) override;
void OnVideoActivityStarted() override;
void OnVideoActivityEnded() override;
ActivityData GetActivityDataAndReset();
ActivityData GetActivityData() const;
private:
FRIEND_TEST_ALL_PREFIXES(IdleEventNotifierTest, CheckInitialValues);
friend class IdleEventNotifierTest;
enum class ActivityType {
USER_OTHER,
KEY,
MOUSE,
VIDEO,
TOUCH
};
struct ActivityDataInternal;
ActivityData ConvertActivityData(
const ActivityDataInternal& internal_data) const;
void UpdateActivityData(ActivityType type);
void ResetTimestampsForRecentActivity();
BootClock boot_clock_;
base::ScopedObservation<chromeos::PowerManagerClient,
chromeos::PowerManagerClient::Observer>
power_manager_client_observation_{this};
base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver>
user_activity_observation_{this};
std::optional<power_manager::PowerSupplyProperties_ExternalPower>
external_power_;
base::ObserverList<Observer>::Unchecked observers_;
std::unique_ptr<ActivityDataInternal> internal_data_;
bool video_playing_ = false;
mojo::Receiver<viz::mojom::VideoDetectorObserver> receiver_;
std::unique_ptr<RecentEventsCounter> key_counter_;
std::unique_ptr<RecentEventsCounter> mouse_counter_;
std::unique_ptr<RecentEventsCounter> touch_counter_;
};
}
}
}
#endif