Skip to content

Commit

Permalink
Bug 697132 - Implement wakelock interfaces. r=jlebar
Browse files Browse the repository at this point in the history
  • Loading branch information
kanru committed Mar 7, 2012
1 parent 094e7d2 commit c026ffd
Show file tree
Hide file tree
Showing 27 changed files with 1,341 additions and 26 deletions.
32 changes: 30 additions & 2 deletions dom/base/Navigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
#include "mozilla/Telemetry.h"
#include "BatteryManager.h"
#include "PowerManager.h"
#include "nsIDOMWakeLock.h"
#include "nsIPowerManagerService.h"
#include "SmsManager.h"
#include "nsISmsService.h"
#include "mozilla/Hal.h"
Expand Down Expand Up @@ -172,7 +174,10 @@ Navigator::Invalidate()
mBatteryManager = nsnull;
}

mPowerManager = nsnull;
if (mPowerManager) {
mPowerManager->Shutdown();
mPowerManager = nsnull;
}

if (mSmsManager) {
mSmsManager->Shutdown();
Expand Down Expand Up @@ -958,15 +963,38 @@ Navigator::GetMozBattery(nsIDOMMozBatteryManager** aBattery)
NS_IMETHODIMP
Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
{
*aPower = nsnull;

if (!mPowerManager) {
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);

mPowerManager = new power::PowerManager();
mPowerManager->Init(win);
}

NS_ADDREF(*aPower = mPowerManager);
nsCOMPtr<nsIDOMMozPowerManager> power =
do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozPowerManager*, mPowerManager));
power.forget(aPower);

return NS_OK;
}

NS_IMETHODIMP
Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLock)
{
*aWakeLock = nsnull;

nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(win, NS_OK);

nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_TRUE(pmService, NS_OK);

return pmService->NewWakeLock(aTopic, win, aWakeLock);
}

//*****************************************************************************
// Navigator::nsIDOMNavigatorSms
//*****************************************************************************
Expand Down
8 changes: 8 additions & 0 deletions dom/base/nsDOMClassInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "nsIDOMBatteryManager.h"
#include "BatteryManager.h"
#include "nsIDOMPowerManager.h"
#include "nsIDOMWakeLock.h"
#include "nsIDOMSmsManager.h"
#include "nsIDOMSmsMessage.h"
#include "nsIDOMSmsEvent.h"
Expand Down Expand Up @@ -1436,6 +1437,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(MozPowerManager, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)

NS_DEFINE_CLASSINFO_DATA(MozWakeLock, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)

NS_DEFINE_CLASSINFO_DATA(MozSmsManager, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)

Expand Down Expand Up @@ -4031,6 +4035,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozPowerManager)
DOM_CLASSINFO_MAP_END

DOM_CLASSINFO_MAP_BEGIN(MozWakeLock, nsIDOMMozWakeLock)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWakeLock)
DOM_CLASSINFO_MAP_END

DOM_CLASSINFO_MAP_BEGIN(MozSmsManager, nsIDOMMozSmsManager)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsManager)
DOM_CLASSINFO_MAP_END
Expand Down
1 change: 1 addition & 0 deletions dom/base/nsDOMClassInfoClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ DOMCI_CLASS(GeoPositionError)
DOMCI_CLASS(MozBatteryManager)

DOMCI_CLASS(MozPowerManager)
DOMCI_CLASS(MozWakeLock)

DOMCI_CLASS(MozSmsManager)
DOMCI_CLASS(MozSmsMessage)
Expand Down
1 change: 1 addition & 0 deletions dom/interfaces/base/domstubs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,4 @@ interface nsIDOMFontFaceList;

// Power
interface nsIDOMMozPowerManager;
interface nsIDOMMozWakeLock;
32 changes: 31 additions & 1 deletion dom/interfaces/base/nsIDOMNavigator.idl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

#include "domstubs.idl"

[scriptable, uuid(b1f4b1fa-49c2-4375-9ce8-bf97ecf6b428)]
[scriptable, uuid(e610c037-db58-4cd7-8ed3-0d7f1422b4d3)]
interface nsIDOMNavigator : nsISupports
{
readonly attribute DOMString appCodeName;
Expand Down Expand Up @@ -110,4 +110,34 @@ interface nsIDOMNavigator : nsISupports
*/
[implicit_jscontext]
void mozVibrate(in jsval aPattern);

/**
* Request a wake lock for a resource.
*
* A page holds a wake lock to request that a resource not be turned
* off (or otherwise made unavailable).
*
* The topic is the name of a resource that might be made unavailable for
* various reasons. For example, on a mobile device the power manager might
* decide to turn off the screen after a period of idle time to save power.
*
* The resource manager checks the lock state of a topic before turning off
* the associated resource. For example, a page could hold a lock on the
* "screen" topic to prevent the screensaver from appearing or the screen
* from turning off.
*
* The resource manager defines what each topic means and sets policy. For
* example, the resource manager might decide to ignore 'screen' wake locks
* held by pages which are not visible.
*
* One topic can be locked multiple times; it is considered released only when
* all locks on the topic have been released.
*
* The returned nsIDOMMozWakeLock object is a token of the lock. You can
* unlock the lock via the object's |unlock| method. The lock is released
* automatically when its associated window is unloaded.
*
* @param aTopic resource name
*/
nsIDOMMozWakeLock requestWakeLock(in DOMString aTopic);
};
4 changes: 4 additions & 0 deletions dom/power/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,19 @@ EXPORTS_NAMESPACES = mozilla/dom/power

EXPORTS_mozilla/dom/power = \
PowerManagerService.h \
Types.h \
$(NULL)

CPPSRCS = \
PowerManager.cpp \
PowerManagerService.cpp \
WakeLock.cpp \
$(NULL)

XPIDLSRCS = \
nsIDOMPowerManager.idl \
nsIDOMWakeLock.idl \
nsIDOMWakeLockListener.idl \
nsIPowerManagerService.idl \
$(NULL)

Expand Down
115 changes: 111 additions & 4 deletions dom/power/PowerManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@
* ***** END LICENSE BLOCK ***** */

#include "PowerManager.h"
#include "WakeLock.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfoID.h"
#include "nsIDOMWakeLockListener.h"
#include "nsIPowerManagerService.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"

DOMCI_DATA(MozPowerManager, mozilla::dom::power::PowerManager)
Expand All @@ -50,20 +54,66 @@ namespace power {
NS_INTERFACE_MAP_BEGIN(PowerManager)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozPowerManager)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozPowerManager)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozWakeLockListener)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozPowerManager)
NS_INTERFACE_MAP_END

NS_IMPL_ADDREF(PowerManager)
NS_IMPL_RELEASE(PowerManager)

nsresult
PowerManager::Init(nsIDOMWindow *aWindow)
{
mWindow = do_GetWeakReference(aWindow);

nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);

// Add ourself to the global notification list.
pmService->AddWakeLockListener(this);
return NS_OK;
}

nsresult
PowerManager::Shutdown()
{
nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);

// Remove ourself from the global notification list.
pmService->RemoveWakeLockListener(this);
return NS_OK;
}

nsresult
PowerManager::CheckPermission()
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
NS_ENSURE_STATE(win);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
NS_ENSURE_STATE(doc);

nsCOMPtr<nsIURI> uri;
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));

if (!nsContentUtils::URIIsChromeOrInPref(uri, "dom.power.whitelist")) {
return NS_ERROR_DOM_SECURITY_ERR;
}

return NS_OK;
}

NS_IMETHODIMP
PowerManager::Reboot()
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
nsresult rv = CheckPermission();
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_TRUE(pmService, NS_OK);
NS_ENSURE_STATE(pmService);

pmService->Reboot();

Expand All @@ -73,17 +123,74 @@ PowerManager::Reboot()
NS_IMETHODIMP
PowerManager::PowerOff()
{
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
nsresult rv = CheckPermission();
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_TRUE(pmService, NS_OK);
NS_ENSURE_STATE(pmService);

pmService->PowerOff();

return NS_OK;
}

NS_IMETHODIMP
PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
nsresult rv = CheckPermission();
NS_ENSURE_SUCCESS(rv, rv);

// already added? bail out.
if (mListeners.Contains(aListener))
return NS_OK;

mListeners.AppendElement(aListener);
return NS_OK;
}

NS_IMETHODIMP
PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
nsresult rv = CheckPermission();
NS_ENSURE_SUCCESS(rv, rv);

mListeners.RemoveElement(aListener);
return NS_OK;
}

NS_IMETHODIMP
PowerManager::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
{
nsresult rv = CheckPermission();
NS_ENSURE_SUCCESS(rv, rv);

nsCOMPtr<nsIPowerManagerService> pmService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
NS_ENSURE_STATE(pmService);

return pmService->GetWakeLockState(aTopic, aState);
}

NS_IMETHODIMP
PowerManager::Callback(const nsAString &aTopic, const nsAString &aState)
{
/**
* We maintain a local listener list instead of using the global
* list so that when the window is destroyed we don't have to
* cleanup the mess.
* Copy the listeners list before we walk through the callbacks
* because the callbacks may install new listeners. We expect no
* more than one listener per window, so it shouldn't be too long.
*/
nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mListeners);
for (PRUint32 i = 0; i < listeners.Length(); ++i) {
listeners[i]->Callback(aTopic, aState);
}

return NS_OK;
}

} // power
} // dom
} // mozilla
16 changes: 16 additions & 0 deletions dom/power/PowerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,37 @@
#ifndef mozilla_dom_power_PowerManager_h
#define mozilla_dom_power_PowerManager_h

#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsIDOMPowerManager.h"
#include "nsIDOMWakeLockListener.h"
#include "nsIDOMWindow.h"
#include "nsWeakReference.h"

namespace mozilla {
namespace dom {
namespace power {

class PowerManager
: public nsIDOMMozPowerManager
, public nsIDOMMozWakeLockListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZPOWERMANAGER
NS_DECL_NSIDOMMOZWAKELOCKLISTENER

PowerManager() {};
virtual ~PowerManager() {};

nsresult Init(nsIDOMWindow *aWindow);
nsresult Shutdown();

private:
nsresult CheckPermission();

nsWeakPtr mWindow;
nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;
};

} // namespace power
Expand Down
Loading

0 comments on commit c026ffd

Please sign in to comment.