Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / power / extension_event_observer_unittest.cc
blob455fb6a3624e27ec358b42b9347147ac0fd8149e
1 // Copyright 2015 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/chromeos/power/extension_event_observer.h"
7 #include <string>
9 #include "base/macros.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
14 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
16 #include "chrome/browser/chromeos/settings/device_settings_service.h"
17 #include "chrome/common/extensions/api/gcm.h"
18 #include "chrome/test/base/testing_browser_process.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "chrome/test/base/testing_profile_manager.h"
21 #include "chromeos/dbus/dbus_thread_manager.h"
22 #include "chromeos/dbus/fake_power_manager_client.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "content/public/test/test_renderer_host.h"
25 #include "extensions/browser/extension_host.h"
26 #include "extensions/browser/extension_host_observer.h"
27 #include "extensions/browser/process_manager.h"
28 #include "extensions/common/extension.h"
29 #include "extensions/common/extension_builder.h"
30 #include "extensions/common/manifest_handlers/background_info.h"
31 #include "extensions/common/value_builder.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "ui/aura/test/test_screen.h"
34 #include "ui/gfx/screen.h"
36 namespace chromeos {
38 class ExtensionEventObserverTest : public ::testing::Test {
39 public:
40 ExtensionEventObserverTest()
41 : power_manager_client_(new FakePowerManagerClient()),
42 test_screen_(aura::TestScreen::Create(gfx::Size())),
43 fake_user_manager_(new FakeChromeUserManager()),
44 scoped_user_manager_enabler_(fake_user_manager_) {
45 DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
46 make_scoped_ptr(power_manager_client_));
48 profile_manager_.reset(
49 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
51 extension_event_observer_.reset(new ExtensionEventObserver());
52 test_api_ = extension_event_observer_->CreateTestApi();
55 ~ExtensionEventObserverTest() override {
56 extension_event_observer_.reset();
57 profile_manager_.reset();
58 DBusThreadManager::Shutdown();
61 // ::testing::Test overrides.
62 void SetUp() override {
63 ::testing::Test::SetUp();
65 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen_.get());
67 // Must be called from ::testing::Test::SetUp.
68 ASSERT_TRUE(profile_manager_->SetUp());
70 const char kUserProfile[] = "profile1@example.com";
71 fake_user_manager_->AddUser(kUserProfile);
72 fake_user_manager_->LoginUser(kUserProfile);
73 profile_ = profile_manager_->CreateTestingProfile(kUserProfile);
75 profile_manager_->SetLoggedIn(true);
77 void TearDown() override {
78 profile_ = NULL;
79 profile_manager_->DeleteAllTestingProfiles();
80 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, nullptr);
81 ::testing::Test::TearDown();
84 protected:
85 scoped_refptr<extensions::Extension> CreateApp(const std::string& name,
86 bool uses_gcm) {
87 scoped_refptr<extensions::Extension> app =
88 extensions::ExtensionBuilder()
89 .SetManifest(
90 extensions::DictionaryBuilder()
91 .Set("name", name)
92 .Set("version", "1.0.0")
93 .Set("manifest_version", 2)
94 .Set("app",
95 extensions::DictionaryBuilder().Set(
96 "background",
97 extensions::DictionaryBuilder().Set(
98 "scripts", extensions::ListBuilder().Append(
99 "background.js"))))
100 .Set("permissions", extensions::ListBuilder().Append(
101 uses_gcm ? "gcm" : "")))
102 .Build();
104 created_apps_.push_back(app);
106 return app;
109 extensions::ExtensionHost* CreateHostForApp(Profile* profile,
110 extensions::Extension* app) {
111 extensions::ProcessManager::Get(profile)->CreateBackgroundHost(
112 app, extensions::BackgroundInfo::GetBackgroundURL(app));
113 base::RunLoop().RunUntilIdle();
115 return extensions::ProcessManager::Get(profile)
116 ->GetBackgroundHostForExtension(app->id());
119 // Owned by DBusThreadManager.
120 FakePowerManagerClient* power_manager_client_;
122 scoped_ptr<ExtensionEventObserver> extension_event_observer_;
123 scoped_ptr<ExtensionEventObserver::TestApi> test_api_;
125 // Owned by |profile_manager_|.
126 TestingProfile* profile_;
127 scoped_ptr<TestingProfileManager> profile_manager_;
129 private:
130 scoped_ptr<aura::TestScreen> test_screen_;
131 content::TestBrowserThreadBundle browser_thread_bundle_;
133 // Needed to ensure we don't end up creating actual RenderViewHosts
134 // and RenderProcessHosts.
135 content::RenderViewHostTestEnabler render_view_host_test_enabler_;
137 // Chrome OS needs extra services to run in the following order.
138 ScopedTestDeviceSettingsService test_device_settings_service_;
139 ScopedTestCrosSettings test_cros_settings_;
141 // Owned by |scoped_user_manager_enabler_|.
142 FakeChromeUserManager* fake_user_manager_;
143 ScopedUserManagerEnabler scoped_user_manager_enabler_;
145 std::vector<scoped_refptr<extensions::Extension>> created_apps_;
147 DISALLOW_COPY_AND_ASSIGN(ExtensionEventObserverTest);
150 // Tests that the ExtensionEventObserver reports readiness for suspend when
151 // there is nothing interesting going on.
152 TEST_F(ExtensionEventObserverTest, BasicSuspendAndDarkSuspend) {
153 power_manager_client_->SendSuspendImminent();
154 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
156 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
157 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
159 power_manager_client_->SendDarkSuspendImminent();
160 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
162 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
163 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
166 // Tests that the ExtensionEventObserver properly handles a canceled suspend
167 // attempt.
168 TEST_F(ExtensionEventObserverTest, CanceledSuspend) {
169 power_manager_client_->SendSuspendImminent();
170 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
172 power_manager_client_->SendSuspendDone();
173 EXPECT_FALSE(test_api_->MaybeRunSuspendReadinessCallback());
176 // Tests that the ExtensionEventObserver delays suspends and dark suspends while
177 // there is a push message pending for an app that uses GCM.
178 TEST_F(ExtensionEventObserverTest, PushMessagesDelaySuspend) {
179 scoped_refptr<extensions::Extension> gcm_app =
180 CreateApp("DelaysSuspendForPushMessages", true /* uses_gcm */);
181 extensions::ExtensionHost* host = CreateHostForApp(profile_, gcm_app.get());
182 ASSERT_TRUE(host);
183 EXPECT_TRUE(test_api_->WillDelaySuspendForExtensionHost(host));
185 // Test that a push message received before a suspend attempt delays the
186 // attempt.
187 const int kSuspendPushId = 23874;
188 extension_event_observer_->OnBackgroundEventDispatched(
189 host, extensions::api::gcm::OnMessage::kEventName, kSuspendPushId);
190 power_manager_client_->SendSuspendImminent();
192 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
193 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
195 extension_event_observer_->OnBackgroundEventAcked(host, kSuspendPushId);
196 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
198 // Now test receiving the suspend attempt before the push message.
199 const int kDarkSuspendPushId = 56674;
200 power_manager_client_->SendDarkSuspendImminent();
201 extension_event_observer_->OnBackgroundEventDispatched(
202 host, extensions::api::gcm::OnMessage::kEventName, kDarkSuspendPushId);
204 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
205 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
207 extension_event_observer_->OnBackgroundEventAcked(host, kDarkSuspendPushId);
208 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
210 // Test that non-push messages do not delay the suspend.
211 const int kNonPushId = 5687;
212 power_manager_client_->SendDarkSuspendImminent();
213 extension_event_observer_->OnBackgroundEventDispatched(host, "FakeMessage",
214 kNonPushId);
216 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
217 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
220 // Tests that messages sent for apps that don't use GCM are ignored.
221 TEST_F(ExtensionEventObserverTest, IgnoresNonGCMApps) {
222 scoped_refptr<extensions::Extension> app = CreateApp("Non-GCM", false);
223 extensions::ExtensionHost* host = CreateHostForApp(profile_, app.get());
224 ASSERT_TRUE(host);
226 EXPECT_FALSE(test_api_->WillDelaySuspendForExtensionHost(host));
228 power_manager_client_->SendSuspendImminent();
229 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
230 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
233 // Tests that network requests started by an app while it is processing a push
234 // message delay any suspend attempt.
235 TEST_F(ExtensionEventObserverTest, NetworkRequestsMayDelaySuspend) {
236 scoped_refptr<extensions::Extension> app = CreateApp("NetworkRequests", true);
237 extensions::ExtensionHost* host = CreateHostForApp(profile_, app.get());
238 ASSERT_TRUE(host);
239 EXPECT_TRUE(test_api_->WillDelaySuspendForExtensionHost(host));
241 // Test that network requests started while there is no pending push message
242 // are ignored.
243 const uint64 kNonPushRequestId = 5170725;
244 extension_event_observer_->OnNetworkRequestStarted(host, kNonPushRequestId);
245 power_manager_client_->SendSuspendImminent();
247 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
248 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
250 // Test that network requests started while a push message is pending delay
251 // the suspend even after the push message has been acked.
252 const int kPushMessageId = 178674;
253 const uint64 kNetworkRequestId = 78917089;
254 power_manager_client_->SendDarkSuspendImminent();
255 extension_event_observer_->OnBackgroundEventDispatched(
256 host, extensions::api::gcm::OnMessage::kEventName, kPushMessageId);
258 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
259 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
261 extension_event_observer_->OnNetworkRequestStarted(host, kNetworkRequestId);
262 extension_event_observer_->OnBackgroundEventAcked(host, kPushMessageId);
263 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
265 extension_event_observer_->OnNetworkRequestDone(host, kNetworkRequestId);
266 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
269 // Tests that any outstanding push messages or network requests for an
270 // ExtensionHost that is destroyed do not end up blocking system suspend.
271 TEST_F(ExtensionEventObserverTest, DeletedExtensionHostDoesNotBlockSuspend) {
272 scoped_refptr<extensions::Extension> app =
273 CreateApp("DeletedExtensionHost", true);
275 // The easiest way to delete an extension host is to delete the Profile it is
276 // associated with so we create a new Profile here.
277 const char kProfileName[] = "DeletedExtensionHostProfile";
278 Profile* new_profile = profile_manager_->CreateTestingProfile(kProfileName);
280 extensions::ExtensionHost* host = CreateHostForApp(new_profile, app.get());
281 ASSERT_TRUE(host);
282 EXPECT_TRUE(test_api_->WillDelaySuspendForExtensionHost(host));
284 const int kPushId = 156178;
285 const uint64 kNetworkId = 791605;
286 extension_event_observer_->OnBackgroundEventDispatched(
287 host, extensions::api::gcm::OnMessage::kEventName, kPushId);
288 extension_event_observer_->OnNetworkRequestStarted(host, kNetworkId);
290 // Now delete the Profile. This has the side-effect of also deleting all the
291 // ExtensionHosts.
292 profile_manager_->DeleteTestingProfile(kProfileName);
294 power_manager_client_->SendSuspendImminent();
295 EXPECT_TRUE(test_api_->MaybeRunSuspendReadinessCallback());
296 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
299 // Tests that the ExtensionEventObserver does not delay suspend attempts when it
300 // is disabled.
301 TEST_F(ExtensionEventObserverTest, DoesNotDelaySuspendWhenDisabled) {
302 scoped_refptr<extensions::Extension> app =
303 CreateApp("NoDelayWhenDisabled", true);
304 extensions::ExtensionHost* host = CreateHostForApp(profile_, app.get());
305 ASSERT_TRUE(host);
306 EXPECT_TRUE(test_api_->WillDelaySuspendForExtensionHost(host));
308 // Test that disabling the suspend delay while a suspend is pending will cause
309 // the ExtensionEventObserver to immediately report readiness.
310 const int kPushId = 416753;
311 extension_event_observer_->OnBackgroundEventDispatched(
312 host, extensions::api::gcm::OnMessage::kEventName, kPushId);
313 power_manager_client_->SendSuspendImminent();
314 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
316 extension_event_observer_->SetShouldDelaySuspend(false);
317 EXPECT_FALSE(test_api_->MaybeRunSuspendReadinessCallback());
318 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
320 // Test that the ExtensionEventObserver does not delay suspend attempts when
321 // it is disabled.
322 power_manager_client_->SendDarkSuspendImminent();
323 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
326 } // namespace chromeos