OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/mus/ws/user_activity_monitor.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/time/default_tick_clock.h" | |
9 | |
10 namespace mus { | |
11 namespace ws { | |
12 | |
13 UserActivityMonitor::UserActivityMonitor(std::unique_ptr<base::TickClock> clock) | |
14 : now_clock_(std::move(clock)) { | |
15 if (!now_clock_) | |
16 now_clock_ = base::WrapUnique(new base::DefaultTickClock); | |
17 last_activity_ = now_clock_->NowTicks(); | |
18 } | |
19 | |
20 UserActivityMonitor::~UserActivityMonitor() {} | |
21 | |
22 void UserActivityMonitor::OnUserActivity() { | |
23 base::TimeTicks now = now_clock_->NowTicks(); | |
24 for (auto& pair : activity_observers_) { | |
25 ActivityObserverInfo* info = &(pair.first); | |
26 if (info->last_activity_notification.is_null() || | |
27 (now - info->last_activity_notification) > info->delay) { | |
28 pair.second->OnUserActivity(); | |
29 info->last_activity_notification = now; | |
30 } | |
31 } | |
32 | |
33 // Wake up all the 'idle' observers. | |
34 for (auto& pair : idle_observers_) { | |
35 IdleObserverInfo* info = &(pair.first); | |
36 if (info->idle_state == mojom::UserIdleObserver::IdleState::ACTIVE) | |
37 continue; | |
38 info->last_idle_state_notification = now; | |
39 info->idle_state = mojom::UserIdleObserver::IdleState::ACTIVE; | |
40 pair.second->OnUserIdleStateChanged(info->idle_state); | |
41 } | |
42 | |
43 last_activity_ = now; | |
44 | |
45 // Start the timer if there are some idle observers. | |
46 if (idle_timer_.IsRunning()) | |
47 idle_timer_.Reset(); | |
48 } | |
49 | |
50 void UserActivityMonitor::Add(mojom::UserActivityMonitorRequest request) { | |
51 bindings_.AddBinding(this, std::move(request)); | |
52 } | |
53 | |
54 void UserActivityMonitor::AddUserActivityObserver( | |
55 uint32_t delay_between_notify_secs, | |
56 mojom::UserActivityObserverPtr observer) { | |
57 ActivityObserverInfo info; | |
58 info.delay = base::TimeDelta::FromSeconds(delay_between_notify_secs); | |
59 observer.set_connection_error_handler( | |
60 base::Bind(&UserActivityMonitor::OnActivityObserverDisconnected, | |
61 base::Unretained(this), observer.get())); | |
62 activity_observers_.push_back(std::make_pair(info, std::move(observer))); | |
63 } | |
64 | |
65 void UserActivityMonitor::AddUserIdleObserver( | |
66 uint32_t idleness_in_minutes, | |
67 mojom::UserIdleObserverPtr observer) { | |
68 IdleObserverInfo info; | |
69 info.idle_duration = base::TimeDelta::FromMinutes(idleness_in_minutes); | |
70 base::TimeTicks now = now_clock_->NowTicks(); | |
71 DCHECK(!last_activity_.is_null()); | |
72 bool user_is_active = (now - last_activity_ < info.idle_duration); | |
73 info.idle_state = user_is_active ? mojom::UserIdleObserver::IdleState::ACTIVE | |
74 : mojom::UserIdleObserver::IdleState::IDLE; | |
75 info.last_idle_state_notification = now; | |
76 observer->OnUserIdleStateChanged(info.idle_state); | |
77 observer.set_connection_error_handler( | |
78 base::Bind(&UserActivityMonitor::OnIdleObserverDisconnected, | |
79 base::Unretained(this), observer.get())); | |
80 idle_observers_.push_back(std::make_pair(info, std::move(observer))); | |
81 if (user_is_active) | |
82 ActivateIdleTimer(); | |
83 } | |
84 | |
85 void UserActivityMonitor::ActivateIdleTimer() { | |
86 if (idle_timer_.IsRunning()) | |
87 return; | |
88 idle_timer_.Start(FROM_HERE, base::TimeDelta::FromMinutes(1), this, | |
89 &UserActivityMonitor::OnMinuteTimer); | |
90 } | |
91 | |
92 void UserActivityMonitor::OnMinuteTimer() { | |
93 base::TimeTicks now = now_clock_->NowTicks(); | |
94 bool active_observer = false; | |
95 for (auto& pair : idle_observers_) { | |
96 IdleObserverInfo* info = &(pair.first); | |
97 if (info->idle_state == mojom::UserIdleObserver::IdleState::IDLE) | |
98 continue; | |
99 if (now - info->last_idle_state_notification < info->idle_duration) { | |
100 active_observer = true; | |
101 continue; | |
102 } | |
103 info->last_idle_state_notification = now; | |
104 info->idle_state = mojom::UserIdleObserver::IdleState::IDLE; | |
105 pair.second->OnUserIdleStateChanged(info->idle_state); | |
106 } | |
107 // All observers are already notified of IDLE. No point running the timer | |
108 // anymore. | |
109 if (!active_observer) | |
110 idle_timer_.Stop(); | |
111 } | |
112 | |
113 void UserActivityMonitor::OnActivityObserverDisconnected( | |
114 mojom::UserActivityObserver* observer) { | |
115 activity_observers_.erase(std::remove_if( | |
116 activity_observers_.begin(), activity_observers_.end(), | |
117 [observer](const std::pair<ActivityObserverInfo, | |
118 mojom::UserActivityObserverPtr>& pair) { | |
119 return pair.second.get() == observer; | |
120 })); | |
121 } | |
122 | |
123 void UserActivityMonitor::OnIdleObserverDisconnected( | |
124 mojom::UserIdleObserver* observer) { | |
125 idle_observers_.erase(std::remove_if( | |
126 idle_observers_.begin(), idle_observers_.end(), | |
127 [observer]( | |
128 const std::pair<IdleObserverInfo, mojom::UserIdleObserverPtr>& pair) { | |
129 return pair.second.get() == observer; | |
130 })); | |
131 } | |
132 | |
133 } // namespace ws | |
134 } // namespace mus | |
OLD | NEW |