зеркало из https://github.com/mozilla/gecko-dev.git
Bug 836654 - Part 4: Add PowerManagerService::NewWakeLockOnBehalfOfProcess. r=cjones
This commit is contained in:
Родитель
d8e79ada25
Коммит
e8adf751fd
|
@ -199,6 +199,16 @@ PowerManagerService::NewWakeLock(const nsAString &aTopic,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMMozWakeLock>
|
||||
PowerManagerService::NewWakeLockOnBehalfOfProcess(const nsAString& aTopic,
|
||||
ContentParent* aContentParent)
|
||||
{
|
||||
nsRefPtr<WakeLock> wakelock = new WakeLock();
|
||||
nsresult rv = wakelock->Init(aTopic, aContentParent);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return wakelock.forget();
|
||||
}
|
||||
|
||||
} // power
|
||||
} // dom
|
||||
} // mozilla
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentParent;
|
||||
|
||||
namespace power {
|
||||
|
||||
class PowerManagerService
|
||||
|
@ -33,6 +36,22 @@ public:
|
|||
// Implement WakeLockObserver
|
||||
void Notify(const hal::WakeLockInformation& aWakeLockInfo);
|
||||
|
||||
/**
|
||||
* Acquire a wake lock on behalf of a given process (aContentParent).
|
||||
*
|
||||
* This method stands in contrast to nsIPowerManagerService::NewWakeLock,
|
||||
* which acquires a wake lock on behalf of the /current/ process.
|
||||
*
|
||||
* NewWakeLockOnBehalfOfProcess is different from NewWakeLock in that
|
||||
*
|
||||
* - The wake lock unlocks itself if the /given/ process dies, and
|
||||
* - The /given/ process shows up in WakeLockInfo::lockingProcesses.
|
||||
*
|
||||
*/
|
||||
already_AddRefed<nsIDOMMozWakeLock>
|
||||
NewWakeLockOnBehalfOfProcess(const nsAString& aTopic,
|
||||
ContentParent* aContentParent);
|
||||
|
||||
private:
|
||||
|
||||
~PowerManagerService();
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
* 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 "WakeLock.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/HalWakeLock.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
|
@ -13,10 +15,11 @@
|
|||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "PowerManager.h"
|
||||
#include "WakeLock.h"
|
||||
|
||||
DOMCI_DATA(MozWakeLock, mozilla::dom::power::WakeLock)
|
||||
|
||||
using namespace mozilla::hal;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace power {
|
||||
|
@ -25,6 +28,8 @@ NS_INTERFACE_MAP_BEGIN(WakeLock)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIDOMMozWakeLock)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozWakeLock)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozWakeLock)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -34,6 +39,7 @@ NS_IMPL_RELEASE(WakeLock)
|
|||
WakeLock::WakeLock()
|
||||
: mLocked(false)
|
||||
, mHidden(true)
|
||||
, mContentParentID(CONTENT_PROCESS_ID_UNKNOWN)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -46,6 +52,13 @@ WakeLock::~WakeLock()
|
|||
nsresult
|
||||
WakeLock::Init(const nsAString &aTopic, nsIDOMWindow *aWindow)
|
||||
{
|
||||
// Don't Init() a WakeLock twice.
|
||||
MOZ_ASSERT(mTopic.IsEmpty());
|
||||
|
||||
if (aTopic.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mTopic.Assign(aTopic);
|
||||
|
||||
mWindow = do_GetWeakReference(aWindow);
|
||||
|
@ -67,15 +80,73 @@ WakeLock::Init(const nsAString &aTopic, nsIDOMWindow *aWindow)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WakeLock::Init(const nsAString& aTopic, ContentParent* aContentParent)
|
||||
{
|
||||
// Don't Init() a WakeLock twice.
|
||||
MOZ_ASSERT(mTopic.IsEmpty());
|
||||
MOZ_ASSERT(aContentParent);
|
||||
|
||||
if (aTopic.IsEmpty()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
mTopic.Assign(aTopic);
|
||||
mContentParentID = aContentParent->ChildID();
|
||||
mHidden = false;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "ipc:content-shutdown", /* ownsWeak */ true);
|
||||
}
|
||||
|
||||
DoLock();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WakeLock::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* data)
|
||||
{
|
||||
// If this wake lock was acquired on behalf of another process, unlock it
|
||||
// when that process dies.
|
||||
//
|
||||
// Note that we do /not/ call DoUnlock() here! The wake lock back-end is
|
||||
// already listening for ipc:content-shutdown messages and will clear out its
|
||||
// tally for the process when it dies. All we need to do here is ensure that
|
||||
// unlock() becomes a nop.
|
||||
|
||||
MOZ_ASSERT(!strcmp(aTopic, "ipc:content-shutdown"));
|
||||
|
||||
nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
|
||||
if (!props) {
|
||||
NS_WARNING("ipc:content-shutdown message without property bag as subject");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint64_t childID = 0;
|
||||
nsresult rv = props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"),
|
||||
&childID);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (childID == mContentParentID) {
|
||||
mLocked = false;
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("ipc:content-shutdown message without childID property");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
WakeLock::DoLock()
|
||||
{
|
||||
if (!mLocked) {
|
||||
// Change the flag immediately to prevent recursive reentering
|
||||
mLocked = true;
|
||||
|
||||
hal::ModifyWakeLock(mTopic,
|
||||
hal::WAKE_LOCK_ADD_ONE,
|
||||
mHidden ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_NO_CHANGE);
|
||||
mHidden ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_NO_CHANGE,
|
||||
mContentParentID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,9 +156,11 @@ WakeLock::DoUnlock()
|
|||
if (mLocked) {
|
||||
// Change the flag immediately to prevent recursive reentering
|
||||
mLocked = false;
|
||||
|
||||
hal::ModifyWakeLock(mTopic,
|
||||
hal::WAKE_LOCK_REMOVE_ONE,
|
||||
mHidden ? hal::WAKE_LOCK_REMOVE_ONE : hal::WAKE_LOCK_NO_CHANGE);
|
||||
mHidden ? hal::WAKE_LOCK_REMOVE_ONE : hal::WAKE_LOCK_NO_CHANGE,
|
||||
mContentParentID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +253,8 @@ WakeLock::HandleEvent(nsIDOMEvent *aEvent)
|
|||
if (mLocked) {
|
||||
hal::ModifyWakeLock(mTopic,
|
||||
hal::WAKE_LOCK_NO_CHANGE,
|
||||
mHidden ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_REMOVE_ONE);
|
||||
mHidden ? hal::WAKE_LOCK_ADD_ONE : hal::WAKE_LOCK_REMOVE_ONE,
|
||||
mContentParentID);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMWakeLock.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
|
@ -16,21 +17,35 @@ class nsIDOMWindow;
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ContentParent;
|
||||
|
||||
namespace power {
|
||||
|
||||
class WakeLock
|
||||
: public nsIDOMMozWakeLock
|
||||
, public nsIDOMEventListener
|
||||
, public nsIObserver
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMMOZWAKELOCK
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
WakeLock();
|
||||
virtual ~WakeLock();
|
||||
|
||||
nsresult Init(const nsAString &aTopic, nsIDOMWindow *aWindow);
|
||||
// Initialize this wake lock on behalf of the given window. Null windows are
|
||||
// allowed; a lock without an associated window is always considered
|
||||
// invisible.
|
||||
nsresult Init(const nsAString &aTopic, nsIDOMWindow* aWindow);
|
||||
|
||||
// Initialize this wake lock on behalf of the given process. If the process
|
||||
// dies, the lock is released. A wake lock initialized via this method is
|
||||
// always considered visible.
|
||||
nsresult Init(const nsAString &aTopic, ContentParent* aContentParent);
|
||||
|
||||
private:
|
||||
void DoUnlock();
|
||||
|
@ -40,6 +55,11 @@ private:
|
|||
|
||||
bool mLocked;
|
||||
bool mHidden;
|
||||
|
||||
// The ID of the ContentParent on behalf of whom we acquired this lock, or
|
||||
// CONTENT_PROCESS_UNKNOWN_ID if this lock was acquired on behalf of the
|
||||
// current process.
|
||||
uint64_t mContentParentID;
|
||||
nsString mTopic;
|
||||
|
||||
// window that this was created for. Weak reference.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define mozilla_Hal_h
|
||||
|
||||
#include "mozilla/hal_sandbox/PHal.h"
|
||||
#include "mozilla/HalTypes.h"
|
||||
#include "base/basictypes.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -359,7 +360,7 @@ void UnregisterWakeLockObserver(WakeLockObserver* aObserver);
|
|||
void ModifyWakeLock(const nsAString &aTopic,
|
||||
hal::WakeLockControl aLockAdjust,
|
||||
hal::WakeLockControl aHiddenAdjust,
|
||||
uint64_t aProcessID = CONTENT_PROCESS_ID_UNKNOWN);
|
||||
uint64_t aProcessID = hal::CONTENT_PROCESS_ID_UNKNOWN);
|
||||
|
||||
/**
|
||||
* Query the wake lock numbers of aTopic.
|
||||
|
|
Загрузка…
Ссылка в новой задаче