1 // Copyright (c) 2012 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 "ash/wm/user_activity_detector.h" 6 7 #include "ash/wm/user_activity_observer.h" 8 #include "base/format_macros.h" 9 #include "base/logging.h" 10 #include "base/strings/stringprintf.h" 11 #include "ui/events/event.h" 12 13 namespace ash { 14 15 namespace { 16 17 // Returns a string describing |event|. 18 std::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 39 const 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. 44 const int UserActivityDetector::kDisplayPowerChangeIgnoreMouseMs = 1000; 45 46 UserActivityDetector::UserActivityDetector() { 47 } 48 49 UserActivityDetector::~UserActivityDetector() { 50 } 51 52 bool UserActivityDetector::HasObserver(UserActivityObserver* observer) const { 53 return observers_.HasObserver(observer); 54 } 55 56 void UserActivityDetector::AddObserver(UserActivityObserver* observer) { 57 observers_.AddObserver(observer); 58 } 59 60 void UserActivityDetector::RemoveObserver(UserActivityObserver* observer) { 61 observers_.RemoveObserver(observer); 62 } 63 64 void UserActivityDetector::OnDisplayPowerChanging() { 65 honor_mouse_events_time_ = GetCurrentTime() + 66 base::TimeDelta::FromMilliseconds(kDisplayPowerChangeIgnoreMouseMs); 67 } 68 69 void UserActivityDetector::OnKeyEvent(ui::KeyEvent* event) { 70 HandleActivity(event); 71 } 72 73 void 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 83 void UserActivityDetector::OnScrollEvent(ui::ScrollEvent* event) { 84 HandleActivity(event); 85 } 86 87 void UserActivityDetector::OnTouchEvent(ui::TouchEvent* event) { 88 HandleActivity(event); 89 } 90 91 void UserActivityDetector::OnGestureEvent(ui::GestureEvent* event) { 92 HandleActivity(event); 93 } 94 95 base::TimeTicks UserActivityDetector::GetCurrentTime() const { 96 return !now_for_test_.is_null() ? now_for_test_ : base::TimeTicks::Now(); 97 } 98 99 void 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 ash 113