Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: chrome/browser/extensions/api/power/power_api_unittest.cc

Issue 363993003: Move chrome.power API from chrome/ to extensions/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix quotes in gn file Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "chrome/browser/extensions/api/power/power_api.h"
6
7 #include <deque>
8 #include <string>
9
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 "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/extensions/api/power/power_api_manager.h"
16 #include "chrome/browser/extensions/extension_function_test_utils.h"
17 #include "chrome/test/base/browser_with_test_window_test.h"
18 #include "content/public/browser/notification_details.h"
19 #include "content/public/browser/notification_source.h"
20 #include "content/public/browser/power_save_blocker.h"
21 #include "extensions/common/extension.h"
22
23 namespace utils = extension_function_test_utils;
24
25 namespace extensions {
26
27 namespace {
28
29 // Args commonly passed to PowerSaveBlockerStubManager::CallFunction().
30 const char kDisplayArgs[] = "[\"display\"]";
31 const char kSystemArgs[] = "[\"system\"]";
32 const char kEmptyArgs[] = "[]";
33
34 // Different actions that can be performed as a result of a
35 // PowerSaveBlocker being created or destroyed.
36 enum Request {
37 BLOCK_APP_SUSPENSION,
38 UNBLOCK_APP_SUSPENSION,
39 BLOCK_DISPLAY_SLEEP,
40 UNBLOCK_DISPLAY_SLEEP,
41 // Returned by PowerSaveBlockerStubManager::PopFirstRequest() when no
42 // requests are present.
43 NONE,
44 };
45
46 // Stub implementation of content::PowerSaveBlocker that just runs a
47 // callback on destruction.
48 class PowerSaveBlockerStub : public content::PowerSaveBlocker {
49 public:
50 explicit PowerSaveBlockerStub(base::Closure unblock_callback)
51 : unblock_callback_(unblock_callback) {
52 }
53
54 virtual ~PowerSaveBlockerStub() {
55 unblock_callback_.Run();
56 }
57
58 private:
59 base::Closure unblock_callback_;
60
61 DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStub);
62 };
63
64 // Manages PowerSaveBlockerStub objects. Tests can instantiate this class
65 // to make PowerApiManager's calls to create PowerSaveBlockers record the
66 // actions that would've been performed instead of actually blocking and
67 // unblocking power management.
68 class PowerSaveBlockerStubManager {
69 public:
70 explicit PowerSaveBlockerStubManager(content::BrowserContext* context)
71 : browser_context_(context),
72 weak_ptr_factory_(this) {
73 // Use base::Unretained since callbacks with return values can't use
74 // weak pointers.
75 PowerApiManager::Get(browser_context_)->SetCreateBlockerFunctionForTesting(
76 base::Bind(&PowerSaveBlockerStubManager::CreateStub,
77 base::Unretained(this)));
78 }
79
80 ~PowerSaveBlockerStubManager() {
81 PowerApiManager::Get(browser_context_)->SetCreateBlockerFunctionForTesting(
82 PowerApiManager::CreateBlockerFunction());
83 }
84
85 // Removes and returns the first item from |requests_|. Returns NONE if
86 // |requests_| is empty.
87 Request PopFirstRequest() {
88 if (requests_.empty())
89 return NONE;
90
91 Request request = requests_.front();
92 requests_.pop_front();
93 return request;
94 }
95
96 private:
97 // Creates a new PowerSaveBlockerStub of type |type|.
98 scoped_ptr<content::PowerSaveBlocker> CreateStub(
99 content::PowerSaveBlocker::PowerSaveBlockerType type,
100 const std::string& reason) {
101 Request unblock_request = NONE;
102 switch (type) {
103 case content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension:
104 requests_.push_back(BLOCK_APP_SUSPENSION);
105 unblock_request = UNBLOCK_APP_SUSPENSION;
106 break;
107 case content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep:
108 requests_.push_back(BLOCK_DISPLAY_SLEEP);
109 unblock_request = UNBLOCK_DISPLAY_SLEEP;
110 break;
111 }
112 return scoped_ptr<content::PowerSaveBlocker>(
113 new PowerSaveBlockerStub(
114 base::Bind(&PowerSaveBlockerStubManager::AppendRequest,
115 weak_ptr_factory_.GetWeakPtr(),
116 unblock_request)));
117 }
118
119 void AppendRequest(Request request) {
120 requests_.push_back(request);
121 }
122
123 content::BrowserContext* browser_context_;
124
125 // Requests in chronological order.
126 std::deque<Request> requests_;
127
128 base::WeakPtrFactory<PowerSaveBlockerStubManager> weak_ptr_factory_;
129
130 DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStubManager);
131 };
132
133 } // namespace
134
135 class PowerApiTest : public BrowserWithTestWindowTest {
136 public:
137 virtual void SetUp() OVERRIDE {
138 BrowserWithTestWindowTest::SetUp();
139 manager_.reset(new PowerSaveBlockerStubManager(profile()));
140 extension_ = utils::CreateEmptyExtensionWithLocation(
141 extensions::Manifest::UNPACKED);
142 }
143
144 virtual void TearDown() OVERRIDE {
145 extension_ = NULL;
146 manager_.reset();
147 BrowserWithTestWindowTest::TearDown();
148 }
149
150 protected:
151 // Shorthand for PowerRequestKeepAwakeFunction and
152 // PowerReleaseKeepAwakeFunction.
153 enum FunctionType {
154 REQUEST,
155 RELEASE,
156 };
157
158 // Calls the function described by |type| with |args|, a JSON list of
159 // arguments, on behalf of |extension|.
160 bool CallFunction(FunctionType type,
161 const std::string& args,
162 extensions::Extension* extension) {
163 scoped_refptr<UIThreadExtensionFunction> function(
164 type == REQUEST ?
165 static_cast<UIThreadExtensionFunction*>(
166 new PowerRequestKeepAwakeFunction) :
167 static_cast<UIThreadExtensionFunction*>(
168 new PowerReleaseKeepAwakeFunction));
169 function->set_extension(extension);
170 return utils::RunFunction(function.get(), args, browser(), utils::NONE);
171 }
172
173 // Send a notification to PowerApiManager saying that |extension| has
174 // been unloaded.
175 void UnloadExtension(extensions::Extension* extension) {
176 PowerApiManager::Get(profile())->OnExtensionUnloaded(
177 profile(), extension, UnloadedExtensionInfo::REASON_UNINSTALL);
178 }
179
180 scoped_ptr<PowerSaveBlockerStubManager> manager_;
181 scoped_refptr<extensions::Extension> extension_;
182 };
183
184 TEST_F(PowerApiTest, RequestAndRelease) {
185 // Simulate an extension making and releasing a "display" request and a
186 // "system" request.
187 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
188 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
189 EXPECT_EQ(NONE, manager_->PopFirstRequest());
190 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get()));
191 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
192 EXPECT_EQ(NONE, manager_->PopFirstRequest());
193
194 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get()));
195 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
196 EXPECT_EQ(NONE, manager_->PopFirstRequest());
197 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get()));
198 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
199 EXPECT_EQ(NONE, manager_->PopFirstRequest());
200 }
201
202 TEST_F(PowerApiTest, RequestWithoutRelease) {
203 // Simulate an extension calling requestKeepAwake() without calling
204 // releaseKeepAwake(). The override should be automatically removed when
205 // the extension is unloaded.
206 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
207 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
208 EXPECT_EQ(NONE, manager_->PopFirstRequest());
209
210 UnloadExtension(extension_.get());
211 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
212 EXPECT_EQ(NONE, manager_->PopFirstRequest());
213 }
214
215 TEST_F(PowerApiTest, ReleaseWithoutRequest) {
216 // Simulate an extension calling releaseKeepAwake() without having
217 // calling requestKeepAwake() earlier. The call should be ignored.
218 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get()));
219 EXPECT_EQ(NONE, manager_->PopFirstRequest());
220 }
221
222 TEST_F(PowerApiTest, UpgradeRequest) {
223 // Simulate an extension calling requestKeepAwake("system") and then
224 // requestKeepAwake("display"). When the second call is made, a
225 // display-sleep-blocking request should be made before the initial
226 // app-suspension-blocking request is released.
227 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get()));
228 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
229 EXPECT_EQ(NONE, manager_->PopFirstRequest());
230
231 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
232 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
233 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
234 EXPECT_EQ(NONE, manager_->PopFirstRequest());
235
236 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get()));
237 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
238 EXPECT_EQ(NONE, manager_->PopFirstRequest());
239 }
240
241 TEST_F(PowerApiTest, DowngradeRequest) {
242 // Simulate an extension calling requestKeepAwake("display") and then
243 // requestKeepAwake("system"). When the second call is made, an
244 // app-suspension-blocking request should be made before the initial
245 // display-sleep-blocking request is released.
246 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
247 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
248 EXPECT_EQ(NONE, manager_->PopFirstRequest());
249
250 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get()));
251 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
252 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
253 EXPECT_EQ(NONE, manager_->PopFirstRequest());
254
255 ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get()));
256 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
257 EXPECT_EQ(NONE, manager_->PopFirstRequest());
258 }
259
260 TEST_F(PowerApiTest, MultipleExtensions) {
261 // Simulate an extension blocking the display from sleeping.
262 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
263 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
264 EXPECT_EQ(NONE, manager_->PopFirstRequest());
265
266 // Create a second extension that blocks system suspend. No additional
267 // PowerSaveBlocker is needed; the blocker from the first extension
268 // already covers the behavior requested by the second extension.
269 scoped_ptr<base::DictionaryValue> extension_value(
270 utils::ParseDictionary("{\"name\": \"Test\", \"version\": \"1.0\"}"));
271 scoped_refptr<extensions::Extension> extension2(
272 utils::CreateExtension(extensions::Manifest::UNPACKED,
273 extension_value.get(), "second_extension"));
274 ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension2.get()));
275 EXPECT_EQ(NONE, manager_->PopFirstRequest());
276
277 // When the first extension is unloaded, a new app-suspension blocker
278 // should be created before the display-sleep blocker is destroyed.
279 UnloadExtension(extension_.get());
280 EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
281 EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
282 EXPECT_EQ(NONE, manager_->PopFirstRequest());
283
284 // Make the first extension block display-sleep again.
285 ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get()));
286 EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest());
287 EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest());
288 EXPECT_EQ(NONE, manager_->PopFirstRequest());
289 }
290
291 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698