1 // Copyright (c) 2011 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.
6 #include "base/command_line.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/background/background_mode_manager.h"
11 #include "chrome/browser/browser_shutdown.h"
12 #include "chrome/browser/extensions/extension_function_test_utils.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/test_extension_system.h"
15 #include "chrome/browser/lifetime/application_lifetime.h"
16 #include "chrome/browser/profiles/profile_info_cache.h"
17 #include "chrome/browser/status_icons/status_icon_menu_model.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "extensions/browser/api_test_utils.h"
24 #include "extensions/browser/extension_prefs.h"
25 #include "extensions/browser/extension_system.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/gfx/image/image.h"
29 #include "ui/gfx/image/image_unittest_util.h"
30 #include "ui/message_center/message_center.h"
32 #if defined(OS_CHROMEOS)
33 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
34 #include "chrome/browser/chromeos/settings/cros_settings.h"
35 #include "chrome/browser/chromeos/settings/device_settings_service.h"
39 using testing::AtMost
;
40 using testing::Exactly
;
41 using testing::InSequence
;
43 using testing::StrictMock
;
47 // Helper class that tracks state transitions in BackgroundModeManager and
48 // exposes them via getters (or gmock for EnableLaunchOnStartup).
49 class TestBackgroundModeManager
: public StrictMock
<BackgroundModeManager
> {
51 TestBackgroundModeManager(const base::CommandLine
& command_line
,
52 ProfileInfoCache
* cache
)
53 : StrictMock
<BackgroundModeManager
>(command_line
, cache
),
54 have_status_tray_(false),
55 has_shown_balloon_(false) {
56 ResumeBackgroundMode();
59 MOCK_METHOD1(EnableLaunchOnStartup
, void(bool should_launch
));
61 // TODO: Use strict-mocking rather than keeping state through overrides below.
62 void DisplayAppInstalledNotification(
63 const extensions::Extension
* extension
) override
{
64 has_shown_balloon_
= true;
66 void CreateStatusTrayIcon() override
{ have_status_tray_
= true; }
67 void RemoveStatusTrayIcon() override
{ have_status_tray_
= false; }
69 bool HaveStatusTray() const { return have_status_tray_
; }
70 bool HasShownBalloon() const { return has_shown_balloon_
; }
71 void SetHasShownBalloon(bool value
) { has_shown_balloon_
= value
; }
74 // Flags to track whether we have a status tray/have shown the balloon.
75 bool have_status_tray_
;
76 bool has_shown_balloon_
;
78 DISALLOW_COPY_AND_ASSIGN(TestBackgroundModeManager
);
81 class TestStatusIcon
: public StatusIcon
{
84 void SetImage(const gfx::ImageSkia
& image
) override
{}
85 void SetToolTip(const base::string16
& tool_tip
) override
{}
86 void DisplayBalloon(const gfx::ImageSkia
& icon
,
87 const base::string16
& title
,
88 const base::string16
& contents
) override
{}
89 void UpdatePlatformContextMenu(StatusIconMenuModel
* menu
) override
{}
92 DISALLOW_COPY_AND_ASSIGN(TestStatusIcon
);
95 void AssertBackgroundModeActive(const TestBackgroundModeManager
& manager
) {
96 EXPECT_TRUE(chrome::WillKeepAlive());
97 EXPECT_TRUE(manager
.HaveStatusTray());
100 void AssertBackgroundModeInactive(const TestBackgroundModeManager
& manager
) {
101 EXPECT_FALSE(chrome::WillKeepAlive());
102 EXPECT_FALSE(manager
.HaveStatusTray());
107 // More complex test helper that exposes APIs for fine grained control of
108 // things like the number of background applications. This allows writing
109 // smaller tests that don't have to install/uninstall extensions.
110 class AdvancedTestBackgroundModeManager
: public TestBackgroundModeManager
{
112 AdvancedTestBackgroundModeManager(const base::CommandLine
& command_line
,
113 ProfileInfoCache
* cache
,
115 : TestBackgroundModeManager(command_line
, cache
), enabled_(enabled
) {}
117 int GetBackgroundAppCount() const override
{
119 for (const auto& profile_count_pair
: profile_app_counts_
)
120 app_count
+= profile_count_pair
.second
;
123 int GetBackgroundAppCountForProfile(Profile
* const profile
) const override
{
124 auto it
= profile_app_counts_
.find(profile
);
125 if (it
== profile_app_counts_
.end()) {
131 void SetBackgroundAppCountForProfile(Profile
* profile
, int count
) {
132 profile_app_counts_
[profile
] = count
;
134 void SetEnabled(bool enabled
) {
136 OnBackgroundModeEnabledPrefChanged();
138 bool IsBackgroundModePrefEnabled() const override
{ return enabled_
; }
142 std::map
<Profile
*, int> profile_app_counts_
;
144 DISALLOW_COPY_AND_ASSIGN(AdvancedTestBackgroundModeManager
);
147 class BackgroundModeManagerTest
: public testing::Test
{
149 BackgroundModeManagerTest() {}
150 ~BackgroundModeManagerTest() override
{}
152 void SetUp() override
{
153 command_line_
.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM
));
154 profile_manager_
= CreateTestingProfileManager();
155 profile_
= profile_manager_
->CreateTestingProfile("p1");
159 scoped_refptr
<extensions::Extension
> CreateExtension(
160 extensions::Manifest::Location location
,
161 const std::string
& data
,
162 const std::string
& id
) {
163 scoped_ptr
<base::DictionaryValue
> parsed_manifest(
164 extensions::api_test_utils::ParseDictionary(data
));
165 return extensions::api_test_utils::CreateExtension(
166 location
, parsed_manifest
.get(), id
);
169 // From views::MenuModelAdapter::IsCommandEnabled with modification.
170 bool IsCommandEnabled(ui::MenuModel
* model
, int id
) const {
172 if (ui::MenuModel::GetModelAndIndexForCommandId(id
, &model
, &index
))
173 return model
->IsEnabledAt(index
);
178 scoped_ptr
<base::CommandLine
> command_line_
;
180 scoped_ptr
<TestingProfileManager
> profile_manager_
;
181 // Test profile used by all tests - this is owned by profile_manager_.
182 TestingProfile
* profile_
;
185 scoped_ptr
<TestingProfileManager
> CreateTestingProfileManager() {
186 scoped_ptr
<TestingProfileManager
> profile_manager
187 (new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
188 EXPECT_TRUE(profile_manager
->SetUp());
189 return profile_manager
.Pass();
192 DISALLOW_COPY_AND_ASSIGN(BackgroundModeManagerTest
);
195 class BackgroundModeManagerWithExtensionsTest
196 : public BackgroundModeManagerTest
{
198 BackgroundModeManagerWithExtensionsTest() {}
199 ~BackgroundModeManagerWithExtensionsTest() override
{}
201 void SetUp() override
{
202 BackgroundModeManagerTest::SetUp();
204 // Aura clears notifications from the message center at shutdown.
205 message_center::MessageCenter::Initialize();
207 // BackgroundModeManager actually affects Chrome start/stop state,
208 // tearing down our thread bundle before we've had chance to clean
209 // everything up. Keeping Chrome alive prevents this.
210 // We aren't interested in if the keep alive works correctly in this test.
211 chrome::IncrementKeepAliveCount();
213 #if defined(OS_CHROMEOS)
214 // On ChromeOS shutdown, HandleAppExitingForPlatform will call
215 // chrome::DecrementKeepAliveCount because it assumes the aura shell
216 // called chrome::IncrementKeepAliveCount. Simulate the call here.
217 chrome::IncrementKeepAliveCount();
220 // Create our test BackgroundModeManager.
221 manager_
.reset(new TestBackgroundModeManager(
222 *command_line_
, profile_manager_
->profile_info_cache()));
223 manager_
->RegisterProfile(profile_
);
226 void TearDown() override
{
227 // Clean up the status icon. If this is not done before profile deletes,
228 // the context menu updates will DCHECK with the now deleted profiles.
229 StatusIcon
* status_icon
= manager_
->status_icon_
;
230 manager_
->status_icon_
= NULL
;
233 // We have to destroy the profiles now because we created them with real
234 // thread state. This causes a lot of machinery to spin up that stops
235 // working when we tear down our thread state at the end of the test.
236 // Deleting our testing profile may have the side-effect of disabling
237 // background mode if it was enabled for that profile (explicitly note that
238 // here to satisfy StrictMock requirements.
239 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(false)).Times(AtMost(1));
240 profile_manager_
->DeleteAllTestingProfiles();
241 Mock::VerifyAndClearExpectations(manager_
.get());
243 // We're getting ready to shutdown the message loop. Clear everything out!
244 base::MessageLoop::current()->RunUntilIdle();
245 // Matching the call to IncrementKeepAliveCount in SetUp().
246 chrome::DecrementKeepAliveCount();
248 // TestBackgroundModeManager has dependencies on the infrastructure.
249 // It should get cleared first.
252 // The Profile Manager references the Browser Process.
253 // The Browser Process references the Notification UI Manager.
254 // The Notification UI Manager references the Message Center.
255 // As a result, we have to clear the browser process state here
256 // before tearing down the Message Center.
257 profile_manager_
.reset();
259 // Message Center shutdown must occur after the DecrementKeepAliveCount
260 // because DecrementKeepAliveCount will end up referencing the message
261 // center during cleanup.
262 message_center::MessageCenter::Shutdown();
264 // Clear the shutdown flag to isolate the remaining effect of this test.
265 browser_shutdown::SetTryingToQuit(false);
269 void AddEphemeralApp(const extensions::Extension
* extension
,
270 ExtensionService
* service
) {
271 extensions::ExtensionPrefs
* prefs
=
272 extensions::ExtensionPrefs::Get(service
->profile());
274 prefs
->OnExtensionInstalled(extension
,
275 extensions::Extension::ENABLED
,
276 syncer::StringOrdinal(),
277 extensions::kInstallFlagIsEphemeral
,
280 service
->AddExtension(extension
);
283 scoped_ptr
<TestBackgroundModeManager
> manager_
;
286 // Required for extension service.
287 content::TestBrowserThreadBundle thread_bundle_
;
289 #if defined(OS_CHROMEOS)
290 // ChromeOS needs extra services to run in the following order.
291 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_
;
292 chromeos::ScopedTestCrosSettings test_cros_settings_
;
293 chromeos::ScopedTestUserManager test_user_manager_
;
296 DISALLOW_COPY_AND_ASSIGN(BackgroundModeManagerWithExtensionsTest
);
300 TEST_F(BackgroundModeManagerTest
, BackgroundAppLoadUnload
) {
301 AdvancedTestBackgroundModeManager
manager(
302 *command_line_
, profile_manager_
->profile_info_cache(), true);
303 manager
.RegisterProfile(profile_
);
304 EXPECT_FALSE(chrome::WillKeepAlive());
307 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
308 manager
.OnBackgroundAppInstalled(NULL
);
309 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
310 manager
.OnApplicationListChanged(profile_
);
311 Mock::VerifyAndClearExpectations(&manager
);
312 AssertBackgroundModeActive(manager
);
314 manager
.SuspendBackgroundMode();
315 AssertBackgroundModeInactive(manager
);
316 manager
.ResumeBackgroundMode();
319 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
320 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
321 manager
.OnApplicationListChanged(profile_
);
322 Mock::VerifyAndClearExpectations(&manager
);
323 AssertBackgroundModeInactive(manager
);
325 manager
.SuspendBackgroundMode();
326 AssertBackgroundModeInactive(manager
);
328 // Mimic app load while suspended, e.g. from sync. This should enable and
329 // resume background mode.
330 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
331 manager
.OnBackgroundAppInstalled(NULL
);
332 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
333 manager
.OnApplicationListChanged(profile_
);
334 Mock::VerifyAndClearExpectations(&manager
);
335 AssertBackgroundModeActive(manager
);
338 // App installs while background mode is disabled should do nothing.
339 TEST_F(BackgroundModeManagerTest
, BackgroundAppInstallUninstallWhileDisabled
) {
340 AdvancedTestBackgroundModeManager
manager(
341 *command_line_
, profile_manager_
->profile_info_cache(), true);
342 manager
.RegisterProfile(profile_
);
344 // Turn off background mode (shouldn't explicitly disable launch-on-startup as
345 // the app-count is zero and launch-on-startup shouldn't be considered on).
346 manager
.SetEnabled(false);
347 manager
.DisableBackgroundMode();
348 AssertBackgroundModeInactive(manager
);
350 // Status tray icons will not be created, launch on startup status will not
352 manager
.OnBackgroundAppInstalled(NULL
);
353 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
354 manager
.OnApplicationListChanged(profile_
);
355 AssertBackgroundModeInactive(manager
);
357 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
358 manager
.OnApplicationListChanged(profile_
);
359 AssertBackgroundModeInactive(manager
);
361 // Re-enable background mode (shouldn't actually enable launch-on-startup as
362 // the app-count is zero).
363 manager
.SetEnabled(true);
364 manager
.EnableBackgroundMode();
365 AssertBackgroundModeInactive(manager
);
369 // App installs while disabled should do nothing until background mode is
371 TEST_F(BackgroundModeManagerTest
, EnableAfterBackgroundAppInstall
) {
372 AdvancedTestBackgroundModeManager
manager(
373 *command_line_
, profile_manager_
->profile_info_cache(), true);
374 manager
.RegisterProfile(profile_
);
376 // Install app, should show status tray icon.
377 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
378 manager
.OnBackgroundAppInstalled(NULL
);
379 // OnBackgroundAppInstalled does not actually add an app to the
380 // BackgroundApplicationListModel which would result in another
381 // call to CreateStatusTray.
382 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
383 manager
.OnApplicationListChanged(profile_
);
384 AssertBackgroundModeActive(manager
);
385 Mock::VerifyAndClearExpectations(&manager
);
387 // Turn off background mode - should hide status tray icon.
388 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
389 manager
.SetEnabled(false);
390 manager
.DisableBackgroundMode();
391 Mock::VerifyAndClearExpectations(&manager
);
392 AssertBackgroundModeInactive(manager
);
394 // Turn back on background mode - again, no status tray icon
395 // will show up since we didn't actually add anything to the list.
396 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
397 manager
.SetEnabled(true);
398 manager
.EnableBackgroundMode();
399 Mock::VerifyAndClearExpectations(&manager
);
400 AssertBackgroundModeActive(manager
);
402 // Uninstall app, should hide status tray icon again.
403 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
404 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
405 manager
.OnApplicationListChanged(profile_
);
406 Mock::VerifyAndClearExpectations(&manager
);
407 AssertBackgroundModeInactive(manager
);
410 TEST_F(BackgroundModeManagerTest
, MultiProfile
) {
411 TestingProfile
* profile2
= profile_manager_
->CreateTestingProfile("p2");
412 AdvancedTestBackgroundModeManager
manager(
413 *command_line_
, profile_manager_
->profile_info_cache(), true);
414 manager
.RegisterProfile(profile_
);
415 manager
.RegisterProfile(profile2
);
416 EXPECT_FALSE(chrome::WillKeepAlive());
418 // Install app, should show status tray icon.
419 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
420 manager
.OnBackgroundAppInstalled(NULL
);
421 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
422 manager
.OnApplicationListChanged(profile_
);
423 Mock::VerifyAndClearExpectations(&manager
);
424 AssertBackgroundModeActive(manager
);
426 // Install app for other profile, should show other status tray icon.
427 manager
.OnBackgroundAppInstalled(NULL
);
428 manager
.SetBackgroundAppCountForProfile(profile2
, 2);
429 manager
.OnApplicationListChanged(profile2
);
430 AssertBackgroundModeActive(manager
);
432 // Should hide both status tray icons.
433 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
434 manager
.SetEnabled(false);
435 manager
.DisableBackgroundMode();
436 Mock::VerifyAndClearExpectations(&manager
);
437 AssertBackgroundModeInactive(manager
);
439 // Turn back on background mode - should show both status tray icons.
440 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
441 manager
.SetEnabled(true);
442 manager
.EnableBackgroundMode();
443 Mock::VerifyAndClearExpectations(&manager
);
444 AssertBackgroundModeActive(manager
);
446 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
447 manager
.OnApplicationListChanged(profile_
);
448 manager
.SetBackgroundAppCountForProfile(profile2
, 1);
449 manager
.OnApplicationListChanged(profile2
);
450 // There is still one background app alive
451 AssertBackgroundModeActive(manager
);
452 // Verify the implicit expectations of no calls on this StrictMock.
453 Mock::VerifyAndClearExpectations(&manager
);
455 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
456 manager
.SetBackgroundAppCountForProfile(profile2
, 0);
457 manager
.OnApplicationListChanged(profile_
);
458 Mock::VerifyAndClearExpectations(&manager
);
459 AssertBackgroundModeInactive(manager
);
462 TEST_F(BackgroundModeManagerTest
, ProfileInfoCacheStorage
) {
463 TestingProfile
* profile2
= profile_manager_
->CreateTestingProfile("p2");
464 AdvancedTestBackgroundModeManager
manager(
465 *command_line_
, profile_manager_
->profile_info_cache(), true);
466 manager
.RegisterProfile(profile_
);
467 manager
.RegisterProfile(profile2
);
468 EXPECT_FALSE(chrome::WillKeepAlive());
470 ProfileInfoCache
* cache
= profile_manager_
->profile_info_cache();
471 EXPECT_EQ(2u, cache
->GetNumberOfProfiles());
473 EXPECT_FALSE(cache
->GetBackgroundStatusOfProfileAtIndex(0));
474 EXPECT_FALSE(cache
->GetBackgroundStatusOfProfileAtIndex(1));
476 // Install app, should show status tray icon.
477 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
478 manager
.OnBackgroundAppInstalled(NULL
);
479 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
480 manager
.OnApplicationListChanged(profile_
);
481 Mock::VerifyAndClearExpectations(&manager
);
483 // Install app for other profile.
484 manager
.OnBackgroundAppInstalled(NULL
);
485 manager
.SetBackgroundAppCountForProfile(profile2
, 1);
486 manager
.OnApplicationListChanged(profile2
);
488 EXPECT_TRUE(cache
->GetBackgroundStatusOfProfileAtIndex(0));
489 EXPECT_TRUE(cache
->GetBackgroundStatusOfProfileAtIndex(1));
491 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
492 manager
.OnApplicationListChanged(profile_
);
494 size_t p1_index
= cache
->GetIndexOfProfileWithPath(profile_
->GetPath());
495 EXPECT_FALSE(cache
->GetBackgroundStatusOfProfileAtIndex(p1_index
));
497 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
498 manager
.SetBackgroundAppCountForProfile(profile2
, 0);
499 manager
.OnApplicationListChanged(profile2
);
500 Mock::VerifyAndClearExpectations(&manager
);
502 size_t p2_index
= cache
->GetIndexOfProfileWithPath(profile_
->GetPath());
503 EXPECT_FALSE(cache
->GetBackgroundStatusOfProfileAtIndex(p2_index
));
505 // Even though neither has background status on, there should still be two
506 // profiles in the cache.
507 EXPECT_EQ(2u, cache
->GetNumberOfProfiles());
510 TEST_F(BackgroundModeManagerTest
, ProfileInfoCacheObserver
) {
511 AdvancedTestBackgroundModeManager
manager(
512 *command_line_
, profile_manager_
->profile_info_cache(), true);
513 manager
.RegisterProfile(profile_
);
514 EXPECT_FALSE(chrome::WillKeepAlive());
516 // Install app, should show status tray icon.
517 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
518 manager
.OnBackgroundAppInstalled(NULL
);
519 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
520 manager
.OnApplicationListChanged(profile_
);
521 Mock::VerifyAndClearExpectations(&manager
);
523 // Background mode should remain active for the remainder of this test.
525 manager
.OnProfileNameChanged(
527 manager
.GetBackgroundModeData(profile_
)->name());
529 EXPECT_EQ(base::UTF8ToUTF16("p1"),
530 manager
.GetBackgroundModeData(profile_
)->name());
532 EXPECT_TRUE(chrome::WillKeepAlive());
533 TestingProfile
* profile2
= profile_manager_
->CreateTestingProfile("p2");
534 manager
.RegisterProfile(profile2
);
535 EXPECT_EQ(2, manager
.NumberOfBackgroundModeData());
537 manager
.OnProfileAdded(profile2
->GetPath());
538 EXPECT_EQ(base::UTF8ToUTF16("p2"),
539 manager
.GetBackgroundModeData(profile2
)->name());
541 manager
.OnProfileWillBeRemoved(profile2
->GetPath());
542 // Should still be in background mode after deleting profile.
543 EXPECT_TRUE(chrome::WillKeepAlive());
544 EXPECT_EQ(1, manager
.NumberOfBackgroundModeData());
546 // Check that the background mode data we think is in the map actually is.
547 EXPECT_EQ(base::UTF8ToUTF16("p1"),
548 manager
.GetBackgroundModeData(profile_
)->name());
551 TEST_F(BackgroundModeManagerTest
, DeleteBackgroundProfile
) {
552 // Tests whether deleting the only profile when it is a BG profile works
553 // or not (http://crbug.com/346214).
554 AdvancedTestBackgroundModeManager
manager(
555 *command_line_
, profile_manager_
->profile_info_cache(), true);
556 manager
.RegisterProfile(profile_
);
557 EXPECT_FALSE(chrome::WillKeepAlive());
559 // Install app, should show status tray icon.
560 EXPECT_CALL(manager
, EnableLaunchOnStartup(true)).Times(Exactly(1));
561 manager
.OnBackgroundAppInstalled(NULL
);
562 manager
.SetBackgroundAppCountForProfile(profile_
, 1);
563 manager
.OnApplicationListChanged(profile_
);
564 Mock::VerifyAndClearExpectations(&manager
);
566 manager
.OnProfileNameChanged(
568 manager
.GetBackgroundModeData(profile_
)->name());
570 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
571 EXPECT_TRUE(chrome::WillKeepAlive());
572 manager
.SetBackgroundAppCountForProfile(profile_
, 0);
573 manager
.OnProfileWillBeRemoved(profile_
->GetPath());
574 Mock::VerifyAndClearExpectations(&manager
);
575 EXPECT_FALSE(chrome::WillKeepAlive());
578 TEST_F(BackgroundModeManagerTest
, DisableBackgroundModeUnderTestFlag
) {
579 command_line_
->AppendSwitch(switches::kKeepAliveForTest
);
580 AdvancedTestBackgroundModeManager
manager(
581 *command_line_
, profile_manager_
->profile_info_cache(), true);
582 manager
.RegisterProfile(profile_
);
583 EXPECT_TRUE(manager
.ShouldBeInBackgroundMode());
585 // No enable-launch-on-startup calls expected yet.
586 Mock::VerifyAndClearExpectations(&manager
);
587 EXPECT_CALL(manager
, EnableLaunchOnStartup(false)).Times(Exactly(1));
588 manager
.SetEnabled(false);
589 EXPECT_FALSE(manager
.ShouldBeInBackgroundMode());
592 TEST_F(BackgroundModeManagerTest
,
593 BackgroundModeDisabledPreventsKeepAliveOnStartup
) {
594 command_line_
->AppendSwitch(switches::kKeepAliveForTest
);
595 AdvancedTestBackgroundModeManager
manager(
596 *command_line_
, profile_manager_
->profile_info_cache(), false);
597 manager
.RegisterProfile(profile_
);
598 EXPECT_FALSE(manager
.ShouldBeInBackgroundMode());
601 TEST_F(BackgroundModeManagerWithExtensionsTest
, BackgroundMenuGeneration
) {
602 scoped_refptr
<extensions::Extension
> component_extension(
604 extensions::Manifest::COMPONENT
,
605 "{\"name\": \"Component Extension\","
606 "\"version\": \"1.0\","
607 "\"manifest_version\": 2,"
608 "\"permissions\": [\"background\"]}",
611 scoped_refptr
<extensions::Extension
> component_extension_with_options(
613 extensions::Manifest::COMPONENT
,
614 "{\"name\": \"Component Extension with Options\","
615 "\"version\": \"1.0\","
616 "\"manifest_version\": 2,"
617 "\"permissions\": [\"background\"],"
618 "\"options_page\": \"test.html\"}",
621 scoped_refptr
<extensions::Extension
> regular_extension(
623 extensions::Manifest::COMMAND_LINE
,
624 "{\"name\": \"Regular Extension\", "
625 "\"version\": \"1.0\","
626 "\"manifest_version\": 2,"
627 "\"permissions\": [\"background\"]}",
630 scoped_refptr
<extensions::Extension
> regular_extension_with_options(
632 extensions::Manifest::COMMAND_LINE
,
633 "{\"name\": \"Regular Extension with Options\","
634 "\"version\": \"1.0\","
635 "\"manifest_version\": 2,"
636 "\"permissions\": [\"background\"],"
637 "\"options_page\": \"test.html\"}",
640 static_cast<extensions::TestExtensionSystem
*>(
641 extensions::ExtensionSystem::Get(profile_
))
642 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
643 base::FilePath(), false);
644 ExtensionService
* service
=
645 extensions::ExtensionSystem::Get(profile_
)->extension_service();
648 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(true)).Times(Exactly(1));
649 service
->AddComponentExtension(component_extension
.get());
650 service
->AddComponentExtension(component_extension_with_options
.get());
651 service
->AddExtension(regular_extension
.get());
652 service
->AddExtension(regular_extension_with_options
.get());
653 Mock::VerifyAndClearExpectations(manager_
.get());
655 scoped_ptr
<StatusIconMenuModel
> menu(new StatusIconMenuModel(NULL
));
656 scoped_ptr
<StatusIconMenuModel
> submenu(new StatusIconMenuModel(NULL
));
657 BackgroundModeManager::BackgroundModeData
* bmd
=
658 manager_
->GetBackgroundModeData(profile_
);
659 bmd
->BuildProfileMenu(submenu
.get(), menu
.get());
661 submenu
->GetLabelAt(0) ==
662 base::UTF8ToUTF16("Component Extension"));
663 EXPECT_FALSE(submenu
->IsCommandIdEnabled(submenu
->GetCommandIdAt(0)));
665 submenu
->GetLabelAt(1) ==
666 base::UTF8ToUTF16("Component Extension with Options"));
667 EXPECT_TRUE(submenu
->IsCommandIdEnabled(submenu
->GetCommandIdAt(1)));
669 submenu
->GetLabelAt(2) ==
670 base::UTF8ToUTF16("Regular Extension"));
671 EXPECT_TRUE(submenu
->IsCommandIdEnabled(submenu
->GetCommandIdAt(2)));
673 submenu
->GetLabelAt(3) ==
674 base::UTF8ToUTF16("Regular Extension with Options"));
675 EXPECT_TRUE(submenu
->IsCommandIdEnabled(submenu
->GetCommandIdAt(3)));
678 TEST_F(BackgroundModeManagerWithExtensionsTest
,
679 BackgroundMenuGenerationMultipleProfile
) {
680 TestingProfile
* profile2
= profile_manager_
->CreateTestingProfile("p2");
681 scoped_refptr
<extensions::Extension
> component_extension(
683 extensions::Manifest::COMPONENT
,
684 "{\"name\": \"Component Extension\","
685 "\"version\": \"1.0\","
686 "\"manifest_version\": 2,"
687 "\"permissions\": [\"background\"]}",
690 scoped_refptr
<extensions::Extension
> component_extension_with_options(
692 extensions::Manifest::COMPONENT
,
693 "{\"name\": \"Component Extension with Options\","
694 "\"version\": \"1.0\","
695 "\"manifest_version\": 2,"
696 "\"permissions\": [\"background\"],"
697 "\"options_page\": \"test.html\"}",
700 scoped_refptr
<extensions::Extension
> regular_extension(
702 extensions::Manifest::COMMAND_LINE
,
703 "{\"name\": \"Regular Extension\", "
704 "\"version\": \"1.0\","
705 "\"manifest_version\": 2,"
706 "\"permissions\": [\"background\"]}",
709 scoped_refptr
<extensions::Extension
> regular_extension_with_options(
711 extensions::Manifest::COMMAND_LINE
,
712 "{\"name\": \"Regular Extension with Options\","
713 "\"version\": \"1.0\","
714 "\"manifest_version\": 2,"
715 "\"permissions\": [\"background\"],"
716 "\"options_page\": \"test.html\"}",
719 static_cast<extensions::TestExtensionSystem
*>(
720 extensions::ExtensionSystem::Get(profile_
))
721 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
722 base::FilePath(), false);
723 ExtensionService
* service1
=
724 extensions::ExtensionSystem::Get(profile_
)->extension_service();
727 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(true)).Times(Exactly(1));
728 service1
->AddComponentExtension(component_extension
.get());
729 service1
->AddComponentExtension(component_extension_with_options
.get());
730 service1
->AddExtension(regular_extension
.get());
731 service1
->AddExtension(regular_extension_with_options
.get());
732 Mock::VerifyAndClearExpectations(manager_
.get());
734 static_cast<extensions::TestExtensionSystem
*>(
735 extensions::ExtensionSystem::Get(profile2
))
736 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
737 base::FilePath(), false);
738 ExtensionService
* service2
=
739 extensions::ExtensionSystem::Get(profile2
)->extension_service();
742 service2
->AddComponentExtension(component_extension
.get());
743 service2
->AddExtension(regular_extension
.get());
744 service2
->AddExtension(regular_extension_with_options
.get());
746 manager_
->RegisterProfile(profile2
);
748 manager_
->status_icon_
= new TestStatusIcon();
749 manager_
->UpdateStatusTrayIconContextMenu();
750 StatusIconMenuModel
* context_menu
= manager_
->context_menu_
;
751 EXPECT_TRUE(context_menu
!= NULL
);
753 // Background Profile Enable Checks
754 EXPECT_TRUE(context_menu
->GetLabelAt(3) == base::UTF8ToUTF16("p1"));
756 context_menu
->IsCommandIdEnabled(context_menu
->GetCommandIdAt(3)));
757 EXPECT_TRUE(context_menu
->GetCommandIdAt(3) == 4);
759 EXPECT_TRUE(context_menu
->GetLabelAt(4) == base::UTF8ToUTF16("p2"));
761 context_menu
->IsCommandIdEnabled(context_menu
->GetCommandIdAt(4)));
762 EXPECT_TRUE(context_menu
->GetCommandIdAt(4) == 8);
764 // Profile 1 Submenu Checks
765 StatusIconMenuModel
* profile1_submenu
=
766 static_cast<StatusIconMenuModel
*>(context_menu
->GetSubmenuModelAt(3));
768 profile1_submenu
->GetLabelAt(0) ==
769 base::UTF8ToUTF16("Component Extension"));
771 profile1_submenu
->IsCommandIdEnabled(
772 profile1_submenu
->GetCommandIdAt(0)));
773 EXPECT_TRUE(profile1_submenu
->GetCommandIdAt(0) == 0);
775 profile1_submenu
->GetLabelAt(1) ==
776 base::UTF8ToUTF16("Component Extension with Options"));
778 profile1_submenu
->IsCommandIdEnabled(
779 profile1_submenu
->GetCommandIdAt(1)));
780 EXPECT_TRUE(profile1_submenu
->GetCommandIdAt(1) == 1);
782 profile1_submenu
->GetLabelAt(2) ==
783 base::UTF8ToUTF16("Regular Extension"));
785 profile1_submenu
->IsCommandIdEnabled(
786 profile1_submenu
->GetCommandIdAt(2)));
787 EXPECT_TRUE(profile1_submenu
->GetCommandIdAt(2) == 2);
789 profile1_submenu
->GetLabelAt(3) ==
790 base::UTF8ToUTF16("Regular Extension with Options"));
792 profile1_submenu
->IsCommandIdEnabled(
793 profile1_submenu
->GetCommandIdAt(3)));
794 EXPECT_TRUE(profile1_submenu
->GetCommandIdAt(3) == 3);
796 // Profile 2 Submenu Checks
797 StatusIconMenuModel
* profile2_submenu
=
798 static_cast<StatusIconMenuModel
*>(context_menu
->GetSubmenuModelAt(4));
800 profile2_submenu
->GetLabelAt(0) ==
801 base::UTF8ToUTF16("Component Extension"));
803 profile2_submenu
->IsCommandIdEnabled(
804 profile2_submenu
->GetCommandIdAt(0)));
805 EXPECT_TRUE(profile2_submenu
->GetCommandIdAt(0) == 5);
807 profile2_submenu
->GetLabelAt(1) ==
808 base::UTF8ToUTF16("Regular Extension"));
810 profile2_submenu
->IsCommandIdEnabled(
811 profile2_submenu
->GetCommandIdAt(1)));
812 EXPECT_TRUE(profile2_submenu
->GetCommandIdAt(1) == 6);
814 profile2_submenu
->GetLabelAt(2) ==
815 base::UTF8ToUTF16("Regular Extension with Options"));
817 profile2_submenu
->IsCommandIdEnabled(
818 profile2_submenu
->GetCommandIdAt(2)));
819 EXPECT_TRUE(profile2_submenu
->GetCommandIdAt(2) == 7);
821 // Model Adapter Checks for crbug.com/315164
822 // P1: Profile 1 Menu Item
823 // P2: Profile 2 Menu Item
824 // CE: Component Extension Menu Item
825 // CEO: Component Extenison with Options Menu Item
826 // RE: Regular Extension Menu Item
827 // REO: Regular Extension with Options Menu Item
828 EXPECT_FALSE(IsCommandEnabled(context_menu
, 0)); // P1 - CE
829 EXPECT_TRUE(IsCommandEnabled(context_menu
, 1)); // P1 - CEO
830 EXPECT_TRUE(IsCommandEnabled(context_menu
, 2)); // P1 - RE
831 EXPECT_TRUE(IsCommandEnabled(context_menu
, 3)); // P1 - REO
832 EXPECT_TRUE(IsCommandEnabled(context_menu
, 4)); // P1
833 EXPECT_FALSE(IsCommandEnabled(context_menu
, 5)); // P2 - CE
834 EXPECT_TRUE(IsCommandEnabled(context_menu
, 6)); // P2 - RE
835 EXPECT_TRUE(IsCommandEnabled(context_menu
, 7)); // P2 - REO
836 EXPECT_TRUE(IsCommandEnabled(context_menu
, 8)); // P2
839 TEST_F(BackgroundModeManagerWithExtensionsTest
, BalloonDisplay
) {
840 scoped_refptr
<extensions::Extension
> bg_ext(
842 extensions::Manifest::COMMAND_LINE
,
843 "{\"name\": \"Background Extension\", "
844 "\"version\": \"1.0\","
845 "\"manifest_version\": 2,"
846 "\"permissions\": [\"background\"]}",
849 scoped_refptr
<extensions::Extension
> upgraded_bg_ext(
851 extensions::Manifest::COMMAND_LINE
,
852 "{\"name\": \"Background Extension\", "
853 "\"version\": \"2.0\","
854 "\"manifest_version\": 2,"
855 "\"permissions\": [\"background\"]}",
858 scoped_refptr
<extensions::Extension
> no_bg_ext(
860 extensions::Manifest::COMMAND_LINE
,
861 "{\"name\": \"Regular Extension\", "
862 "\"version\": \"1.0\","
863 "\"manifest_version\": 2,"
864 "\"permissions\": []}",
867 scoped_refptr
<extensions::Extension
> upgraded_no_bg_ext_has_bg(
869 extensions::Manifest::COMMAND_LINE
,
870 "{\"name\": \"Regular Extension\", "
871 "\"version\": \"2.0\","
872 "\"manifest_version\": 2,"
873 "\"permissions\": [\"background\"]}",
876 static_cast<extensions::TestExtensionSystem
*>(
877 extensions::ExtensionSystem::Get(profile_
))
878 ->CreateExtensionService(base::CommandLine::ForCurrentProcess(),
879 base::FilePath(), false);
881 ExtensionService
* service
=
882 extensions::ExtensionSystem::Get(profile_
)->extension_service();
883 ASSERT_FALSE(service
->is_ready());
886 ASSERT_TRUE(service
->is_ready());
887 manager_
->status_icon_
= new TestStatusIcon();
888 manager_
->UpdateStatusTrayIconContextMenu();
890 // Adding a background extension should show the balloon.
891 EXPECT_FALSE(manager_
->HasShownBalloon());
892 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(true)).Times(Exactly(1));
893 service
->AddExtension(bg_ext
.get());
894 Mock::VerifyAndClearExpectations(manager_
.get());
895 EXPECT_TRUE(manager_
->HasShownBalloon());
897 // Adding an extension without background should not show the balloon.
898 manager_
->SetHasShownBalloon(false);
899 service
->AddExtension(no_bg_ext
.get());
900 EXPECT_FALSE(manager_
->HasShownBalloon());
902 // Upgrading an extension that has background should not reshow the balloon.
904 // TODO: Fix crbug.com/438376 and remove these checks.
905 InSequence expected_call_sequence
;
906 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(false)).Times(Exactly(1));
907 EXPECT_CALL(*manager_
, EnableLaunchOnStartup(true)).Times(Exactly(1));
909 service
->AddExtension(upgraded_bg_ext
.get());
910 Mock::VerifyAndClearExpectations(manager_
.get());
911 EXPECT_FALSE(manager_
->HasShownBalloon());
913 // Upgrading an extension that didn't have background to one that does should
915 service
->AddExtension(upgraded_no_bg_ext_has_bg
.get());
916 EXPECT_TRUE(manager_
->HasShownBalloon());