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. 4 5 #include "base/command_line.h" 6 #include "base/memory/scoped_ptr.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "chrome/browser/background/background_mode_manager.h" 9 #include "chrome/browser/lifetime/application_lifetime.h" 10 #include "chrome/browser/profiles/profile_info_cache.h" 11 #include "chrome/common/chrome_switches.h" 12 #include "chrome/test/base/testing_browser_process.h" 13 #include "chrome/test/base/testing_profile.h" 14 #include "chrome/test/base/testing_profile_manager.h" 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "ui/gfx/image/image.h" 17 #include "ui/gfx/image/image_unittest_util.h" 18 19 class BackgroundModeManagerTest : public testing::Test { 20 public: 21 BackgroundModeManagerTest() 22 : profile_manager_(TestingBrowserProcess::GetGlobal()) {} 23 virtual ~BackgroundModeManagerTest() {} 24 virtual void SetUp() { 25 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM)); 26 ASSERT_TRUE(profile_manager_.SetUp()); 27 } 28 scoped_ptr<CommandLine> command_line_; 29 TestingProfileManager profile_manager_; 30 }; 31 32 class TestBackgroundModeManager : public BackgroundModeManager { 33 public: 34 TestBackgroundModeManager( 35 CommandLine* command_line, ProfileInfoCache* cache, bool enabled) 36 : BackgroundModeManager(command_line, cache), 37 enabled_(enabled), 38 app_count_(0), 39 profile_app_count_(0), 40 have_status_tray_(false), 41 launch_on_startup_(false) {} 42 virtual void EnableLaunchOnStartup(bool launch) OVERRIDE { 43 launch_on_startup_ = launch; 44 } 45 virtual void CreateStatusTrayIcon() OVERRIDE { have_status_tray_ = true; } 46 virtual void RemoveStatusTrayIcon() OVERRIDE { have_status_tray_ = false; } 47 virtual int GetBackgroundAppCount() const OVERRIDE { return app_count_; } 48 virtual int GetBackgroundAppCountForProfile( 49 Profile* const profile) const OVERRIDE { 50 return profile_app_count_; 51 } 52 virtual bool IsBackgroundModePrefEnabled() const OVERRIDE { return enabled_; } 53 void SetBackgroundAppCount(int count) { app_count_ = count; } 54 void SetBackgroundAppCountForProfile(int count) { 55 profile_app_count_ = count; 56 } 57 void SetEnabled(bool enabled) { 58 enabled_ = enabled; 59 OnBackgroundModeEnabledPrefChanged(); 60 } 61 bool HaveStatusTray() const { return have_status_tray_; } 62 bool IsLaunchOnStartup() const { return launch_on_startup_; } 63 private: 64 bool enabled_; 65 int app_count_; 66 int profile_app_count_; 67 68 // Flags to track whether we are launching on startup/have a status tray. 69 bool have_status_tray_; 70 bool launch_on_startup_; 71 }; 72 73 static void AssertBackgroundModeActive( 74 const TestBackgroundModeManager& manager) { 75 EXPECT_TRUE(chrome::WillKeepAlive()); 76 EXPECT_TRUE(manager.HaveStatusTray()); 77 EXPECT_TRUE(manager.IsLaunchOnStartup()); 78 } 79 80 static void AssertBackgroundModeInactive( 81 const TestBackgroundModeManager& manager) { 82 EXPECT_FALSE(chrome::WillKeepAlive()); 83 EXPECT_FALSE(manager.HaveStatusTray()); 84 EXPECT_FALSE(manager.IsLaunchOnStartup()); 85 } 86 87 TEST_F(BackgroundModeManagerTest, BackgroundAppLoadUnload) { 88 TestingProfile* profile = profile_manager_.CreateTestingProfile("p1"); 89 TestBackgroundModeManager manager( 90 command_line_.get(), profile_manager_.profile_info_cache(), true); 91 manager.RegisterProfile(profile); 92 EXPECT_FALSE(chrome::WillKeepAlive()); 93 94 // Mimic app load. 95 manager.OnBackgroundAppInstalled(NULL); 96 manager.SetBackgroundAppCount(1); 97 manager.OnApplicationListChanged(profile); 98 AssertBackgroundModeActive(manager); 99 100 // Mimic app unload. 101 manager.SetBackgroundAppCount(0); 102 manager.OnApplicationListChanged(profile); 103 AssertBackgroundModeInactive(manager); 104 } 105 106 // App installs while background mode is disabled should do nothing. 107 TEST_F(BackgroundModeManagerTest, BackgroundAppInstallUninstallWhileDisabled) { 108 TestingProfile* profile = profile_manager_.CreateTestingProfile("p1"); 109 TestBackgroundModeManager manager( 110 command_line_.get(), profile_manager_.profile_info_cache(), true); 111 manager.RegisterProfile(profile); 112 // Turn off background mode. 113 manager.SetEnabled(false); 114 manager.DisableBackgroundMode(); 115 AssertBackgroundModeInactive(manager); 116 117 // Status tray icons will not be created, launch on startup status will not 118 // be modified. 119 manager.OnBackgroundAppInstalled(NULL); 120 manager.SetBackgroundAppCount(1); 121 manager.OnApplicationListChanged(profile); 122 AssertBackgroundModeInactive(manager); 123 124 manager.SetBackgroundAppCount(0); 125 manager.OnApplicationListChanged(profile); 126 AssertBackgroundModeInactive(manager); 127 128 // Re-enable background mode. 129 manager.SetEnabled(true); 130 manager.EnableBackgroundMode(); 131 AssertBackgroundModeInactive(manager); 132 } 133 134 135 // App installs while disabled should do nothing until background mode is 136 // enabled.. 137 TEST_F(BackgroundModeManagerTest, EnableAfterBackgroundAppInstall) { 138 TestingProfile* profile = profile_manager_.CreateTestingProfile("p1"); 139 TestBackgroundModeManager manager( 140 command_line_.get(), profile_manager_.profile_info_cache(), true); 141 manager.RegisterProfile(profile); 142 143 // Install app, should show status tray icon. 144 manager.OnBackgroundAppInstalled(NULL); 145 // OnBackgroundAppInstalled does not actually add an app to the 146 // BackgroundApplicationListModel which would result in another 147 // call to CreateStatusTray. 148 manager.SetBackgroundAppCount(1); 149 manager.OnApplicationListChanged(profile); 150 AssertBackgroundModeActive(manager); 151 152 // Turn off background mode - should hide status tray icon. 153 manager.SetEnabled(false); 154 manager.DisableBackgroundMode(); 155 AssertBackgroundModeInactive(manager); 156 157 // Turn back on background mode - again, no status tray icon 158 // will show up since we didn't actually add anything to the list. 159 manager.SetEnabled(true); 160 manager.EnableBackgroundMode(); 161 AssertBackgroundModeActive(manager); 162 163 // Uninstall app, should hide status tray icon again. 164 manager.SetBackgroundAppCount(0); 165 manager.OnApplicationListChanged(profile); 166 AssertBackgroundModeInactive(manager); 167 } 168 169 TEST_F(BackgroundModeManagerTest, MultiProfile) { 170 TestingProfile* profile1 = profile_manager_.CreateTestingProfile("p1"); 171 TestingProfile* profile2 = profile_manager_.CreateTestingProfile("p2"); 172 TestBackgroundModeManager manager( 173 command_line_.get(), profile_manager_.profile_info_cache(), true); 174 manager.RegisterProfile(profile1); 175 manager.RegisterProfile(profile2); 176 EXPECT_FALSE(chrome::WillKeepAlive()); 177 178 // Install app, should show status tray icon. 179 manager.OnBackgroundAppInstalled(NULL); 180 manager.SetBackgroundAppCount(1); 181 manager.OnApplicationListChanged(profile1); 182 AssertBackgroundModeActive(manager); 183 184 // Install app for other profile, hsould show other status tray icon. 185 manager.OnBackgroundAppInstalled(NULL); 186 manager.SetBackgroundAppCount(2); 187 manager.OnApplicationListChanged(profile2); 188 AssertBackgroundModeActive(manager); 189 190 // Should hide both status tray icons. 191 manager.SetEnabled(false); 192 manager.DisableBackgroundMode(); 193 AssertBackgroundModeInactive(manager); 194 195 // Turn back on background mode - should show both status tray icons. 196 manager.SetEnabled(true); 197 manager.EnableBackgroundMode(); 198 AssertBackgroundModeActive(manager); 199 200 manager.SetBackgroundAppCount(1); 201 manager.OnApplicationListChanged(profile2); 202 // There is still one background app alive 203 AssertBackgroundModeActive(manager); 204 205 manager.SetBackgroundAppCount(0); 206 manager.OnApplicationListChanged(profile1); 207 AssertBackgroundModeInactive(manager); 208 } 209 210 TEST_F(BackgroundModeManagerTest, ProfileInfoCacheStorage) { 211 TestingProfile* profile1 = profile_manager_.CreateTestingProfile("p1"); 212 TestingProfile* profile2 = profile_manager_.CreateTestingProfile("p2"); 213 TestBackgroundModeManager manager( 214 command_line_.get(), profile_manager_.profile_info_cache(), true); 215 manager.RegisterProfile(profile1); 216 manager.RegisterProfile(profile2); 217 EXPECT_FALSE(chrome::WillKeepAlive()); 218 219 ProfileInfoCache* cache = profile_manager_.profile_info_cache(); 220 EXPECT_EQ(2u, cache->GetNumberOfProfiles()); 221 222 EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(0)); 223 EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(1)); 224 225 // Install app, should show status tray icon. 226 manager.OnBackgroundAppInstalled(NULL); 227 manager.SetBackgroundAppCount(1); 228 manager.SetBackgroundAppCountForProfile(1); 229 manager.OnApplicationListChanged(profile1); 230 231 // Install app for other profile. 232 manager.OnBackgroundAppInstalled(NULL); 233 manager.SetBackgroundAppCount(1); 234 manager.SetBackgroundAppCountForProfile(1); 235 manager.OnApplicationListChanged(profile2); 236 237 EXPECT_TRUE(cache->GetBackgroundStatusOfProfileAtIndex(0)); 238 EXPECT_TRUE(cache->GetBackgroundStatusOfProfileAtIndex(1)); 239 240 manager.SetBackgroundAppCountForProfile(0); 241 manager.OnApplicationListChanged(profile1); 242 243 size_t p1_index = cache->GetIndexOfProfileWithPath(profile1->GetPath()); 244 EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(p1_index)); 245 246 manager.SetBackgroundAppCountForProfile(0); 247 manager.OnApplicationListChanged(profile2); 248 249 size_t p2_index = cache->GetIndexOfProfileWithPath(profile1->GetPath()); 250 EXPECT_FALSE(cache->GetBackgroundStatusOfProfileAtIndex(p2_index)); 251 252 // Even though neither has background status on, there should still be two 253 // profiles in the cache. 254 EXPECT_EQ(2u, cache->GetNumberOfProfiles()); 255 } 256 257 TEST_F(BackgroundModeManagerTest, ProfileInfoCacheObserver) { 258 TestingProfile* profile1 = profile_manager_.CreateTestingProfile("p1"); 259 TestBackgroundModeManager manager( 260 command_line_.get(), profile_manager_.profile_info_cache(), true); 261 manager.RegisterProfile(profile1); 262 EXPECT_FALSE(chrome::WillKeepAlive()); 263 264 // Install app, should show status tray icon. 265 manager.OnBackgroundAppInstalled(NULL); 266 manager.SetBackgroundAppCount(1); 267 manager.SetBackgroundAppCountForProfile(1); 268 manager.OnApplicationListChanged(profile1); 269 270 manager.OnProfileNameChanged( 271 profile1->GetPath(), 272 manager.GetBackgroundModeData(profile1)->name()); 273 274 EXPECT_EQ(UTF8ToUTF16("p1"), 275 manager.GetBackgroundModeData(profile1)->name()); 276 277 TestingProfile* profile2 = profile_manager_.CreateTestingProfile("p2"); 278 manager.RegisterProfile(profile2); 279 EXPECT_EQ(2, manager.NumberOfBackgroundModeData()); 280 281 manager.OnProfileAdded(profile2->GetPath()); 282 EXPECT_EQ(UTF8ToUTF16("p2"), 283 manager.GetBackgroundModeData(profile2)->name()); 284 285 manager.OnProfileWillBeRemoved(profile2->GetPath()); 286 EXPECT_EQ(1, manager.NumberOfBackgroundModeData()); 287 288 // Check that the background mode data we think is in the map actually is. 289 EXPECT_EQ(UTF8ToUTF16("p1"), 290 manager.GetBackgroundModeData(profile1)->name()); 291 } 292 293 TEST_F(BackgroundModeManagerTest, DisableBackgroundModeUnderTestFlag) { 294 TestingProfile* profile1 = profile_manager_.CreateTestingProfile("p1"); 295 command_line_->AppendSwitch(switches::kKeepAliveForTest); 296 TestBackgroundModeManager manager( 297 command_line_.get(), profile_manager_.profile_info_cache(), true); 298 manager.RegisterProfile(profile1); 299 EXPECT_TRUE(manager.ShouldBeInBackgroundMode()); 300 manager.SetEnabled(false); 301 EXPECT_FALSE(manager.ShouldBeInBackgroundMode()); 302 } 303 304 TEST_F(BackgroundModeManagerTest, 305 BackgroundModeDisabledPreventsKeepAliveOnStartup) { 306 TestingProfile* profile1 = profile_manager_.CreateTestingProfile("p1"); 307 command_line_->AppendSwitch(switches::kKeepAliveForTest); 308 TestBackgroundModeManager manager( 309 command_line_.get(), profile_manager_.profile_info_cache(), false); 310 manager.RegisterProfile(profile1); 311 EXPECT_FALSE(manager.ShouldBeInBackgroundMode()); 312 } 313