Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / power / power_api_unittest.cc
blobeb6c6a20e44368106337974fa18774d2f32976ff
1 // Copyright 2014 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/power/power_api.h"
7 #include <deque>
8 #include <string>
10 #include "base/basictypes.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "content/public/browser/power_save_blocker.h"
15 #include "extensions/browser/api_test_utils.h"
16 #include "extensions/browser/api_unittest.h"
17 #include "extensions/common/extension.h"
18 #include "extensions/common/test_util.h"
20 namespace extensions {
22 namespace {
24 // Args commonly passed to PowerSaveBlockerStubManager::CallFunction().
25 const char kDisplayArgs[] = "[\"display\"]";
26 const char kSystemArgs[] = "[\"system\"]";
27 const char kEmptyArgs[] = "[]";
29 // Different actions that can be performed as a result of a
30 // PowerSaveBlocker being created or destroyed.
31 enum Request {
32 BLOCK_APP_SUSPENSION,
33 UNBLOCK_APP_SUSPENSION,
34 BLOCK_DISPLAY_SLEEP,
35 UNBLOCK_DISPLAY_SLEEP,
36 // Returned by PowerSaveBlockerStubManager::PopFirstRequest() when no
37 // requests are present.
38 NONE,
41 // Stub implementation of content::PowerSaveBlocker that just runs a
42 // callback on destruction.
43 class PowerSaveBlockerStub : public content::PowerSaveBlocker {
44 public:
45 explicit PowerSaveBlockerStub(base::Closure unblock_callback)
46 : unblock_callback_(unblock_callback) {
49 ~PowerSaveBlockerStub() override { unblock_callback_.Run(); }
51 private:
52 base::Closure unblock_callback_;
54 DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStub);
57 // Manages PowerSaveBlockerStub objects. Tests can instantiate this class
58 // to make PowerAPI's calls to create PowerSaveBlockers record the
59 // actions that would've been performed instead of actually blocking and
60 // unblocking power management.
61 class PowerSaveBlockerStubManager {
62 public:
63 explicit PowerSaveBlockerStubManager(content::BrowserContext* context)
64 : browser_context_(context),
65 weak_ptr_factory_(this) {
66 // Use base::Unretained since callbacks with return values can't use
67 // weak pointers.
68 PowerAPI::Get(browser_context_)
69 ->SetCreateBlockerFunctionForTesting(base::Bind(
70 &PowerSaveBlockerStubManager::CreateStub, base::Unretained(this)));
73 ~PowerSaveBlockerStubManager() {
74 PowerAPI::Get(browser_context_)
75 ->SetCreateBlockerFunctionForTesting(PowerAPI::CreateBlockerFunction());
78 // Removes and returns the first item from |requests_|. Returns NONE if
79 // |requests_| is empty.
80 Request PopFirstRequest() {
81 if (requests_.empty())
82 return NONE;
84 Request request = requests_.front();
85 requests_.pop_front();
86 return request;
89 private:
90 // Creates a new PowerSaveBlockerStub of type |type|.
91 scoped_ptr<content::PowerSaveBlocker> CreateStub(
92 content::PowerSaveBlocker::PowerSaveBlockerType type,
93 content::PowerSaveBlocker::Reason reason,
94 const std::string& description) {
95 Request unblock_request = NONE;
96 switch (type) {
97 case content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension:
98 requests_.push_back(BLOCK_APP_SUSPENSION);
99 unblock_request = UNBLOCK_APP_SUSPENSION;
100 break;
101 case content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep:
102 requests_.push_back(BLOCK_DISPLAY_SLEEP);
103 unblock_request = UNBLOCK_DISPLAY_SLEEP;
104 break;
106 return scoped_ptr<content::PowerSaveBlocker>(
107 new PowerSaveBlockerStub(
108 base::Bind(&PowerSaveBlockerStubManager::AppendRequest,
109 weak_ptr_factory_.GetWeakPtr(),
110 unblock_request)));
113 void AppendRequest(Request request) {
114 requests_.push_back(request);
117 content::BrowserContext* browser_context_;
119 // Requests in chronological order.
120 std::deque<Request> requests_;
122 base::WeakPtrFactory<PowerSaveBlockerStubManager> weak_ptr_factory_;
124 DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStubManager);
127 } // namespace
129 class PowerAPITest : public ApiUnitTest {
130 public:
131 void SetUp() override {
132 ApiUnitTest::SetUp();
133 manager_.reset(new PowerSaveBlockerStubManager(browser_context()));
136 void TearDown() override {
137 manager_.reset();
138 ApiUnitTest::TearDown();
141 protected:
142 // Shorthand for PowerRequestKeepAwakeFunction and
143 // PowerReleaseKeepAwakeFunction.
144 enum FunctionType {
145 REQUEST,
146 RELEASE,
149 // Calls the function described by |type| with |args|, a JSON list of
150 // arguments, on behalf of |extension|.
151 bool CallFunction(FunctionType type,
152 const std::string& args,
153 const extensions::Extension* extension) {
154 scoped_refptr<UIThreadExtensionFunction> function(
155 type == REQUEST ?
156 static_cast<UIThreadExtensionFunction*>(
157 new PowerRequestKeepAwakeFunction) :
158 static_cast<UIThreadExtensionFunction*>(
159 new PowerReleaseKeepAwakeFunction));
160 function->set_extension(extension);
161 return api_test_utils::RunFunction(function.get(), args, browser_context());
164 // Send a notification to PowerAPI saying that |extension| has
165 // been unloaded.
166 void UnloadExtension(const extensions::Extension* extension) {
167 PowerAPI::Get(browser_context())
168 ->OnExtensionUnloaded(browser_context(), extension,
169 UnloadedExtensionInfo::REASON_UNINSTALL);
172 scoped_ptr<PowerSaveBlockerStubManager> manager_;
175 TEST_F(PowerAPITest, RequestAndRelease) {
176 // Simulate an extension making and releasing a "display" request and a
177 // "system" request.
178 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
179 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
180 EXPECT_EQ(NONE, manager_->PopFirstRequest());
181 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension()));
182 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
183 EXPECT_EQ(NONE, manager_->PopFirstRequest());
185 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension()));
186 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
187 EXPECT_EQ(NONE, manager_->PopFirstRequest());
188 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension()));
189 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
190 EXPECT_EQ(NONE, manager_->PopFirstRequest());
193 TEST_F(PowerAPITest, RequestWithoutRelease) {
194 // Simulate an extension calling requestKeepAwake() without calling
195 // releaseKeepAwake(). The override should be automatically removed when
196 // the extension is unloaded.
197 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
198 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
199 EXPECT_EQ(NONE, manager_->PopFirstRequest());
201 UnloadExtension(extension());
202 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
203 EXPECT_EQ(NONE, manager_->PopFirstRequest());
206 TEST_F(PowerAPITest, ReleaseWithoutRequest) {
207 // Simulate an extension calling releaseKeepAwake() without having
208 // calling requestKeepAwake() earlier. The call should be ignored.
209 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension()));
210 EXPECT_EQ(NONE, manager_->PopFirstRequest());
213 TEST_F(PowerAPITest, UpgradeRequest) {
214 // Simulate an extension calling requestKeepAwake("system") and then
215 // requestKeepAwake("display"). When the second call is made, a
216 // display-sleep-blocking request should be made before the initial
217 // app-suspension-blocking request is released.
218 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension()));
219 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
220 EXPECT_EQ(NONE, manager_->PopFirstRequest());
222 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
223 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
224 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
225 EXPECT_EQ(NONE, manager_->PopFirstRequest());
227 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension()));
228 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
229 EXPECT_EQ(NONE, manager_->PopFirstRequest());
232 TEST_F(PowerAPITest, DowngradeRequest) {
233 // Simulate an extension calling requestKeepAwake("display") and then
234 // requestKeepAwake("system"). When the second call is made, an
235 // app-suspension-blocking request should be made before the initial
236 // display-sleep-blocking request is released.
237 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
238 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
239 EXPECT_EQ(NONE, manager_->PopFirstRequest());
241 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension()));
242 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
243 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
244 EXPECT_EQ(NONE, manager_->PopFirstRequest());
246 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension()));
247 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
248 EXPECT_EQ(NONE, manager_->PopFirstRequest());
251 TEST_F(PowerAPITest, MultipleExtensions) {
252 // Simulate an extension blocking the display from sleeping.
253 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
254 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
255 EXPECT_EQ(NONE, manager_->PopFirstRequest());
257 // Create a second extension that blocks system suspend. No additional
258 // PowerSaveBlocker is needed; the blocker from the first extension
259 // already covers the behavior requested by the second extension.
260 scoped_refptr<Extension> extension2(test_util::CreateEmptyExtension("id2"));
261 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension2.get()));
262 EXPECT_EQ(NONE, manager_->PopFirstRequest());
264 // When the first extension is unloaded, a new app-suspension blocker
265 // should be created before the display-sleep blocker is destroyed.
266 UnloadExtension(extension());
267 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
268 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
269 EXPECT_EQ(NONE, manager_->PopFirstRequest());
271 // Make the first extension block display-sleep again.
272 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension()));
273 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
274 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
275 EXPECT_EQ(NONE, manager_->PopFirstRequest());
278 } // namespace extensions