Bug 781353 - Hook up "power" to Permission Manager. r=jlebar

This commit is contained in:
Kan-Ru Chen (陳侃如) 2012-08-11 19:40:43 +08:00
parent 1a38d38c0b
commit ba4db0438e
5 changed files with 69 additions and 78 deletions

View File

@ -54,6 +54,8 @@
#include "nsIDOMGlobalPropertyInitializer.h"
using namespace mozilla::dom::power;
// This should not be in the namespace.
DOMCI_DATA(Navigator, mozilla::dom::Navigator)
@ -1029,11 +1031,11 @@ Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
*aPower = nullptr;
if (!mPowerManager) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_OK);
mPowerManager = new power::PowerManager();
mPowerManager->Init(win);
mPowerManager = PowerManager::CheckPermissionAndCreateInstance(window);
NS_ENSURE_TRUE(mPowerManager, NS_OK);
}
nsCOMPtr<nsIDOMMozPowerManager> power(mPowerManager);

View File

@ -6,9 +6,10 @@
#include "mozilla/Hal.h"
#include "PowerManager.h"
#include "WakeLock.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMWakeLockListener.h"
#include "nsIDocument.h"
#include "nsIPermissionManager.h"
#include "nsIPowerManagerService.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
@ -57,33 +58,9 @@ PowerManager::Shutdown()
return NS_OK;
}
bool
PowerManager::CheckPermission()
{
if (nsContentUtils::IsCallerChrome()) {
return true;
}
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, false);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
NS_ENSURE_TRUE(doc, false);
nsCOMPtr<nsIURI> uri;
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
if (!nsContentUtils::URIIsChromeOrInPref(uri, "dom.power.whitelist")) {
return false;
}
return true;
}
NS_IMETHODIMP
PowerManager::Reboot()
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -96,8 +73,6 @@ PowerManager::Reboot()
NS_IMETHODIMP
PowerManager::PowerOff()
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -110,8 +85,6 @@ PowerManager::PowerOff()
NS_IMETHODIMP
PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
// already added? bail out.
if (mListeners.Contains(aListener))
return NS_OK;
@ -123,8 +96,6 @@ PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
NS_IMETHODIMP
PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
mListeners.RemoveElement(aListener);
return NS_OK;
}
@ -132,8 +103,6 @@ PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
NS_IMETHODIMP
PowerManager::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);
@ -163,11 +132,6 @@ PowerManager::Callback(const nsAString &aTopic, const nsAString &aState)
NS_IMETHODIMP
PowerManager::GetScreenEnabled(bool *aEnabled)
{
if (!CheckPermission()) {
*aEnabled = true;
return NS_OK;
}
*aEnabled = hal::GetScreenEnabled();
return NS_OK;
}
@ -175,10 +139,6 @@ PowerManager::GetScreenEnabled(bool *aEnabled)
NS_IMETHODIMP
PowerManager::SetScreenEnabled(bool aEnabled)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
// TODO bug 707589: When the screen's state changes, all visible windows
// should fire a visibility change event.
hal::SetScreenEnabled(aEnabled);
return NS_OK;
}
@ -186,11 +146,6 @@ PowerManager::SetScreenEnabled(bool aEnabled)
NS_IMETHODIMP
PowerManager::GetScreenBrightness(double *aBrightness)
{
if (!CheckPermission()) {
*aBrightness = 1;
return NS_OK;
}
*aBrightness = hal::GetScreenBrightness();
return NS_OK;
}
@ -198,8 +153,6 @@ PowerManager::GetScreenBrightness(double *aBrightness)
NS_IMETHODIMP
PowerManager::SetScreenBrightness(double aBrightness)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
NS_ENSURE_TRUE(0 <= aBrightness && aBrightness <= 1, NS_ERROR_INVALID_ARG);
hal::SetScreenBrightness(aBrightness);
return NS_OK;
@ -208,11 +161,6 @@ PowerManager::SetScreenBrightness(double aBrightness)
NS_IMETHODIMP
PowerManager::GetCpuSleepAllowed(bool *aAllowed)
{
if (!CheckPermission()) {
*aAllowed = true;
return NS_OK;
}
*aAllowed = hal::GetCpuSleepAllowed();
return NS_OK;
}
@ -220,12 +168,40 @@ PowerManager::GetCpuSleepAllowed(bool *aAllowed)
NS_IMETHODIMP
PowerManager::SetCpuSleepAllowed(bool aAllowed)
{
NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR);
hal::SetCpuSleepAllowed(aAllowed);
return NS_OK;
}
already_AddRefed<PowerManager>
PowerManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
{
nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
aWindow :
aWindow->GetCurrentInnerWindow();
// Need the document for security check.
nsCOMPtr<nsIDocument> document = innerWindow->GetExtantDoc();
NS_ENSURE_TRUE(document, nullptr);
nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
NS_ENSURE_TRUE(permMgr, nullptr);
PRUint32 permission = nsIPermissionManager::DENY_ACTION;
permMgr->TestPermissionFromPrincipal(principal, "power", &permission);
if (permission != nsIPermissionManager::ALLOW_ACTION) {
return nullptr;
}
nsRefPtr<PowerManager> powerManager = new PowerManager();
powerManager->Init(aWindow);
return powerManager.forget();
}
} // power
} // dom
} // mozilla

View File

@ -12,6 +12,8 @@
#include "nsIDOMWindow.h"
#include "nsWeakReference.h"
class nsPIDOMWindow;
namespace mozilla {
namespace dom {
namespace power {
@ -31,8 +33,10 @@ public:
nsresult Init(nsIDOMWindow *aWindow);
nsresult Shutdown();
static already_AddRefed<PowerManager>
CheckPermissionAndCreateInstance(nsPIDOMWindow*);
private:
bool CheckPermission();
nsWeakPtr mWindow;
nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;

View File

@ -1,10 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
waitForExplicitFinish();
let kPrefNode = "dom.power.whitelist";
let kPageSource1 = "data:text/html,1";
let kPageSource2 = "data:text/html,2";
let kUrlSource = "http://mochi.test:8888/";
let kDataSource = "data:text/html,";
let gOldPref;
let gWin, gWin1, gWin2;
@ -13,7 +16,7 @@ let gLock, gLock1, gLock2;
let gCurStepIndex = -1;
let gSteps = [
function basicWakeLock() {
gTab = gBrowser.addTab(kPageSource1);
gTab = gBrowser.addTab(kUrlSource);
gWin = gBrowser.getBrowserForTab(gTab).contentWindow;
let browser = gBrowser.getBrowserForTab(gTab);
@ -51,7 +54,7 @@ let gSteps = [
}, true);
},
function multiWakeLock() {
gTab = gBrowser.addTab(kPageSource1);
gTab = gBrowser.addTab(kUrlSource);
gWin = gBrowser.getBrowserForTab(gTab).contentWindow;
let browser = gBrowser.getBrowserForTab(gTab);
@ -100,9 +103,9 @@ let gSteps = [
}, true);
},
function crossTabWakeLock1() {
gTab1 = gBrowser.addTab(kPageSource1);
gTab1 = gBrowser.addTab(kUrlSource);
gWin1 = gBrowser.getBrowserForTab(gTab1).contentWindow;
gTab2 = gBrowser.addTab(kPageSource1);
gTab2 = gBrowser.addTab(kUrlSource);
gWin2 = gBrowser.getBrowserForTab(gTab2).contentWindow;
gBrowser.selectedTab = gTab1;
@ -138,7 +141,7 @@ let gSteps = [
gWin2.removeEventListener("pageshow", onPageShow, true);
executeSoon(runNextStep);
}, true);
gWin2.location = kPageSource2;
gWin2.location = kDataSource;
},
function crossTabWakeLock3() {
is(gWin1.navigator.mozPower.getWakeLockState("test"), "unlocked",
@ -166,7 +169,7 @@ let gSteps = [
gWin2.removeEventListener("pageshow", onPageShow, true);
executeSoon(runNextStep);
}, true);
gWin2.location = kPageSource2;
gWin2.location = kDataSource;
},
function crossTabWakeLock6() {
is(gWin1.navigator.mozPower.getWakeLockState("test"), "unlocked",
@ -219,18 +222,12 @@ function runNextStep() {
if (gCurStepIndex < gSteps.length) {
gSteps[gCurStepIndex]();
} else {
Services.prefs.setCharPref(kPrefNode, gOldPref);
SpecialPowers.removePermission("power", kUrlSource);
finish();
}
}
function test() {
try {
gOldPref = Services.prefs.getCharPref(kPrefNode);
} catch (e) {
gOldPref = "";
}
// data url inherits its parent's principal, which is |about:| here.
Services.prefs.setCharPref(kPrefNode, "about:");
SpecialPowers.addPermission("power", true, kUrlSource);
runNextStep();
}

View File

@ -16,6 +16,18 @@
ok('mozPower' in navigator, "navigator.mozPower should exist");
/** Test permission **/
SpecialPowers.removePermission("power", document);
power = navigator.mozPower;
ok(!power, "Shouldn't be able to access power manager without permission.");
SpecialPowers.addPermission("power", true, document);
power = navigator.mozPower;
ok(power, "Shouldn be able to access power manager with permission.");
</script>
</pre>
</body>