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/strings/string_number_conversions.h"
11 #include "extensions/browser/api/idle/idle_api_constants.h"
12 #include "extensions/browser/api/idle/idle_manager_factory.h"
13 #include "extensions/browser/api/idle/idle_manager.h"
14 #include "extensions/browser/api_unittest.h"
15 #include "extensions/browser/event_router.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "extensions/common/api/idle.h"
18 #include "extensions/common/extension.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
24 namespace idle
= extensions::core_api::idle
;
26 namespace extensions
{
30 class MockEventDelegate
: public IdleManager::EventDelegate
{
32 MockEventDelegate() {}
33 virtual ~MockEventDelegate() {}
34 MOCK_METHOD2(OnStateChanged
, void(const std::string
&, ui::IdleState
));
35 virtual void RegisterObserver(EventRouter::Observer
* observer
) {}
36 virtual void UnregisterObserver(EventRouter::Observer
* observer
) {}
39 class TestIdleProvider
: public IdleManager::IdleTimeProvider
{
42 ~TestIdleProvider() override
;
43 void CalculateIdleState(int idle_threshold
, ui::IdleCallback notify
) override
;
44 void CalculateIdleTime(ui::IdleTimeCallback notify
) override
;
45 bool CheckIdleStateIsLocked() override
;
47 void set_idle_time(int idle_time
);
48 void set_locked(bool locked
);
55 TestIdleProvider::TestIdleProvider() : idle_time_(0), locked_(false) {
58 TestIdleProvider::~TestIdleProvider() {
61 void TestIdleProvider::CalculateIdleState(int idle_threshold
,
62 ui::IdleCallback notify
) {
64 notify
.Run(ui::IDLE_STATE_LOCKED
);
66 if (idle_time_
>= idle_threshold
) {
67 notify
.Run(ui::IDLE_STATE_IDLE
);
69 notify
.Run(ui::IDLE_STATE_ACTIVE
);
74 void TestIdleProvider::CalculateIdleTime(ui::IdleTimeCallback notify
) {
75 notify
.Run(idle_time_
);
78 bool TestIdleProvider::CheckIdleStateIsLocked() {
82 void TestIdleProvider::set_idle_time(int idle_time
) {
83 idle_time_
= idle_time
;
86 void TestIdleProvider::set_locked(bool locked
) {
92 ScopedListen(IdleManager
* idle_manager
, const std::string
& extension_id
);
96 IdleManager
* idle_manager_
;
97 const std::string extension_id_
;
100 ScopedListen::ScopedListen(IdleManager
* idle_manager
,
101 const std::string
& extension_id
)
102 : idle_manager_(idle_manager
), extension_id_(extension_id
) {
103 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
104 extension_id_
, GURL(), NULL
);
105 idle_manager_
->OnListenerAdded(details
);
108 ScopedListen::~ScopedListen() {
109 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
110 extension_id_
, GURL(), NULL
);
111 idle_manager_
->OnListenerRemoved(details
);
114 KeyedService
* IdleManagerTestFactory(content::BrowserContext
* context
) {
115 return new IdleManager(context
);
120 class IdleTest
: public ApiUnitTest
{
122 void SetUp() override
;
125 IdleManager
* idle_manager_
;
126 TestIdleProvider
* idle_provider_
;
127 testing::StrictMock
<MockEventDelegate
>* event_delegate_
;
130 void IdleTest::SetUp() {
131 ApiUnitTest::SetUp();
133 IdleManagerFactory::GetInstance()->SetTestingFactory(browser_context(),
134 &IdleManagerTestFactory
);
135 idle_manager_
= IdleManagerFactory::GetForBrowserContext(browser_context());
137 idle_provider_
= new TestIdleProvider();
138 idle_manager_
->SetIdleTimeProviderForTest(
139 scoped_ptr
<IdleManager::IdleTimeProvider
>(idle_provider_
).Pass());
140 event_delegate_
= new testing::StrictMock
<MockEventDelegate
>();
141 idle_manager_
->SetEventDelegateForTest(
142 scoped_ptr
<IdleManager::EventDelegate
>(event_delegate_
).Pass());
143 idle_manager_
->Init();
146 // Verifies that "locked" takes priority over "active".
147 TEST_F(IdleTest
, QueryLockedActive
) {
148 idle_provider_
->set_locked(true);
149 idle_provider_
->set_idle_time(0);
151 scoped_ptr
<base::Value
> result(
152 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
154 std::string idle_state
;
155 ASSERT_TRUE(result
->GetAsString(&idle_state
));
156 EXPECT_EQ("locked", idle_state
);
159 // Verifies that "locked" takes priority over "idle".
160 TEST_F(IdleTest
, QueryLockedIdle
) {
161 idle_provider_
->set_locked(true);
162 idle_provider_
->set_idle_time(INT_MAX
);
164 scoped_ptr
<base::Value
> result(
165 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
167 std::string idle_state
;
168 ASSERT_TRUE(result
->GetAsString(&idle_state
));
169 EXPECT_EQ("locked", idle_state
);
172 // Verifies that any amount of idle time less than the detection interval
173 // translates to a state of "active".
174 TEST_F(IdleTest
, QueryActive
) {
175 idle_provider_
->set_locked(false);
177 for (int time
= 0; time
< 60; ++time
) {
179 idle_provider_
->set_idle_time(time
);
181 scoped_ptr
<base::Value
> result(
182 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
184 std::string idle_state
;
185 ASSERT_TRUE(result
->GetAsString(&idle_state
));
186 EXPECT_EQ("active", idle_state
);
190 // Verifies that an idle time >= the detection interval returns the "idle"
192 TEST_F(IdleTest
, QueryIdle
) {
193 idle_provider_
->set_locked(false);
195 for (int time
= 80; time
>= 60; --time
) {
197 idle_provider_
->set_idle_time(time
);
199 scoped_ptr
<base::Value
> result(
200 RunFunctionAndReturnValue(new IdleQueryStateFunction(), "[60]"));
202 std::string idle_state
;
203 ASSERT_TRUE(result
->GetAsString(&idle_state
));
204 EXPECT_EQ("idle", idle_state
);
208 // Verifies that requesting a detection interval < 15 has the same effect as
210 TEST_F(IdleTest
, QueryMinThreshold
) {
211 idle_provider_
->set_locked(false);
213 for (int threshold
= 0; threshold
< 20; ++threshold
) {
214 for (int time
= 10; time
< 60; ++time
) {
215 SCOPED_TRACE(threshold
);
217 idle_provider_
->set_idle_time(time
);
219 std::string args
= "[" + base::IntToString(threshold
) + "]";
220 scoped_ptr
<base::Value
> result(
221 RunFunctionAndReturnValue(new IdleQueryStateFunction(), args
));
223 std::string idle_state
;
224 ASSERT_TRUE(result
->GetAsString(&idle_state
));
226 int real_threshold
= (threshold
< 15) ? 15 : threshold
;
227 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
228 EXPECT_EQ(expected
, idle_state
);
233 // Verifies that passing in a detection interval > 4 hours has the same effect
234 // as passing in 4 hours.
235 TEST_F(IdleTest
, QueryMaxThreshold
) {
236 idle_provider_
->set_locked(false);
238 const int kFourHoursInSeconds
= 4 * 60 * 60;
240 for (int threshold
= kFourHoursInSeconds
- 20;
241 threshold
< (kFourHoursInSeconds
+ 20); ++threshold
) {
242 for (int time
= kFourHoursInSeconds
- 30; time
< kFourHoursInSeconds
+ 30;
244 SCOPED_TRACE(threshold
);
246 idle_provider_
->set_idle_time(time
);
248 std::string args
= "[" + base::IntToString(threshold
) + "]";
249 scoped_ptr
<base::Value
> result(
250 RunFunctionAndReturnValue(new IdleQueryStateFunction(), args
));
252 std::string idle_state
;
253 ASSERT_TRUE(result
->GetAsString(&idle_state
));
256 (threshold
> kFourHoursInSeconds
) ? kFourHoursInSeconds
: threshold
;
257 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
258 EXPECT_EQ(expected
, idle_state
);
263 // Verifies that transitioning from an active to idle state fires an "idle"
264 // OnStateChanged event.
265 TEST_F(IdleTest
, ActiveToIdle
) {
266 ScopedListen
listen_test(idle_manager_
, "test");
268 idle_provider_
->set_locked(false);
270 for (int time
= 0; time
< 60; ++time
) {
272 idle_provider_
->set_idle_time(time
);
274 idle_manager_
->UpdateIdleState();
277 idle_provider_
->set_idle_time(60);
279 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
280 idle_manager_
->UpdateIdleState();
281 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
283 for (int time
= 61; time
< 75; ++time
) {
285 idle_provider_
->set_idle_time(time
);
286 idle_manager_
->UpdateIdleState();
290 // Verifies that locking an active system generates a "locked" event.
291 TEST_F(IdleTest
, ActiveToLocked
) {
292 ScopedListen
listen_test(idle_manager_
, "test");
294 idle_provider_
->set_locked(true);
295 idle_provider_
->set_idle_time(5);
297 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
298 idle_manager_
->UpdateIdleState();
301 // Verifies that transitioning from an idle to active state generates an
303 TEST_F(IdleTest
, IdleToActive
) {
304 ScopedListen
listen_test(idle_manager_
, "test");
306 idle_provider_
->set_locked(false);
307 idle_provider_
->set_idle_time(75);
308 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
309 idle_manager_
->UpdateIdleState();
310 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
312 idle_provider_
->set_idle_time(0);
313 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_ACTIVE
));
314 idle_manager_
->UpdateIdleState();
317 // Verifies that locking an idle system generates a "locked" event.
318 TEST_F(IdleTest
, IdleToLocked
) {
319 ScopedListen
listen_test(idle_manager_
, "test");
321 idle_provider_
->set_locked(false);
322 idle_provider_
->set_idle_time(75);
324 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
325 idle_manager_
->UpdateIdleState();
326 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
328 idle_provider_
->set_locked(true);
329 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
330 idle_manager_
->UpdateIdleState();
333 // Verifies that unlocking an active system generates an "active" event.
334 TEST_F(IdleTest
, LockedToActive
) {
335 ScopedListen
listen_test(idle_manager_
, "test");
337 idle_provider_
->set_locked(true);
338 idle_provider_
->set_idle_time(0);
340 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
341 idle_manager_
->UpdateIdleState();
343 idle_provider_
->set_locked(false);
344 idle_provider_
->set_idle_time(5);
345 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_ACTIVE
));
346 idle_manager_
->UpdateIdleState();
349 // Verifies that unlocking an inactive system generates an "idle" event.
350 TEST_F(IdleTest
, LockedToIdle
) {
351 ScopedListen
listen_test(idle_manager_
, "test");
353 idle_provider_
->set_locked(true);
354 idle_provider_
->set_idle_time(75);
355 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_LOCKED
));
356 idle_manager_
->UpdateIdleState();
357 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
359 idle_provider_
->set_locked(false);
360 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
361 idle_manager_
->UpdateIdleState();
364 // Verifies that events are routed to extensions that have one or more listeners
366 TEST_F(IdleTest
, MultipleExtensions
) {
367 ScopedListen
listen_1(idle_manager_
, "1");
368 ScopedListen
listen_2(idle_manager_
, "2");
370 idle_provider_
->set_locked(true);
371 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_LOCKED
));
372 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_LOCKED
));
373 idle_manager_
->UpdateIdleState();
374 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
377 ScopedListen
listen_2prime(idle_manager_
, "2");
378 ScopedListen
listen_3(idle_manager_
, "3");
379 idle_provider_
->set_locked(false);
380 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_ACTIVE
));
381 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_ACTIVE
));
382 EXPECT_CALL(*event_delegate_
, OnStateChanged("3", ui::IDLE_STATE_ACTIVE
));
383 idle_manager_
->UpdateIdleState();
384 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
387 idle_provider_
->set_locked(true);
388 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", ui::IDLE_STATE_LOCKED
));
389 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", ui::IDLE_STATE_LOCKED
));
390 idle_manager_
->UpdateIdleState();
393 // Verifies that setDetectionInterval changes the detection interval from the
394 // default of 60 seconds, and that the call only affects a single extension's
396 TEST_F(IdleTest
, SetDetectionInterval
) {
397 ScopedListen
listen_default(idle_manager_
, "default");
398 ScopedListen
listen_extension(idle_manager_
, extension()->id());
400 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
401 new IdleSetDetectionIntervalFunction(), "[45]"));
403 idle_provider_
->set_locked(false);
404 idle_provider_
->set_idle_time(44);
405 idle_manager_
->UpdateIdleState();
407 idle_provider_
->set_idle_time(45);
408 EXPECT_CALL(*event_delegate_
,
409 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
410 idle_manager_
->UpdateIdleState();
411 // Verify that the expectation has been fulfilled before incrementing the
413 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
415 idle_provider_
->set_idle_time(60);
416 EXPECT_CALL(*event_delegate_
, OnStateChanged("default", ui::IDLE_STATE_IDLE
));
417 idle_manager_
->UpdateIdleState();
420 // Verifies that setting the detection interval before creating the listener
422 TEST_F(IdleTest
, SetDetectionIntervalBeforeListener
) {
423 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
424 new IdleSetDetectionIntervalFunction(), "[45]"));
426 ScopedListen
listen_extension(idle_manager_
, extension()->id());
428 idle_provider_
->set_locked(false);
429 idle_provider_
->set_idle_time(44);
430 idle_manager_
->UpdateIdleState();
432 idle_provider_
->set_idle_time(45);
433 EXPECT_CALL(*event_delegate_
,
434 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
435 idle_manager_
->UpdateIdleState();
438 // Verifies that setting a detection interval above the maximum value results
439 // in an interval of 4 hours.
440 TEST_F(IdleTest
, SetDetectionIntervalMaximum
) {
441 ScopedListen
listen_extension(idle_manager_
, extension()->id());
443 scoped_ptr
<base::Value
> result(
444 RunFunctionAndReturnValue(new IdleSetDetectionIntervalFunction(),
445 "[18000]")); // five hours in seconds
447 idle_provider_
->set_locked(false);
448 idle_provider_
->set_idle_time(4 * 60 * 60 - 1);
449 idle_manager_
->UpdateIdleState();
451 idle_provider_
->set_idle_time(4 * 60 * 60);
452 EXPECT_CALL(*event_delegate_
,
453 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
454 idle_manager_
->UpdateIdleState();
457 // Verifies that setting a detection interval below the minimum value results
458 // in an interval of 15 seconds.
459 TEST_F(IdleTest
, SetDetectionIntervalMinimum
) {
460 ScopedListen
listen_extension(idle_manager_
, extension()->id());
462 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
463 new IdleSetDetectionIntervalFunction(), "[10]"));
465 idle_provider_
->set_locked(false);
466 idle_provider_
->set_idle_time(14);
467 idle_manager_
->UpdateIdleState();
469 idle_provider_
->set_idle_time(15);
470 EXPECT_CALL(*event_delegate_
,
471 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
472 idle_manager_
->UpdateIdleState();
475 // Verifies that an extension's detection interval is discarded when it unloads.
476 TEST_F(IdleTest
, UnloadCleanup
) {
478 ScopedListen
listen(idle_manager_
, extension()->id());
480 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
481 new IdleSetDetectionIntervalFunction(), "[15]"));
484 // Listener count dropping to zero does not reset threshold.
487 ScopedListen
listen(idle_manager_
, extension()->id());
488 idle_provider_
->set_idle_time(16);
489 EXPECT_CALL(*event_delegate_
,
490 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
491 idle_manager_
->UpdateIdleState();
492 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
495 // Threshold will reset after unload (and listen count == 0)
496 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
497 registry
->TriggerOnUnloaded(extension(),
498 UnloadedExtensionInfo::REASON_UNINSTALL
);
501 ScopedListen
listen(idle_manager_
, extension()->id());
502 idle_manager_
->UpdateIdleState();
503 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
505 idle_provider_
->set_idle_time(61);
506 EXPECT_CALL(*event_delegate_
,
507 OnStateChanged(extension()->id(), ui::IDLE_STATE_IDLE
));
508 idle_manager_
->UpdateIdleState();
512 // Verifies that unloading an extension with no listeners or threshold works.
513 TEST_F(IdleTest
, UnloadOnly
) {
514 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
515 registry
->TriggerOnUnloaded(extension(),
516 UnloadedExtensionInfo::REASON_UNINSTALL
);
519 // Verifies that its ok for the unload notification to happen before all the
520 // listener removals.
521 TEST_F(IdleTest
, UnloadWhileListening
) {
522 ScopedListen
listen(idle_manager_
, extension()->id());
523 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser_context());
524 registry
->TriggerOnUnloaded(extension(),
525 UnloadedExtensionInfo::REASON_UNINSTALL
);
528 // Verifies that re-adding a listener after a state change doesn't immediately
529 // fire a change event. Regression test for http://crbug.com/366580.
530 TEST_F(IdleTest
, ReAddListener
) {
531 idle_provider_
->set_locked(false);
535 ScopedListen
listen(idle_manager_
, "test");
536 idle_provider_
->set_idle_time(60);
537 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", ui::IDLE_STATE_IDLE
));
538 idle_manager_
->UpdateIdleState();
539 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
543 idle_provider_
->set_idle_time(0);
544 idle_manager_
->UpdateIdleState();
547 // Nothing should have fired, the listener wasn't added until afterward.
548 ScopedListen
listen(idle_manager_
, "test");
549 idle_manager_
->UpdateIdleState();
550 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
554 } // namespace extensions