fune/dom/power/PowerManagerService.cpp
Makoto Kato a10b8df4d2 Bug 1492736 - Part 1. Add nsIWakeLock to manage wake lock from devtools. r=baku
DevTools wants to use wake lock to keep screen.  But since MozWakeLock is
removed by bug 1369194, there is no way to unlock wake lock from script.

So this issue adds nsIWakeLock to unlock wake lock.

Differential Revision: https://phabricator.services.mozilla.com/D7158

--HG--
extra : rebase_source : 4d6069fce27a7d85ce484a1418a8a17de83166f1
2018-09-28 14:05:07 +09:00

167 lines
4.3 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "mozilla/dom/ContentParent.h"
#include "mozilla/Hal.h"
#include "mozilla/HalWakeLock.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "nsIDOMWakeLockListener.h"
#include "nsIDOMWindow.h"
#include "nsIObserverService.h"
#include "PowerManagerService.h"
#include "WakeLock.h"
// For _exit().
#ifdef XP_WIN
#include <process.h>
#else
#include <unistd.h>
#endif
namespace mozilla {
namespace dom {
namespace power {
using namespace hal;
NS_IMPL_ISUPPORTS(PowerManagerService, nsIPowerManagerService)
/* static */ StaticRefPtr<PowerManagerService> PowerManagerService::sSingleton;
/* static */ already_AddRefed<PowerManagerService>
PowerManagerService::GetInstance()
{
if (!sSingleton) {
sSingleton = new PowerManagerService();
sSingleton->Init();
ClearOnShutdown(&sSingleton);
}
RefPtr<PowerManagerService> service = sSingleton.get();
return service.forget();
}
void
PowerManagerService::Init()
{
RegisterWakeLockObserver(this);
}
PowerManagerService::~PowerManagerService()
{
UnregisterWakeLockObserver(this);
}
void
PowerManagerService::ComputeWakeLockState(const WakeLockInformation& aWakeLockInfo,
nsAString &aState)
{
WakeLockState state = hal::ComputeWakeLockState(aWakeLockInfo.numLocks(),
aWakeLockInfo.numHidden());
switch (state) {
case WAKE_LOCK_STATE_UNLOCKED:
aState.AssignLiteral("unlocked");
break;
case WAKE_LOCK_STATE_HIDDEN:
aState.AssignLiteral("locked-background");
break;
case WAKE_LOCK_STATE_VISIBLE:
aState.AssignLiteral("locked-foreground");
break;
}
}
void
PowerManagerService::Notify(const WakeLockInformation& aWakeLockInfo)
{
nsAutoString state;
ComputeWakeLockState(aWakeLockInfo, state);
/**
* 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.
*/
AutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
for (uint32_t i = 0; i < listeners.Length(); ++i) {
listeners[i]->Callback(aWakeLockInfo.topic(), state);
}
}
NS_IMETHODIMP
PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
if (mWakeLockListeners.Contains(aListener))
return NS_OK;
mWakeLockListeners.AppendElement(aListener);
return NS_OK;
}
NS_IMETHODIMP
PowerManagerService::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
{
mWakeLockListeners.RemoveElement(aListener);
return NS_OK;
}
NS_IMETHODIMP
PowerManagerService::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
{
WakeLockInformation info;
GetWakeLockInfo(aTopic, &info);
ComputeWakeLockState(info, aState);
return NS_OK;
}
already_AddRefed<WakeLock>
PowerManagerService::NewWakeLock(const nsAString& aTopic,
nsPIDOMWindowInner* aWindow,
mozilla::ErrorResult& aRv)
{
RefPtr<WakeLock> wakelock = new WakeLock();
aRv = wakelock->Init(aTopic, aWindow);
if (aRv.Failed()) {
return nullptr;
}
return wakelock.forget();
}
NS_IMETHODIMP
PowerManagerService::NewWakeLock(const nsAString &aTopic,
mozIDOMWindow *aWindow,
nsIWakeLock **aWakeLock)
{
mozilla::ErrorResult rv;
RefPtr<WakeLock> wakelock =
NewWakeLock(aTopic, nsPIDOMWindowInner::From(aWindow), rv);
if (rv.Failed()) {
return rv.StealNSResult();
}
wakelock.forget(aWakeLock);
return NS_OK;
}
already_AddRefed<WakeLock>
PowerManagerService::NewWakeLockOnBehalfOfProcess(const nsAString& aTopic,
ContentParent* aContentParent)
{
RefPtr<WakeLock> wakelock = new WakeLock();
nsresult rv = wakelock->Init(aTopic, aContentParent);
NS_ENSURE_SUCCESS(rv, nullptr);
return wakelock.forget();
}
} // namespace power
} // namespace dom
} // namespace mozilla