| 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 |