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.
5 #include "extensions/browser/api/idle/idle_api.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "extensions/browser/api/idle/idle_api_constants.h"
13 #include "extensions/browser/api/idle/idle_manager_factory.h"
14 #include "extensions/browser/api/idle/idle_manager.h"
15 #include "extensions/browser/api_unittest.h"
16 #include "extensions/browser/event_router.h"
17 #include "extensions/browser/extension_registry.h"
18 #include "extensions/common/api/idle.h"
19 #include "extensions/common/extension.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
25 namespace idle
= extensions::api::idle
;
27 namespace extensions
{
31 class MockEventDelegate
: public IdleManager::EventDelegate
{
33 MockEventDelegate() {}
34 virtual ~MockEventDelegate() {}
35 MOCK_METHOD2(OnStateChanged
, void(const std::string
&, ui::IdleState
));
36 virtual void RegisterObserver(EventRouter::Observer
* observer
) {}
37 virtual void UnregisterObserver(EventRouter::Observer
* observer
) {}
40 class TestIdleProvider
: public IdleManager::IdleTimeProvider
{
43 ~TestIdleProvider() override
;
44 void CalculateIdleState(int idle_threshold
, ui::IdleCallback notify
) override
;
45 void CalculateIdleTime(ui::IdleTimeCallback notify
) override
;
46 bool CheckIdleStateIsLocked() override
;
48 void set_idle_time(int idle_time
);
49 void set_locked(bool locked
);
56 TestIdleProvider::TestIdleProvider() : idle_time_(0), locked_(false) {
59 TestIdleProvider::~TestIdleProvider() {
62 void TestIdleProvider::CalculateIdleState(int idle_threshold
,
63 ui::IdleCallback notify
) {
65 notify
.Run(ui::IDLE_STATE_LOCKED
);
67 if (idle_time_
>= idle_threshold
) {
68 notify
.Run(ui::IDLE_STATE_IDLE
);
70 notify
.Run(ui::IDLE_STATE_ACTIVE
);
75 void TestIdleProvider::CalculateIdleTime(ui::IdleTimeCallback notify
) {
76 notify
.Run(idle_time_
);
79 bool TestIdleProvider::CheckIdleStateIsLocked() {
83 void TestIdleProvider::set_idle_time(int idle_time
) {
84 idle_time_
= idle_time
;
87 void TestIdleProvider::set_locked(bool locked
) {
93 ScopedListen(IdleManager
* idle_manager
, const std::string
& extension_id
);
97 IdleManager
* idle_manager_
;
98 const std::string extension_id_
;
101 ScopedListen::ScopedListen(IdleManager
* idle_manager
,
102 const std::string
& extension_id
)
103 : idle_manager_(idle_manager
), extension_id_(extension_id
) {
104 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
105 extension_id_
, GURL(), NULL
);
106 idle_manager_
->OnListenerAdded(details
);
109 ScopedListen::~ScopedListen() {
110 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
111 extension_id_
, GURL(), NULL
);
112 idle_manager_
->OnListenerRemoved(details
);
115 scoped_ptr
<KeyedService
> IdleManagerTestFactory(
116 content::BrowserContext
* context
) {
117 return make_scoped_ptr(new IdleManager(context
));
122 class IdleTest
: public ApiUnitTest
{
124 void SetUp() override
;
127 IdleManager
* idle_manager_
;
128 TestIdleProvider
* idle_provider_
;
129 testing::StrictMock
<MockEventDelegate
>* event_delegate_
;
132 void IdleTest::SetUp() {
133 ApiUnitTest::SetUp();
135 IdleManagerFactory::GetInstance()->SetTestingFactory(browser_context(),
136 &IdleManagerTestFactory
);
137 idle_manager_
= IdleManagerFactory::GetForBrowserContext(browser_context());
139 idle_provider_
= new TestIdleProvider();
140 idle_manager_
->SetIdleTimeProviderForTest(
141 scoped_ptr
<IdleManager::IdleTimeProvider
>(idle_provider_
).Pass());
142 event_delegate_
= new testing::StrictMock
<MockEventDelegate
>();
143 idle_manager_
->SetEventDelegateForTest(
144 scoped_ptr
<IdleManager::EventDelegate
>(event_delegate_
).Pass());
145 idle_manager_
->Init();
148 // Verifies that "locked" takes priority over "active".
149 TEST_F(IdleTest
, QueryLockedActive
) {
150 idle_provider_
->set_locked(true);
151 idle_provider_
->set_idle_time(0);
153 scoped_ptr
<base::Value
> result(
154 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
156 std::string idle_state
;
157 ASSERT_TRUE(result
->GetAsString(&idle_state
));
158 EXPECT_EQ("locked", idle_state
);
161 // Verifies that "locked" takes priority over "idle".
162 TEST_F(IdleTest
, QueryLockedIdle
) {
163 idle_provider_
->set_locked(true);
164 idle_provider_
->set_idle_time(INT_MAX
);
166 scoped_ptr
<base::Value
> result(
167 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
169 std::string idle_state
;
170 ASSERT_TRUE(result
->GetAsString(&idle_state
));
171 EXPECT_EQ("locked", idle_state
);
174 // Verifies that any amount of idle time less than the detection interval
175 // translates to a state of "active".
176 TEST_F(IdleTest
, QueryActive
) {
177 idle_provider_
->set_locked(false);
179 for (int time
= 0; time
< 60; ++time
) {
181 idle_provider_
->set_idle_time(time
);
183 scoped_ptr
<base::Value
> result(
184 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
186 std::string idle_state
;
187 ASSERT_TRUE(result
->GetAsString(&idle_state
));
188 EXPECT_EQ("active", idle_state
);
192 // Verifies that an idle time >= the detection interval returns the "idle"
194 TEST_F(IdleTest
, QueryIdle
) {
195 idle_provider_
->set_locked(false);
197 for (int time
= 80; time
>= 60; --time
) {
199 idle_provider_
->set_idle_time(time
);
201 scoped_ptr
<base::Value
> result(
202 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
204 std::string idle_state
;
205 ASSERT_TRUE(result
->GetAsString(&idle_state
));
206 EXPECT_EQ("idle", idle_state
);
210 // Verifies that requesting a detection interval < 15 has the same effect as
212 TEST_F(IdleTest
, QueryMinThreshold
) {
213 idle_provider_
->set_locked(false);
215 for (int threshold
= 0; threshold
< 20; ++threshold
) {
216 for (int time
= 10; time
< 60; ++time
) {
217 SCOPED_TRACE(threshold
);
219 idle_provider_
->set_idle_time(time
);
221 std::string args
= "[" + base::IntToString(threshold
) + "]";
222 scoped_ptr
<base::Value
> result(
223 RunFunctionAndReturnValue(new IdleQueryStateFunction(), args
));
225 std::string idle_state
;
226 ASSERT_TRUE(result
->GetAsString(&idle_state
));
228 int real_threshold
= (threshold
< 15) ? 15 : threshold
;
229 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
230 EXPECT_EQ(expected
, idle_state
);
235 // Verifies that passing in a detection interval > 4 hours has the same effect
236 // as passing in 4 hours.
237 TEST_F(IdleTest
, QueryMaxThreshold
) {
238 idle_provider_
->set_locked(false);
240 const int kFourHoursInSeconds
= 4 * 60 * 60;
242 for (int threshold
= kFourHoursInSeconds
- 20;
243 threshold
< (kFourHoursInSeconds
+ 20); ++threshold
) {
244 for (int time
= kFourHoursInSeconds
- 30; time
< kFourHoursInSeconds
+ 30;
246 SCOPED_TRACE(threshold
);
248 idle_provider_
->set_idle_time(time
);
250 std::string args
= "[" + base::IntToString(threshold
) + "]";
251 scoped_ptr
<base::Value
> result(
252 RunFunctionAndReturnValue(new IdleQueryStateFunction(), args
));
254 std::string idle_state
;
255 ASSERT_TRUE(result
->GetAsString(&idle_state
));
258 (threshold
> kFourHoursInSeconds
) ? kFourHoursInSeconds
: threshold
;
259 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
260 EXPECT_EQ(expected
, idle_state
);
265 // Verifies that transitioning from an active to idle state fires an "idle"
266 // OnStateChanged event.
267 TEST_F(IdleTest
, ActiveToIdle
) {
268 ScopedListen
listen_test(idle_manager_
, "test");
270 idle_provider_
->set_locked(false);
272 for (int time
= 0; time
< 60; ++time
) {
274 idle_provider_
->set_idle_time(time
);
276 idle_manager_
->UpdateIdleState();
279 idle_provider_
->set_idle_time(60);
281 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
282 idle_manager_
->UpdateIdleState();
283 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
285 for (int time
= 61; time
< 75; ++time
) {
287 idle_provider_
->set_idle_time(time
);
288 idle_manager_
->UpdateIdleState();
292 // Verifies that locking an active system generates a "locked" event.
293 TEST_F(IdleTest
, ActiveToLocked
) {
294 ScopedListen
listen_test(idle_manager_
, "test");
296 idle_provider_
->set_locked(true);
297 idle_provider_
->set_idle_time(5);
299 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
300 idle_manager_
->UpdateIdleState();
303 // Verifies that transitioning from an idle to active state generates an
305 TEST_F(IdleTest
, IdleToActive
) {
306 ScopedListen
listen_test(idle_manager_
, "test");
308 idle_provider_
->set_locked(false);
309 idle_provider_
->set_idle_time(75);
310 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
311 idle_manager_
->UpdateIdleState();
312 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
314 idle_provider_
->set_idle_time(0);
315 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_ACTIVE
));
316 idle_manager_
->UpdateIdleState();
319 // Verifies that locking an idle system generates a "locked" event.
320 TEST_F(IdleTest
, IdleToLocked
) {
321 ScopedListen
listen_test(idle_manager_
, "test");
323 idle_provider_
->set_locked(false);
324 idle_provider_
->set_idle_time(75);
326 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
327 idle_manager_
->UpdateIdleState();
328 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
330 idle_provider_
->set_locked(true);
331 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
332 idle_manager_
->UpdateIdleState();
335 // Verifies that unlocking an active system generates an "active" event.
336 TEST_F(IdleTest
, LockedToActive
) {
337 ScopedListen
listen_test(idle_manager_
, "test");
339 idle_provider_
->set_locked(true);
340 idle_provider_
->set_idle_time(0);
342 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
343 idle_manager_
->UpdateIdleState();
345 idle_provider_
->set_locked(false);
346 idle_provider_
->set_idle_time(5);
347 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_ACTIVE
));
348 idle_manager_
->UpdateIdleState();
351 // Verifies that unlocking an inactive system generates an "idle" event.
352 TEST_F(IdleTest
, LockedToIdle
) {
353 ScopedListen
listen_test(idle_manager_
, "test");
355 idle_provider_
->set_locked(true);
356 idle_provider_
->set_idle_time(75);
357 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
358 idle_manager_
->UpdateIdleState();
359 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
361 idle_provider_
->set_locked(false);
362 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
363 idle_manager_
->UpdateIdleState();
366 // Verifies that events are routed to extensions that have one or more listeners
368 TEST_F(IdleTest
, MultipleExtensions
) {
369 ScopedListen
listen_1(idle_manager_
, "1");
370 ScopedListen
listen_2(idle_manager_
, "2");
372 idle_provider_
->set_locked(true);
373 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_LOCKED
));
374 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_LOCKED
));
375 idle_manager_
->UpdateIdleState();
376 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
379 ScopedListen
listen_2prime(idle_manager_
, "2");
380 ScopedListen
listen_3(idle_manager_
, "3");
381 idle_provider_
->set_locked(false);
382 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_ACTIVE
));
383 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_ACTIVE
));
384 EXPECT_CALL(*event_delegate_
, OnStateChanged("3", ui::IDLE_STATE_ACTIVE
));
385 idle_manager_
->UpdateIdleState();
386 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
389 idle_provider_
->set_locked(true);
390 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_LOCKED
));
391 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_LOCKED
));
392 idle_manager_
->UpdateIdleState();
395 // Verifies that setDetectionInterval changes the detection interval from the
396 // default of 60 seconds, and that the call only affects a single extension's
398 TEST_F(IdleTest
, SetDetectionInterval
) {
399 ScopedListen
listen_default(idle_manager_
, "default");
400 ScopedListen
listen_extension(idle_manager_
, extension()->id());
402 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
403 new IdleSetDetectionIntervalFunction(), "[45]"));
405 idle_provider_
->set_locked(false);
406 idle_provider_
->set_idle_time(44);
407 idle_manager_
->UpdateIdleState();
409 idle_provider_
->set_idle_time(45);
410 EXPECT_CALL(*event_delegate_
,
411 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
412 idle_manager_
->UpdateIdleState();
413 // Verify that the expectation has been fulfilled before incrementing the
415 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
417 idle_provider_
->set_idle_time(60);
418 EXPECT_CALL(*event_delegate_
, OnStateChanged("default", ui::IDLE_STATE_IDLE
));
419 idle_manager_
->UpdateIdleState();
422 // Verifies that setting the detection interval before creating the listener
424 TEST_F(IdleTest
, SetDetectionIntervalBeforeListener
) {
425 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
426 new IdleSetDetectionIntervalFunction(), "[45]"));
428 ScopedListen
listen_extension(idle_manager_
, extension()->id());
430 idle_provider_
->set_locked(false);
431 idle_provider_
->set_idle_time(44);
432 idle_manager_
->UpdateIdleState();
434 idle_provider_
->set_idle_time(45);
435 EXPECT_CALL(*event_delegate_
,
436 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
437 idle_manager_
->UpdateIdleState();
440 // Verifies that setting a detection interval above the maximum value results
441 // in an interval of 4 hours.
442 TEST_F(IdleTest
, SetDetectionIntervalMaximum
) {
443 ScopedListen
listen_extension(idle_manager_
, extension()->id());
445 scoped_ptr
<base::Value
> result(
446 RunFunctionAndReturnValue(new IdleSetDetectionIntervalFunction(),
447 "[18000]")); // five hours in seconds
449 idle_provider_
->set_locked(false);
450 idle_provider_
->set_idle_time(4 * 60 * 60 - 1);
451 idle_manager_
->UpdateIdleState();
453 idle_provider_
->set_idle_time(4 * 60 * 60);
454 EXPECT_CALL(*event_delegate_
,
455 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
456 idle_manager_
->UpdateIdleState();
459 // Verifies that setting a detection interval below the minimum value results
460 // in an interval of 15 seconds.
461 TEST_F(IdleTest
, SetDetectionIntervalMinimum
) {
462 ScopedListen
listen_extension(idle_manager_
, extension()->id());
464 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
465 new IdleSetDetectionIntervalFunction(), "[10]"));
467 idle_provider_
->set_locked(false);
468 idle_provider_
->set_idle_time(14);
469 idle_manager_
->UpdateIdleState();
471 idle_provider_
->set_idle_time(15);
472 EXPECT_CALL(*event_delegate_
,
473 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
474 idle_manager_
->UpdateIdleState();
477 // Verifies that an extension's detection interval is discarded when it unloads.
478 TEST_F(IdleTest
, UnloadCleanup
) {
480 ScopedListen
listen(idle_manager_
, extension()->id());
482 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
483 new IdleSetDetectionIntervalFunction(), "[15]"));
486 // Listener count dropping to zero does not reset threshold.
489 ScopedListen
listen(idle_manager_
, extension()->id());
490 idle_provider_
->set_idle_time(16);
491 EXPECT_CALL(*event_delegate_
,
492 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
493 idle_manager_
->UpdateIdleState();
494 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
497 // Threshold will reset after unload (and listen count == 0)
498 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
499 registry
->TriggerOnUnloaded(extension(),
500 UnloadedExtensionInfo::REASON_UNINSTALL
);
503 ScopedListen
listen(idle_manager_
, extension()->id());
504 idle_manager_
->UpdateIdleState();
505 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
507 idle_provider_
->set_idle_time(61);
508 EXPECT_CALL(*event_delegate_
,
509 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
510 idle_manager_
->UpdateIdleState();
514 // Verifies that unloading an extension with no listeners or threshold works.
515 TEST_F(IdleTest
, UnloadOnly
) {
516 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
517 registry
->TriggerOnUnloaded(extension(),
518 UnloadedExtensionInfo::REASON_UNINSTALL
);
521 // Verifies that its ok for the unload notification to happen before all the
522 // listener removals.
523 TEST_F(IdleTest
, UnloadWhileListening
) {
524 ScopedListen
listen(idle_manager_
, extension()->id());
525 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
526 registry
->TriggerOnUnloaded(extension(),
527 UnloadedExtensionInfo::REASON_UNINSTALL
);
530 // Verifies that re-adding a listener after a state change doesn't immediately
531 // fire a change event. Regression test for http://crbug.com/366580.
532 TEST_F(IdleTest
, ReAddListener
) {
533 idle_provider_
->set_locked(false);
537 ScopedListen
listen(idle_manager_
, "test");
538 idle_provider_
->set_idle_time(60);
539 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
540 idle_manager_
->UpdateIdleState();
541 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
545 idle_provider_
->set_idle_time(0);
546 idle_manager_
->UpdateIdleState();
549 // Nothing should have fired, the listener wasn't added until afterward.
550 ScopedListen
listen(idle_manager_
, "test");
551 idle_manager_
->UpdateIdleState();
552 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
556 } // namespace extensions