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 "chrome/browser/extensions/api/idle/idle_api.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/api/idle/idle_api_constants.h"
13 #include "chrome/browser/extensions/api/idle/idle_manager.h"
14 #include "chrome/browser/extensions/api/idle/idle_manager_factory.h"
15 #include "chrome/browser/extensions/extension_api_unittest.h"
16 #include "chrome/common/extensions/api/idle.h"
17 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_source.h"
19 #include "extensions/browser/event_router.h"
20 #include "extensions/common/extension.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
26 namespace idle
= extensions::api::idle
;
28 namespace extensions
{
32 class MockEventDelegate
: public IdleManager::EventDelegate
{
34 MockEventDelegate() {}
35 virtual ~MockEventDelegate() {}
36 MOCK_METHOD2(OnStateChanged
, void(const std::string
&, IdleState
));
37 virtual void RegisterObserver(EventRouter::Observer
* observer
) {}
38 virtual void UnregisterObserver(EventRouter::Observer
* observer
) {}
41 class TestIdleProvider
: public IdleManager::IdleTimeProvider
{
44 virtual ~TestIdleProvider();
45 virtual void CalculateIdleState(int idle_threshold
,
46 IdleCallback notify
) OVERRIDE
;
47 virtual void CalculateIdleTime(IdleTimeCallback notify
) OVERRIDE
;
48 virtual bool CheckIdleStateIsLocked() OVERRIDE
;
50 void set_idle_time(int idle_time
);
51 void set_locked(bool locked
);
58 TestIdleProvider::TestIdleProvider()
63 TestIdleProvider::~TestIdleProvider() {
66 void TestIdleProvider::CalculateIdleState(int idle_threshold
,
67 IdleCallback notify
) {
69 notify
.Run(IDLE_STATE_LOCKED
);
71 if (idle_time_
>= idle_threshold
) {
72 notify
.Run(IDLE_STATE_IDLE
);
74 notify
.Run(IDLE_STATE_ACTIVE
);
79 void TestIdleProvider::CalculateIdleTime(IdleTimeCallback notify
) {
80 notify
.Run(idle_time_
);
83 bool TestIdleProvider::CheckIdleStateIsLocked() {
87 void TestIdleProvider::set_idle_time(int idle_time
) {
88 idle_time_
= idle_time
;
91 void TestIdleProvider::set_locked(bool locked
) {
97 ScopedListen(IdleManager
* idle_manager
, const std::string
& extension_id
);
101 IdleManager
* idle_manager_
;
102 const std::string extension_id_
;
105 ScopedListen::ScopedListen(IdleManager
* idle_manager
,
106 const std::string
& extension_id
)
107 : idle_manager_(idle_manager
),
108 extension_id_(extension_id
) {
109 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
112 idle_manager_
->OnListenerAdded(details
);
115 ScopedListen::~ScopedListen() {
116 const EventListenerInfo
details(idle::OnStateChanged::kEventName
,
119 idle_manager_
->OnListenerRemoved(details
);
122 KeyedService
* IdleManagerTestFactory(content::BrowserContext
* profile
) {
123 return new IdleManager(static_cast<Profile
*>(profile
));
128 class IdleTest
: public ExtensionApiUnittest
{
130 virtual void SetUp() OVERRIDE
;
133 IdleManager
* idle_manager_
;
134 TestIdleProvider
* idle_provider_
;
135 testing::StrictMock
<MockEventDelegate
>* event_delegate_
;
138 void IdleTest::SetUp() {
139 ExtensionApiUnittest::SetUp();
141 IdleManagerFactory::GetInstance()->SetTestingFactory(browser()->profile(),
142 &IdleManagerTestFactory
);
143 idle_manager_
= IdleManagerFactory::GetForProfile(browser()->profile());
145 idle_provider_
= new TestIdleProvider();
146 idle_manager_
->SetIdleTimeProviderForTest(
147 scoped_ptr
<IdleManager::IdleTimeProvider
>(idle_provider_
).Pass());
148 event_delegate_
= new testing::StrictMock
<MockEventDelegate
>();
149 idle_manager_
->SetEventDelegateForTest(
150 scoped_ptr
<IdleManager::EventDelegate
>(event_delegate_
).Pass());
151 idle_manager_
->Init();
154 // Verifies that "locked" takes priority over "active".
155 TEST_F(IdleTest
, QueryLockedActive
) {
156 idle_provider_
->set_locked(true);
157 idle_provider_
->set_idle_time(0);
159 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
160 new IdleQueryStateFunction(),
163 std::string idle_state
;
164 ASSERT_TRUE(result
->GetAsString(&idle_state
));
165 EXPECT_EQ("locked", idle_state
);
168 // Verifies that "locked" takes priority over "idle".
169 TEST_F(IdleTest
, QueryLockedIdle
) {
170 idle_provider_
->set_locked(true);
171 idle_provider_
->set_idle_time(INT_MAX
);
173 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
174 new IdleQueryStateFunction(),
177 std::string idle_state
;
178 ASSERT_TRUE(result
->GetAsString(&idle_state
));
179 EXPECT_EQ("locked", idle_state
);
182 // Verifies that any amount of idle time less than the detection interval
183 // translates to a state of "active".
184 TEST_F(IdleTest
, QueryActive
) {
185 idle_provider_
->set_locked(false);
187 for (int time
= 0; time
< 60; ++time
) {
189 idle_provider_
->set_idle_time(time
);
191 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
192 new IdleQueryStateFunction(),
195 std::string idle_state
;
196 ASSERT_TRUE(result
->GetAsString(&idle_state
));
197 EXPECT_EQ("active", idle_state
);
201 // Verifies that an idle time >= the detection interval returns the "idle"
203 TEST_F(IdleTest
, QueryIdle
) {
204 idle_provider_
->set_locked(false);
206 for (int time
= 80; time
>= 60; --time
) {
208 idle_provider_
->set_idle_time(time
);
210 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
211 new IdleQueryStateFunction(),
214 std::string idle_state
;
215 ASSERT_TRUE(result
->GetAsString(&idle_state
));
216 EXPECT_EQ("idle", idle_state
);
220 // Verifies that requesting a detection interval < 15 has the same effect as
222 TEST_F(IdleTest
, QueryMinThreshold
) {
223 idle_provider_
->set_locked(false);
225 for (int threshold
= 0; threshold
< 20; ++threshold
) {
226 for (int time
= 10; time
< 60; ++time
) {
227 SCOPED_TRACE(threshold
);
229 idle_provider_
->set_idle_time(time
);
231 std::string args
= "[" + base::IntToString(threshold
) + "]";
232 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
233 new IdleQueryStateFunction(), args
));
235 std::string idle_state
;
236 ASSERT_TRUE(result
->GetAsString(&idle_state
));
238 int real_threshold
= (threshold
< 15) ? 15 : threshold
;
239 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
240 EXPECT_EQ(expected
, idle_state
);
245 // Verifies that passing in a detection interval > 4 hours has the same effect
246 // as passing in 4 hours.
247 TEST_F(IdleTest
, QueryMaxThreshold
) {
248 idle_provider_
->set_locked(false);
250 const int kFourHoursInSeconds
= 4*60*60;
252 for (int threshold
= kFourHoursInSeconds
- 20;
253 threshold
< (kFourHoursInSeconds
+ 20); ++threshold
) {
254 for (int time
= kFourHoursInSeconds
- 30; time
< kFourHoursInSeconds
+ 30;
256 SCOPED_TRACE(threshold
);
258 idle_provider_
->set_idle_time(time
);
260 std::string args
= "[" + base::IntToString(threshold
) + "]";
261 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
262 new IdleQueryStateFunction(), args
));
264 std::string idle_state
;
265 ASSERT_TRUE(result
->GetAsString(&idle_state
));
267 int real_threshold
= (threshold
> kFourHoursInSeconds
) ?
268 kFourHoursInSeconds
: threshold
;
269 const char* expected
= (time
< real_threshold
) ? "active" : "idle";
270 EXPECT_EQ(expected
, idle_state
);
275 // Verifies that transitioning from an active to idle state fires an "idle"
276 // OnStateChanged event.
277 TEST_F(IdleTest
, ActiveToIdle
) {
278 ScopedListen
listen_test(idle_manager_
, "test");
280 idle_provider_
->set_locked(false);
282 for (int time
= 0; time
< 60; ++time
) {
284 idle_provider_
->set_idle_time(time
);
286 idle_manager_
->UpdateIdleState();
289 idle_provider_
->set_idle_time(60);
291 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_IDLE
));
292 idle_manager_
->UpdateIdleState();
293 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
295 for (int time
= 61; time
< 75; ++time
) {
297 idle_provider_
->set_idle_time(time
);
298 idle_manager_
->UpdateIdleState();
302 // Verifies that locking an active system generates a "locked" event.
303 TEST_F(IdleTest
, ActiveToLocked
) {
304 ScopedListen
listen_test(idle_manager_
, "test");
306 idle_provider_
->set_locked(true);
307 idle_provider_
->set_idle_time(5);
309 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_LOCKED
));
310 idle_manager_
->UpdateIdleState();
313 // Verifies that transitioning from an idle to active state generates an
315 TEST_F(IdleTest
, IdleToActive
) {
316 ScopedListen
listen_test(idle_manager_
, "test");
318 idle_provider_
->set_locked(false);
319 idle_provider_
->set_idle_time(75);
320 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_IDLE
));
321 idle_manager_
->UpdateIdleState();
322 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
324 idle_provider_
->set_idle_time(0);
325 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_ACTIVE
));
326 idle_manager_
->UpdateIdleState();
329 // Verifies that locking an idle system generates a "locked" event.
330 TEST_F(IdleTest
, IdleToLocked
) {
331 ScopedListen
listen_test(idle_manager_
, "test");
333 idle_provider_
->set_locked(false);
334 idle_provider_
->set_idle_time(75);
336 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_IDLE
));
337 idle_manager_
->UpdateIdleState();
338 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
340 idle_provider_
->set_locked(true);
341 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_LOCKED
));
342 idle_manager_
->UpdateIdleState();
345 // Verifies that unlocking an active system generates an "active" event.
346 TEST_F(IdleTest
, LockedToActive
) {
347 ScopedListen
listen_test(idle_manager_
, "test");
349 idle_provider_
->set_locked(true);
350 idle_provider_
->set_idle_time(0);
352 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_LOCKED
));
353 idle_manager_
->UpdateIdleState();
355 idle_provider_
->set_locked(false);
356 idle_provider_
->set_idle_time(5);
357 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_ACTIVE
));
358 idle_manager_
->UpdateIdleState();
361 // Verifies that unlocking an inactive system generates an "idle" event.
362 TEST_F(IdleTest
, LockedToIdle
) {
363 ScopedListen
listen_test(idle_manager_
, "test");
365 idle_provider_
->set_locked(true);
366 idle_provider_
->set_idle_time(75);
367 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_LOCKED
));
368 idle_manager_
->UpdateIdleState();
369 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
371 idle_provider_
->set_locked(false);
372 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_IDLE
));
373 idle_manager_
->UpdateIdleState();
376 // Verifies that events are routed to extensions that have one or more listeners
378 TEST_F(IdleTest
, MultipleExtensions
) {
379 ScopedListen
listen_1(idle_manager_
, "1");
380 ScopedListen
listen_2(idle_manager_
, "2");
382 idle_provider_
->set_locked(true);
383 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", IDLE_STATE_LOCKED
));
384 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", IDLE_STATE_LOCKED
));
385 idle_manager_
->UpdateIdleState();
386 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
389 ScopedListen
listen_2prime(idle_manager_
, "2");
390 ScopedListen
listen_3(idle_manager_
, "3");
391 idle_provider_
->set_locked(false);
392 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", IDLE_STATE_ACTIVE
));
393 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", IDLE_STATE_ACTIVE
));
394 EXPECT_CALL(*event_delegate_
, OnStateChanged("3", IDLE_STATE_ACTIVE
));
395 idle_manager_
->UpdateIdleState();
396 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
399 idle_provider_
->set_locked(true);
400 EXPECT_CALL(*event_delegate_
, OnStateChanged("1", IDLE_STATE_LOCKED
));
401 EXPECT_CALL(*event_delegate_
, OnStateChanged("2", IDLE_STATE_LOCKED
));
402 idle_manager_
->UpdateIdleState();
405 // Verifies that setDetectionInterval changes the detection interval from the
406 // default of 60 seconds, and that the call only affects a single extension's
408 TEST_F(IdleTest
, SetDetectionInterval
) {
409 ScopedListen
listen_default(idle_manager_
, "default");
410 ScopedListen
listen_extension(idle_manager_
, extension()->id());
412 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
413 new IdleSetDetectionIntervalFunction(),
416 idle_provider_
->set_locked(false);
417 idle_provider_
->set_idle_time(44);
418 idle_manager_
->UpdateIdleState();
420 idle_provider_
->set_idle_time(45);
421 EXPECT_CALL(*event_delegate_
,
422 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
423 idle_manager_
->UpdateIdleState();
424 // Verify that the expectation has been fulfilled before incrementing the
426 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
428 idle_provider_
->set_idle_time(60);
429 EXPECT_CALL(*event_delegate_
, OnStateChanged("default", IDLE_STATE_IDLE
));
430 idle_manager_
->UpdateIdleState();
433 // Verifies that setting the detection interval before creating the listener
435 TEST_F(IdleTest
, SetDetectionIntervalBeforeListener
) {
436 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
437 new IdleSetDetectionIntervalFunction(),
440 ScopedListen
listen_extension(idle_manager_
, extension()->id());
442 idle_provider_
->set_locked(false);
443 idle_provider_
->set_idle_time(44);
444 idle_manager_
->UpdateIdleState();
446 idle_provider_
->set_idle_time(45);
447 EXPECT_CALL(*event_delegate_
,
448 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
449 idle_manager_
->UpdateIdleState();
452 // Verifies that setting a detection interval above the maximum value results
453 // in an interval of 4 hours.
454 TEST_F(IdleTest
, SetDetectionIntervalMaximum
) {
455 ScopedListen
listen_extension(idle_manager_
, extension()->id());
457 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
458 new IdleSetDetectionIntervalFunction(),
459 "[18000]")); // five hours in seconds
461 idle_provider_
->set_locked(false);
462 idle_provider_
->set_idle_time(4*60*60 - 1);
463 idle_manager_
->UpdateIdleState();
465 idle_provider_
->set_idle_time(4*60*60);
466 EXPECT_CALL(*event_delegate_
,
467 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
468 idle_manager_
->UpdateIdleState();
471 // Verifies that setting a detection interval below the minimum value results
472 // in an interval of 15 seconds.
473 TEST_F(IdleTest
, SetDetectionIntervalMinimum
) {
474 ScopedListen
listen_extension(idle_manager_
, extension()->id());
476 scoped_ptr
<base::Value
> result(RunFunctionAndReturnValue(
477 new IdleSetDetectionIntervalFunction(),
480 idle_provider_
->set_locked(false);
481 idle_provider_
->set_idle_time(14);
482 idle_manager_
->UpdateIdleState();
484 idle_provider_
->set_idle_time(15);
485 EXPECT_CALL(*event_delegate_
,
486 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
487 idle_manager_
->UpdateIdleState();
490 // Verifies that an extension's detection interval is discarded when it unloads.
491 TEST_F(IdleTest
, UnloadCleanup
) {
493 ScopedListen
listen(idle_manager_
, extension()->id());
495 scoped_ptr
<base::Value
> result45(RunFunctionAndReturnValue(
496 new IdleSetDetectionIntervalFunction(),
500 // Listener count dropping to zero does not reset threshold.
503 ScopedListen
listen(idle_manager_
, extension()->id());
504 idle_provider_
->set_idle_time(16);
505 EXPECT_CALL(*event_delegate_
,
506 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
507 idle_manager_
->UpdateIdleState();
508 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
511 // Threshold will reset after unload (and listen count == 0)
512 UnloadedExtensionInfo
details(extension(),
513 UnloadedExtensionInfo::REASON_UNINSTALL
);
514 idle_manager_
->Observe(
515 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED
,
516 content::Source
<Profile
>(browser()->profile()),
517 content::Details
<UnloadedExtensionInfo
>(&details
));
520 ScopedListen
listen(idle_manager_
, extension()->id());
521 idle_manager_
->UpdateIdleState();
522 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
524 idle_provider_
->set_idle_time(61);
525 EXPECT_CALL(*event_delegate_
,
526 OnStateChanged(extension()->id(), IDLE_STATE_IDLE
));
527 idle_manager_
->UpdateIdleState();
531 // Verifies that unloading an extension with no listeners or threshold works.
532 TEST_F(IdleTest
, UnloadOnly
) {
533 UnloadedExtensionInfo
details(extension(),
534 UnloadedExtensionInfo::REASON_UNINSTALL
);
535 idle_manager_
->Observe(
536 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED
,
537 content::Source
<Profile
>(browser()->profile()),
538 content::Details
<UnloadedExtensionInfo
>(&details
));
541 // Verifies that its ok for the unload notification to happen before all the
542 // listener removals.
543 TEST_F(IdleTest
, UnloadWhileListening
) {
544 ScopedListen
listen(idle_manager_
, extension()->id());
545 UnloadedExtensionInfo
details(extension(),
546 UnloadedExtensionInfo::REASON_UNINSTALL
);
547 idle_manager_
->Observe(
548 chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED
,
549 content::Source
<Profile
>(browser()->profile()),
550 content::Details
<UnloadedExtensionInfo
>(&details
));
553 // Verifies that re-adding a listener after a state change doesn't immediately
554 // fire a change event. Regression test for http://crbug.com/366580.
555 TEST_F(IdleTest
, ReAddListener
) {
556 idle_provider_
->set_locked(false);
560 ScopedListen
listen(idle_manager_
, "test");
561 idle_provider_
->set_idle_time(60);
562 EXPECT_CALL(*event_delegate_
, OnStateChanged("test", IDLE_STATE_IDLE
));
563 idle_manager_
->UpdateIdleState();
564 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
568 idle_provider_
->set_idle_time(0);
569 idle_manager_
->UpdateIdleState();
572 // Nothing should have fired, the listener wasn't added until afterward.
573 ScopedListen
listen(idle_manager_
, "test");
574 idle_manager_
->UpdateIdleState();
575 testing::Mock::VerifyAndClearExpectations(event_delegate_
);
579 } // namespace extensions