12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/power/power_api.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <deque> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/power/power_api_manager.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/browser_with_test_window_test.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/notification_details.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/notification_source.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/power_save_blocker.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace utils = extension_function_test_utils; 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Args commonly passed to PowerSaveBlockerStubManager::CallFunction(). 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDisplayArgs[] = "[\"display\"]"; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSystemArgs[] = "[\"system\"]"; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kEmptyArgs[] = "[]"; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Different actions that can be performed as a result of a 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// PowerSaveBlocker being created or destroyed. 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum Request { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BLOCK_APP_SUSPENSION, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UNBLOCK_APP_SUSPENSION, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BLOCK_DISPLAY_SLEEP, 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UNBLOCK_DISPLAY_SLEEP, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returned by PowerSaveBlockerStubManager::PopFirstRequest() when no 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // requests are present. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NONE, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stub implementation of content::PowerSaveBlocker that just runs a 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// callback on destruction. 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PowerSaveBlockerStub : public content::PowerSaveBlocker { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit PowerSaveBlockerStub(base::Closure unblock_callback) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : unblock_callback_(unblock_callback) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~PowerSaveBlockerStub() { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unblock_callback_.Run(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure unblock_callback_; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStub); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Manages PowerSaveBlockerStub objects. Tests can instantiate this class 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// to make PowerApiManager's calls to create PowerSaveBlockers record the 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// actions that would've been performed instead of actually blocking and 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// unblocking power management. 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PowerSaveBlockerStubManager { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerSaveBlockerStubManager() : weak_ptr_factory_(this) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use base::Unretained since callbacks with return values can't use 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // weak pointers. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerApiManager::GetInstance()->SetCreateBlockerFunctionForTesting( 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerSaveBlockerStubManager::CreateStub, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~PowerSaveBlockerStubManager() { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerApiManager::GetInstance()->SetCreateBlockerFunctionForTesting( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerApiManager::CreateBlockerFunction()); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Removes and returns the first item from |requests_|. Returns NONE if 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |requests_| is empty. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Request PopFirstRequest() { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (requests_.empty()) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NONE; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Request request = requests_.front(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_.pop_front(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return request; 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a new PowerSaveBlockerStub of type |type|. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<content::PowerSaveBlocker> CreateStub( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PowerSaveBlocker::PowerSaveBlockerType type, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& reason) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Request unblock_request = NONE; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_.push_back(BLOCK_APP_SUSPENSION); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unblock_request = UNBLOCK_APP_SUSPENSION; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep: 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_.push_back(BLOCK_DISPLAY_SLEEP); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unblock_request = UNBLOCK_DISPLAY_SLEEP; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_ptr<content::PowerSaveBlocker>( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new PowerSaveBlockerStub( 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&PowerSaveBlockerStubManager::AppendRequest, 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unblock_request))); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AppendRequest(Request request) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_.push_back(request); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Requests in chronological order. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::deque<Request> requests_; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtrFactory<PowerSaveBlockerStubManager> weak_ptr_factory_; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockerStubManager); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PowerApiTest : public BrowserWithTestWindowTest { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() OVERRIDE { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserWithTestWindowTest::SetUp(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manager_.reset(new PowerSaveBlockerStubManager); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_ = utils::CreateEmptyExtensionWithLocation( 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Manifest::UNPACKED); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Shorthand for PowerRequestKeepAwakeFunction and 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // PowerReleaseKeepAwakeFunction. 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum FunctionType { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) REQUEST, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RELEASE, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calls the function described by |type| with |args|, a JSON list of 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // arguments, on behalf of |extension|. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool CallFunction(FunctionType type, 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& args, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Extension* extension) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<UIThreadExtensionFunction> function( 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) type == REQUEST ? 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<UIThreadExtensionFunction*>( 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new PowerRequestKeepAwakeFunction) : 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<UIThreadExtensionFunction*>( 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new PowerReleaseKeepAwakeFunction)); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) function->set_extension(extension); 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return utils::RunFunction(function.get(), args, browser(), utils::NONE); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send a notification to PowerApiManager saying that |extension| has 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // been unloaded. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UnloadExtension(extensions::Extension* extension) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnloadedExtensionInfo details( 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension, extension_misc::UNLOAD_REASON_UNINSTALL); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PowerApiManager::GetInstance()->Observe( 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNLOADED, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Source<Profile>(browser()->profile()), 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Details<UnloadedExtensionInfo>(&details)); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<PowerSaveBlockerStubManager> manager_; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::Extension> extension_; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, RequestAndRelease) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension making and releasing a "display" request and a 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // "system" request. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get())); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get())); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get())); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, RequestWithoutRelease) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension calling requestKeepAwake() without calling 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // releaseKeepAwake(). The override should be automatically removed when 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the extension is unloaded. 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnloadExtension(extension_.get()); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, ReleaseWithoutRequest) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension calling releaseKeepAwake() without having 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // calling requestKeepAwake() earlier. The call should be ignored. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get())); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, UpgradeRequest) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension calling requestKeepAwake("system") and then 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // requestKeepAwake("display"). When the second call is made, a 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // display-sleep-blocking request should be made before the initial 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // app-suspension-blocking request is released. 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get())); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get())); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, DowngradeRequest) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension calling requestKeepAwake("display") and then 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // requestKeepAwake("system"). When the second call is made, an 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // app-suspension-blocking request should be made before the initial 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // display-sleep-blocking request is released. 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension_.get())); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(RELEASE, kEmptyArgs, extension_.get())); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(PowerApiTest, MultipleExtensions) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an extension blocking the display from sleeping. 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a second extension that blocks system suspend. No additional 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // PowerSaveBlocker is needed; the blocker from the first extension 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // already covers the behavior requested by the second extension. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> extension_value( 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) utils::ParseDictionary("{\"name\": \"Test\", \"version\": \"1.0\"}")); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<extensions::Extension> extension2( 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) utils::CreateExtension(extensions::Manifest::UNPACKED, 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_value.get(), "second_extension")); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kSystemArgs, extension2.get())); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When the first extension is unloaded, a new app-suspension blocker 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // should be created before the display-sleep blocker is destroyed. 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UnloadExtension(extension_.get()); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make the first extension block display-sleep again. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(CallFunction(REQUEST, kDisplayArgs, extension_.get())); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(BLOCK_DISPLAY_SLEEP, manager_->PopFirstRequest()); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(UNBLOCK_APP_SUSPENSION, manager_->PopFirstRequest()); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(NONE, manager_->PopFirstRequest()); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 286