1// Copyright 2014 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 "ui/wm/core/user_activity_detector.h" 6 7#include "base/format_macros.h" 8#include "base/logging.h" 9#include "base/strings/stringprintf.h" 10#include "ui/events/event.h" 11#include "ui/wm/core/user_activity_observer.h" 12 13namespace wm { 14 15namespace { 16 17// Returns a string describing |event|. 18std::string GetEventDebugString(const ui::Event* event) { 19 std::string details = base::StringPrintf( 20 "type=%d name=%s flags=%d time=%" PRId64, 21 event->type(), event->name().c_str(), event->flags(), 22 event->time_stamp().InMilliseconds()); 23 24 if (event->IsKeyEvent()) { 25 details += base::StringPrintf(" key_code=%d", 26 static_cast<const ui::KeyEvent*>(event)->key_code()); 27 } else if (event->IsMouseEvent() || event->IsTouchEvent() || 28 event->IsGestureEvent()) { 29 details += base::StringPrintf(" location=%s", 30 static_cast<const ui::LocatedEvent*>( 31 event)->location().ToString().c_str()); 32 } 33 34 return details; 35} 36 37} // namespace 38 39const int UserActivityDetector::kNotifyIntervalMs = 200; 40 41// Too low and mouse events generated at the tail end of reconfiguration 42// will be reported as user activity and turn the screen back on; too high 43// and we'll ignore legitimate activity. 44const int UserActivityDetector::kDisplayPowerChangeIgnoreMouseMs = 1000; 45 46UserActivityDetector::UserActivityDetector() { 47} 48 49UserActivityDetector::~UserActivityDetector() { 50} 51 52bool UserActivityDetector::HasObserver(UserActivityObserver* observer) const { 53 return observers_.HasObserver(observer); 54} 55 56void UserActivityDetector::AddObserver(UserActivityObserver* observer) { 57 observers_.AddObserver(observer); 58} 59 60void UserActivityDetector::RemoveObserver(UserActivityObserver* observer) { 61 observers_.RemoveObserver(observer); 62} 63 64void UserActivityDetector::OnDisplayPowerChanging() { 65 honor_mouse_events_time_ = GetCurrentTime() + 66 base::TimeDelta::FromMilliseconds(kDisplayPowerChangeIgnoreMouseMs); 67} 68 69void UserActivityDetector::OnKeyEvent(ui::KeyEvent* event) { 70 HandleActivity(event); 71} 72 73void UserActivityDetector::OnMouseEvent(ui::MouseEvent* event) { 74 if (event->flags() & ui::EF_IS_SYNTHESIZED) 75 return; 76 if (!honor_mouse_events_time_.is_null() && 77 GetCurrentTime() < honor_mouse_events_time_) 78 return; 79 80 HandleActivity(event); 81} 82 83void UserActivityDetector::OnScrollEvent(ui::ScrollEvent* event) { 84 HandleActivity(event); 85} 86 87void UserActivityDetector::OnTouchEvent(ui::TouchEvent* event) { 88 HandleActivity(event); 89} 90 91void UserActivityDetector::OnGestureEvent(ui::GestureEvent* event) { 92 HandleActivity(event); 93} 94 95base::TimeTicks UserActivityDetector::GetCurrentTime() const { 96 return !now_for_test_.is_null() ? now_for_test_ : base::TimeTicks::Now(); 97} 98 99void UserActivityDetector::HandleActivity(const ui::Event* event) { 100 base::TimeTicks now = GetCurrentTime(); 101 last_activity_time_ = now; 102 if (last_observer_notification_time_.is_null() || 103 (now - last_observer_notification_time_).InMillisecondsF() >= 104 kNotifyIntervalMs) { 105 if (VLOG_IS_ON(1)) 106 VLOG(1) << "Reporting user activity: " << GetEventDebugString(event); 107 FOR_EACH_OBSERVER(UserActivityObserver, observers_, OnUserActivity(event)); 108 last_observer_notification_time_ = now; 109 } 110} 111 112} // namespace wm 113