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/compiler_specific.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/time/time.h" 10 #include "ui/aura/test/aura_test_base.h" 11 #include "ui/events/event.h" 12 #include "ui/events/event_constants.h" 13 #include "ui/events/keycodes/keyboard_codes.h" 14 #include "ui/gfx/point.h" 15 #include "ui/wm/core/user_activity_observer.h" 16 17 namespace wm { 18 19 // Implementation that just counts the number of times we've been told that the 20 // user is active. 21 class TestUserActivityObserver : public UserActivityObserver { 22 public: 23 TestUserActivityObserver() : num_invocations_(0) {} 24 25 int num_invocations() const { return num_invocations_; } 26 void reset_stats() { num_invocations_ = 0; } 27 28 // UserActivityObserver implementation. 29 virtual void OnUserActivity(const ui::Event* event) OVERRIDE { 30 num_invocations_++; 31 } 32 33 private: 34 // Number of times that OnUserActivity() has been called. 35 int num_invocations_; 36 37 DISALLOW_COPY_AND_ASSIGN(TestUserActivityObserver); 38 }; 39 40 class UserActivityDetectorTest : public aura::test::AuraTestBase { 41 public: 42 UserActivityDetectorTest() {} 43 virtual ~UserActivityDetectorTest() {} 44 45 virtual void SetUp() OVERRIDE { 46 AuraTestBase::SetUp(); 47 observer_.reset(new TestUserActivityObserver); 48 detector_.reset(new UserActivityDetector); 49 detector_->AddObserver(observer_.get()); 50 51 now_ = base::TimeTicks::Now(); 52 detector_->set_now_for_test(now_); 53 } 54 55 virtual void TearDown() OVERRIDE { 56 detector_->RemoveObserver(observer_.get()); 57 AuraTestBase::TearDown(); 58 } 59 60 protected: 61 // Move |detector_|'s idea of the current time forward by |delta|. 62 void AdvanceTime(base::TimeDelta delta) { 63 now_ += delta; 64 detector_->set_now_for_test(now_); 65 } 66 67 scoped_ptr<UserActivityDetector> detector_; 68 scoped_ptr<TestUserActivityObserver> observer_; 69 70 base::TimeTicks now_; 71 72 private: 73 DISALLOW_COPY_AND_ASSIGN(UserActivityDetectorTest); 74 }; 75 76 // Checks that the observer is notified in response to different types of input 77 // events. 78 TEST_F(UserActivityDetectorTest, Basic) { 79 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); 80 detector_->OnKeyEvent(&key_event); 81 EXPECT_FALSE(key_event.handled()); 82 EXPECT_EQ(now_.ToInternalValue(), 83 detector_->last_activity_time().ToInternalValue()); 84 EXPECT_EQ(1, observer_->num_invocations()); 85 observer_->reset_stats(); 86 87 base::TimeDelta advance_delta = base::TimeDelta::FromMilliseconds( 88 UserActivityDetector::kNotifyIntervalMs); 89 AdvanceTime(advance_delta); 90 ui::MouseEvent mouse_event( 91 ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), ui::EF_NONE, ui::EF_NONE); 92 detector_->OnMouseEvent(&mouse_event); 93 EXPECT_FALSE(mouse_event.handled()); 94 EXPECT_EQ(now_.ToInternalValue(), 95 detector_->last_activity_time().ToInternalValue()); 96 EXPECT_EQ(1, observer_->num_invocations()); 97 observer_->reset_stats(); 98 99 base::TimeTicks time_before_ignore = now_; 100 101 // Temporarily ignore mouse events when displays are turned on or off. 102 detector_->OnDisplayPowerChanging(); 103 detector_->OnMouseEvent(&mouse_event); 104 EXPECT_FALSE(mouse_event.handled()); 105 EXPECT_EQ(time_before_ignore.ToInternalValue(), 106 detector_->last_activity_time().ToInternalValue()); 107 EXPECT_EQ(0, observer_->num_invocations()); 108 observer_->reset_stats(); 109 110 const base::TimeDelta kIgnoreMouseTime = 111 base::TimeDelta::FromMilliseconds( 112 UserActivityDetector::kDisplayPowerChangeIgnoreMouseMs); 113 AdvanceTime(kIgnoreMouseTime / 2); 114 detector_->OnMouseEvent(&mouse_event); 115 EXPECT_FALSE(mouse_event.handled()); 116 EXPECT_EQ(time_before_ignore.ToInternalValue(), 117 detector_->last_activity_time().ToInternalValue()); 118 EXPECT_EQ(0, observer_->num_invocations()); 119 observer_->reset_stats(); 120 121 // After enough time has passed, mouse events should be reported again. 122 AdvanceTime(std::max(kIgnoreMouseTime, advance_delta)); 123 detector_->OnMouseEvent(&mouse_event); 124 EXPECT_FALSE(mouse_event.handled()); 125 EXPECT_EQ(now_.ToInternalValue(), 126 detector_->last_activity_time().ToInternalValue()); 127 EXPECT_EQ(1, observer_->num_invocations()); 128 observer_->reset_stats(); 129 130 AdvanceTime(advance_delta); 131 ui::TouchEvent touch_event( 132 ui::ET_TOUCH_PRESSED, gfx::Point(), 0, base::TimeDelta()); 133 detector_->OnTouchEvent(&touch_event); 134 EXPECT_FALSE(touch_event.handled()); 135 EXPECT_EQ(now_.ToInternalValue(), 136 detector_->last_activity_time().ToInternalValue()); 137 EXPECT_EQ(1, observer_->num_invocations()); 138 observer_->reset_stats(); 139 140 AdvanceTime(advance_delta); 141 ui::GestureEvent gesture_event( 142 0, 143 0, 144 ui::EF_NONE, 145 base::TimeDelta::FromMilliseconds(base::Time::Now().ToDoubleT() * 1000), 146 ui::GestureEventDetails(ui::ET_GESTURE_TAP)); 147 detector_->OnGestureEvent(&gesture_event); 148 EXPECT_FALSE(gesture_event.handled()); 149 EXPECT_EQ(now_.ToInternalValue(), 150 detector_->last_activity_time().ToInternalValue()); 151 EXPECT_EQ(1, observer_->num_invocations()); 152 observer_->reset_stats(); 153 } 154 155 // Checks that observers aren't notified too frequently. 156 TEST_F(UserActivityDetectorTest, RateLimitNotifications) { 157 // The observer should be notified about a key event. 158 ui::KeyEvent event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); 159 detector_->OnKeyEvent(&event); 160 EXPECT_FALSE(event.handled()); 161 EXPECT_EQ(1, observer_->num_invocations()); 162 observer_->reset_stats(); 163 164 // It shouldn't be notified if a second event occurs in the same instant in 165 // time. 166 detector_->OnKeyEvent(&event); 167 EXPECT_FALSE(event.handled()); 168 EXPECT_EQ(0, observer_->num_invocations()); 169 observer_->reset_stats(); 170 171 // Advance the time, but not quite enough for another notification to be sent. 172 AdvanceTime( 173 base::TimeDelta::FromMilliseconds( 174 UserActivityDetector::kNotifyIntervalMs - 100)); 175 detector_->OnKeyEvent(&event); 176 EXPECT_FALSE(event.handled()); 177 EXPECT_EQ(0, observer_->num_invocations()); 178 observer_->reset_stats(); 179 180 // Advance time by the notification interval, definitely moving out of the 181 // rate limit. This should let us trigger another notification. 182 AdvanceTime(base::TimeDelta::FromMilliseconds( 183 UserActivityDetector::kNotifyIntervalMs)); 184 185 detector_->OnKeyEvent(&event); 186 EXPECT_FALSE(event.handled()); 187 EXPECT_EQ(1, observer_->num_invocations()); 188 } 189 190 // Checks that the detector ignores synthetic mouse events. 191 TEST_F(UserActivityDetectorTest, IgnoreSyntheticMouseEvents) { 192 ui::MouseEvent mouse_event( 193 ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), ui::EF_IS_SYNTHESIZED, 194 ui::EF_NONE); 195 detector_->OnMouseEvent(&mouse_event); 196 EXPECT_FALSE(mouse_event.handled()); 197 EXPECT_EQ(base::TimeTicks().ToInternalValue(), 198 detector_->last_activity_time().ToInternalValue()); 199 EXPECT_EQ(0, observer_->num_invocations()); 200 } 201 202 } // namespace wm 203