From e9a3b24dc964b2dfb498b88749606adafed2c3e0 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 16 Apr 2012 18:35:33 -0400 Subject: [PATCH] Bug 739913 - Add cpuSleepAllowed attribute to mozPower. r=cjones --- b2g/chrome/content/shell.js | 4 ++++ dom/power/PowerManager.cpp | 21 +++++++++++++++++++++ dom/power/nsIDOMPowerManager.idl | 9 ++++++++- hal/Hal.cpp | 16 ++++++++++++++++ hal/Hal.h | 11 +++++++++++ hal/Makefile.in | 6 +++++- hal/fallback/FallbackWakeLocks.cpp | 23 +++++++++++++++++++++++ hal/gonk/GonkHal.cpp | 21 +++++++++++++++++++++ hal/sandbox/PHal.ipdl | 3 +++ hal/sandbox/SandboxHal.cpp | 28 ++++++++++++++++++++++++++++ 10 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 hal/fallback/FallbackWakeLocks.cpp diff --git a/b2g/chrome/content/shell.js b/b2g/chrome/content/shell.js index 165a280d298..d82cca77843 100644 --- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -323,6 +323,10 @@ var shell = { navigator.mozPower.screenEnabled = true; } } + if (topic == "cpu") { + navigator.mozPower.cpuSleepAllowed = (state != "locked-foreground" && + state != "locked-background"); + } } let idleTimeout = Services.prefs.getIntPref("power.screen.timeout"); diff --git a/dom/power/PowerManager.cpp b/dom/power/PowerManager.cpp index 4c698ba07b3..9dcf5b34baf 100644 --- a/dom/power/PowerManager.cpp +++ b/dom/power/PowerManager.cpp @@ -236,6 +236,27 @@ PowerManager::SetScreenBrightness(double aBrightness) return NS_OK; } +NS_IMETHODIMP +PowerManager::GetCpuSleepAllowed(bool *aAllowed) +{ + if (!CheckPermission()) { + *aAllowed = true; + return NS_OK; + } + + *aAllowed = hal::GetCpuSleepAllowed(); + return NS_OK; +} + +NS_IMETHODIMP +PowerManager::SetCpuSleepAllowed(bool aAllowed) +{ + NS_ENSURE_TRUE(CheckPermission(), NS_ERROR_DOM_SECURITY_ERR); + + hal::SetCpuSleepAllowed(aAllowed); + return NS_OK; +} + } // power } // dom } // mozilla diff --git a/dom/power/nsIDOMPowerManager.idl b/dom/power/nsIDOMPowerManager.idl index b0e3e6e54cc..a1e3633f1a5 100644 --- a/dom/power/nsIDOMPowerManager.idl +++ b/dom/power/nsIDOMPowerManager.idl @@ -42,7 +42,7 @@ interface nsIDOMMozWakeLockListener; /** * This interface implements navigator.mozPower */ -[scriptable, uuid(4586bed1-cf78-4436-b503-88277d645b68)] +[scriptable, uuid(256a3287-f528-45b5-9ba8-2b3650c056e6)] interface nsIDOMMozPowerManager : nsISupports { void powerOff(); @@ -96,4 +96,11 @@ interface nsIDOMMozPowerManager : nsISupports * @throw NS_ERROR_INVALID_ARG if brightness is not in the range [0, 1]. */ attribute double screenBrightness; + + /** + * Is it possible that the device's CPU will sleep after the screen is + * disabled? Setting this attribute to false will prevent the device + * entering suspend state. + */ + attribute boolean cpuSleepAllowed; }; diff --git a/hal/Hal.cpp b/hal/Hal.cpp index 0e5f31f60a2..2a806ac8cb7 100644 --- a/hal/Hal.cpp +++ b/hal/Hal.cpp @@ -363,6 +363,22 @@ void SetScreenEnabled(bool enabled) PROXY_IF_SANDBOXED(SetScreenEnabled(enabled)); } +bool GetCpuSleepAllowed() +{ + // Generally for interfaces that are accessible by normal web content + // we should cache the result and be notified on state changes, like + // what the battery API does. But since this is only used by + // privileged interface, the synchronous getter is OK here. + AssertMainThread(); + RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed()); +} + +void SetCpuSleepAllowed(bool allowed) +{ + AssertMainThread(); + PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed)); +} + double GetScreenBrightness() { AssertMainThread(); diff --git a/hal/Hal.h b/hal/Hal.h index eec11951811..783242c2c4e 100644 --- a/hal/Hal.h +++ b/hal/Hal.h @@ -148,6 +148,17 @@ double GetScreenBrightness(); */ void SetScreenBrightness(double brightness); +/** + * Determine whether the device is allowed to sleep. + */ +bool GetCpuSleepAllowed(); + +/** + * Set whether the device is allowed to suspend automatically after + * the screen is disabled. + */ +void SetCpuSleepAllowed(bool allowed); + /** * Set the value of a light to a particular color, with a specific flash pattern. * light specifices which light. See Hal.idl for the list of constants diff --git a/hal/Makefile.in b/hal/Makefile.in index 7c251375bfe..c49860de3ff 100644 --- a/hal/Makefile.in +++ b/hal/Makefile.in @@ -117,7 +117,11 @@ CPPSRCS += \ endif ifneq (gonk,$(MOZ_WIDGET_TOOLKIT)) #{ -CPPSRCS += FallbackLights.cpp FallbackTime.cpp +CPPSRCS += \ + FallbackLights.cpp \ + FallbackTime.cpp \ + FallbackWakeLocks.cpp \ + $(NULL) endif #} # Screen Orientation backend diff --git a/hal/fallback/FallbackWakeLocks.cpp b/hal/fallback/FallbackWakeLocks.cpp new file mode 100644 index 00000000000..1fd97a2e620 --- /dev/null +++ b/hal/fallback/FallbackWakeLocks.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et ft=cpp : */ +/* 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/. */ + +#include "Hal.h" + +namespace mozilla { +namespace hal_impl { + +bool +GetCpuSleepAllowed() +{ + return true; +} + +void +SetCpuSleepAllowed(bool allowed) +{} + +} // namespace hal_impl +} // namespace mozilla diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index ed9c6a9c980..98c03e5f2e7 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -329,6 +329,8 @@ namespace { * RAII class to help us remember to close file descriptors. */ const char *screenEnabledFilename = "/sys/power/state"; +const char *wakeLockFilename = "/sys/power/wake_lock"; +const char *wakeUnlockFilename = "/sys/power/wake_unlock"; template bool ReadFromFile(const char *filename, char (&buf)[n]) @@ -370,6 +372,12 @@ void WriteToFile(const char *filename, const char *toWrite) // the screen is on or not. bool sScreenEnabled = true; +// We can read wakeLockFilename to find out whether the cpu wake lock +// is already acquired, but reading and parsing it is a lot more work +// than tracking it ourselves, and it won't be accurate anyway (kernel +// internal wake locks aren't counted here.) +bool sCpuSleepAllowed = true; + } // anonymous namespace bool @@ -422,6 +430,19 @@ SetScreenBrightness(double brightness) hal::SetLight(hal::eHalLightID_Buttons, aConfig); } +bool +GetCpuSleepAllowed() +{ + return sCpuSleepAllowed; +} + +void +SetCpuSleepAllowed(bool aAllowed) +{ + WriteToFile(aAllowed ? wakeUnlockFilename : wakeLockFilename, "gecko"); + sCpuSleepAllowed = aAllowed; +} + static light_device_t* sLights[hal::eHalLightID_Count]; // will be initialized to NULL light_device_t* GetDevice(hw_module_t* module, char const* name) diff --git a/hal/sandbox/PHal.ipdl b/hal/sandbox/PHal.ipdl index e26ad51c965..71f84e11f65 100644 --- a/hal/sandbox/PHal.ipdl +++ b/hal/sandbox/PHal.ipdl @@ -120,6 +120,9 @@ parent: sync GetScreenEnabled() returns (bool enabled); SetScreenEnabled(bool enabled); + sync GetCpuSleepAllowed() returns (bool allowed); + SetCpuSleepAllowed(bool allowed); + sync GetScreenBrightness() returns (double brightness); SetScreenBrightness(double brightness); diff --git a/hal/sandbox/SandboxHal.cpp b/hal/sandbox/SandboxHal.cpp index 1348cbdfe55..79119233ede 100644 --- a/hal/sandbox/SandboxHal.cpp +++ b/hal/sandbox/SandboxHal.cpp @@ -138,6 +138,20 @@ SetScreenEnabled(bool enabled) Hal()->SendSetScreenEnabled(enabled); } +bool +GetCpuSleepAllowed() +{ + bool allowed = true; + Hal()->SendGetCpuSleepAllowed(&allowed); + return allowed; +} + +void +SetCpuSleepAllowed(bool allowed) +{ + Hal()->SendSetCpuSleepAllowed(allowed); +} + double GetScreenBrightness() { @@ -367,6 +381,20 @@ public: return true; } + NS_OVERRIDE virtual bool + RecvGetCpuSleepAllowed(bool *allowed) + { + *allowed = hal::GetCpuSleepAllowed(); + return true; + } + + NS_OVERRIDE virtual bool + RecvSetCpuSleepAllowed(const bool &allowed) + { + hal::SetCpuSleepAllowed(allowed); + return true; + } + NS_OVERRIDE virtual bool RecvGetScreenBrightness(double *brightness) {