Bug 836654 - Part 3: Modify hal to accept a ContentParent ID in ModifyWakeLock(). r=cjones
authorJustin Lebar <justin.lebar@gmail.com>
Thu, 14 Feb 2013 15:41:30 -0500
changeset 121950 6480e7d33c5a02b0ff083188b7976066b5b5dc40
parent 121949 fb43c5972c2c3973ef75cac87704d8242988a526
child 121951 691f0a62b261e89137d8a5de1191e4d1578a4acc
push id23012
push userjlebar@mozilla.com
push dateThu, 14 Feb 2013 20:43:09 +0000
treeherdermozilla-inbound@4497d85b07f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs836654
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 836654 - Part 3: Modify hal to accept a ContentParent ID in ModifyWakeLock(). r=cjones Also return the list of processes holding the lock in GetWakeLockInfo and in the wake-lock changed notification.
hal/Hal.cpp
hal/Hal.h
hal/HalTypes.h
hal/HalWakeLock.cpp
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -17,23 +17,25 @@
 #include "nsIWebNavigation.h"
 #include "nsITabChild.h"
 #include "nsIDocShell.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "WindowIdentifier.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/ContentParent.h"
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #endif
 
 using namespace mozilla::services;
+using namespace mozilla::dom;
 
 #define PROXY_IF_SANDBOXED(_call)                 \
   do {                                            \
     if (InSandbox()) {                            \
       if (!hal_sandbox::HalChildDestroyed()) {    \
         hal_sandbox::_call;                       \
       }                                           \
     } else {                                      \
@@ -639,33 +641,28 @@ UnregisterWakeLockObserver(WakeLockObser
 {
   AssertMainThread();
   sWakeLockObservers.RemoveObserver(aObserver);
 }
 
 void
 ModifyWakeLock(const nsAString& aTopic,
                WakeLockControl aLockAdjust,
-               WakeLockControl aHiddenAdjust)
+               WakeLockControl aHiddenAdjust,
+               uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */)
 {
   AssertMainThread();
-  uint64_t processID = InSandbox() ? dom::ContentChild::GetSingleton()->GetID() : 0;
-  PROXY_IF_SANDBOXED(ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, processID));
-}
 
-void
-ModifyWakeLockInternal(const nsAString& aTopic,
-                       WakeLockControl aLockAdjust,
-                       WakeLockControl aHiddenAdjust,
-                       uint64_t aProcessID)
-{
-  AssertMainThread();
-  // TODO: Bug 812403 - support wake locks in nested content processes.
-  AssertMainProcess();
-  PROXY_IF_SANDBOXED(ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, aProcessID));
+  if (aProcessID == CONTENT_PROCESS_ID_UNKNOWN) {
+    aProcessID = InSandbox() ? ContentChild::GetSingleton()->GetID() :
+                               CONTENT_PROCESS_ID_MAIN;
+  }
+
+  PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust,
+                                    aHiddenAdjust, aProcessID));
 }
 
 void
 GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
 }
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -10,16 +10,17 @@
 #include "mozilla/hal_sandbox/PHal.h"
 #include "base/basictypes.h"
 #include "mozilla/Types.h"
 #include "nsTArray.h"
 #include "prlog.h"
 #include "mozilla/dom/battery/Types.h"
 #include "mozilla/dom/network/Types.h"
 #include "mozilla/dom/power/Types.h"
+#include "mozilla/dom/ContentParent.h"
 #include "mozilla/hal_sandbox/PHal.h"
 #include "mozilla/dom/ScreenOrientation.h"
 
 /*
  * Hal.h contains the public Hal API.
  *
  * By default, this file defines its functions in the hal namespace, but if
  * MOZ_HAL_NAMESPACE is defined, we'll define our functions in that namespace.
@@ -335,36 +336,35 @@ void RegisterWakeLockObserver(WakeLockOb
 
 /**
  * Inform the wake lock backend a wake lock observer unregistered.
  * @param aWakeLockObserver The observer that should be removed.
  */
 void UnregisterWakeLockObserver(WakeLockObserver* aObserver);
 
 /**
- * Adjust the wake lock counts.
+ * Adjust a wake lock's counts on behalf of a given process.
+ *
+ * In most cases, you shouldn't need to pass the aProcessID argument; the
+ * default of CONTENT_PROCESS_ID_UNKNOWN is probably what you want.
+ *
  * @param aTopic        lock topic
  * @param aLockAdjust   to increase or decrease active locks
  * @param aHiddenAdjust to increase or decrease hidden locks
+ * @param aProcessID    indicates which process we're modifying the wake lock
+ *                      on behalf of.  It is interpreted as
+ *
+ *                      CONTENT_PROCESS_ID_UNKNOWN: The current process
+ *                      CONTENT_PROCESS_ID_MAIN: The root process
+ *                      X: The process with ContentChild::GetID() == X
  */
 void ModifyWakeLock(const nsAString &aTopic,
                     hal::WakeLockControl aLockAdjust,
-                    hal::WakeLockControl aHiddenAdjust);
-
-/**
- * Adjust the wake lock counts. Do not call this function directly.
- * @param aTopic        lock topic
- * @param aLockAdjust   to increase or decrease active locks
- * @param aHiddenAdjust to increase or decrease hidden locks
- * @param aProcessID    unique id per-ContentChild or 0 for chrome
- */
-void ModifyWakeLockInternal(const nsAString &aTopic,
-                            hal::WakeLockControl aLockAdjust,
-                            hal::WakeLockControl aHiddenAdjust,
-                            uint64_t aProcessID);
+                    hal::WakeLockControl aHiddenAdjust,
+                    uint64_t aProcessID = CONTENT_PROCESS_ID_UNKNOWN);
 
 /**
  * Query the wake lock numbers of aTopic.
  * @param aTopic        lock topic
  * @param aWakeLockInfo wake lock numbers
  */
 void GetWakeLockInfo(const nsAString &aTopic, hal::WakeLockInformation *aWakeLockInfo);
 
--- a/hal/HalTypes.h
+++ b/hal/HalTypes.h
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #ifndef mozilla_hal_Types_h
 #define mozilla_hal_Types_h
 
 #include "IPCMessageUtils.h"
+#include "Observer.h"
 
 namespace mozilla {
 namespace hal {
 
 /**
  * XXX
  */
 const uint64_t CONTENT_PROCESS_ID_UNKNOWN = uint64_t(-1);
--- a/hal/HalWakeLock.cpp
+++ b/hal/HalWakeLock.cpp
@@ -2,16 +2,17 @@
 /* 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/Hal.h"
 #include "mozilla/HalWakeLock.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/dom/ContentParent.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIPropertyBag2.h"
 #include "nsObserverService.h"
 
 using namespace mozilla::hal;
 
@@ -39,16 +40,17 @@ namespace hal_impl {
 namespace {
 struct LockCount {
   LockCount()
     : numLocks(0)
     , numHidden(0)
   {}
   uint32_t numLocks;
   uint32_t numHidden;
+  nsTArray<uint64_t> processes;
 };
 typedef nsDataHashtable<nsUint64HashKey, LockCount> ProcessLockTable;
 typedef nsClassHashtable<nsStringHashKey, ProcessLockTable> LockTable;
 
 static int sActiveListeners = 0;
 static StaticAutoPtr<LockTable> sLockTable;
 static bool sInitialized = false;
 static bool sIsShuttingDown = false;
@@ -57,16 +59,21 @@ static PLDHashOperator
 CountWakeLocks(const uint64_t& aKey, LockCount aCount, void* aUserArg)
 {
   MOZ_ASSERT(aUserArg);
 
   LockCount* totalCount = static_cast<LockCount*>(aUserArg);
   totalCount->numLocks += aCount.numLocks;
   totalCount->numHidden += aCount.numHidden;
 
+  // This is linear in the number of processes, but that should be small.
+  if (!totalCount->processes.Contains(aKey)) {
+    totalCount->processes.AppendElement(aKey);
+  }
+
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
 RemoveChildFromList(const nsAString& aKey, nsAutoPtr<ProcessLockTable>& aTable,
                     void* aUserArg)
 {
   MOZ_ASSERT(aUserArg);
@@ -168,22 +175,23 @@ EnableWakeLockNotifications()
 
 void
 DisableWakeLockNotifications()
 {
   sActiveListeners--;
 }
 
 void
-ModifyWakeLockInternal(const nsAString& aTopic,
-                       hal::WakeLockControl aLockAdjust,
-                       hal::WakeLockControl aHiddenAdjust,
-                       uint64_t aProcessID)
+ModifyWakeLock(const nsAString& aTopic,
+               hal::WakeLockControl aLockAdjust,
+               hal::WakeLockControl aHiddenAdjust,
+               uint64_t aProcessID)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aProcessID != CONTENT_PROCESS_ID_UNKNOWN);
 
   if (sIsShuttingDown) {
     return;
   }
   if (!sInitialized) {
     Init();
   }
 
@@ -222,19 +230,17 @@ ModifyWakeLockInternal(const nsAString& 
   if (!totalCount.numLocks) {
     sLockTable->Remove(aTopic);
   }
 
   WakeLockState newState = ComputeWakeLockState(totalCount.numLocks, totalCount.numHidden);
 
   if (sActiveListeners && oldState != newState) {
     WakeLockInformation info;
-    info.numLocks() = totalCount.numLocks;
-    info.numHidden() = totalCount.numHidden;
-    info.topic() = aTopic;
+    GetWakeLockInfo(aTopic, &info);
     NotifyWakeLockChange(info);
   }
 }
 
 void
 GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
 {
   if (sIsShuttingDown) {
@@ -251,13 +257,14 @@ GetWakeLockInfo(const nsAString& aTopic,
     aWakeLockInfo->numHidden() = 0;
     aWakeLockInfo->topic() = aTopic;
     return;
   }
   LockCount totalCount;
   table->EnumerateRead(CountWakeLocks, &totalCount);
   aWakeLockInfo->numLocks() = totalCount.numLocks;
   aWakeLockInfo->numHidden() = totalCount.numHidden;
+  aWakeLockInfo->lockingProcesses() = totalCount.processes;
   aWakeLockInfo->topic() = aTopic;
 }
 
 } // hal_impl
 } // mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -61,16 +61,17 @@ struct NetworkInformation {
 struct SwitchEvent {
   SwitchDevice device;
   SwitchState status;
 };
 
 struct WakeLockInformation {
   uint32_t numLocks;
   uint32_t numHidden;
+  uint64_t[] lockingProcesses;
   nsString topic;
 };
 
 struct ScreenConfiguration {
   nsIntRect rect;
   ScreenOrientation orientation;
   uint32_t colorDepth;
   uint32_t pixelDepth;
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -271,21 +271,22 @@ EnableWakeLockNotifications()
 
 void
 DisableWakeLockNotifications()
 {
   Hal()->SendDisableWakeLockNotifications();
 }
 
 void
-ModifyWakeLockInternal(const nsAString &aTopic,
-                       WakeLockControl aLockAdjust,
-                       WakeLockControl aHiddenAdjust,
-                       uint64_t aProcessID)
+ModifyWakeLock(const nsAString &aTopic,
+               WakeLockControl aLockAdjust,
+               WakeLockControl aHiddenAdjust,
+               uint64_t aProcessID)
 {
+  MOZ_ASSERT(aProcessID != CONTENT_PROCESS_ID_UNKNOWN);
   Hal()->SendModifyWakeLock(nsString(aTopic), aLockAdjust, aHiddenAdjust, aProcessID);
 }
 
 void
 GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
 {
   Hal()->SendGetWakeLockInfo(nsString(aTopic), aWakeLockInfo);
 }
@@ -707,18 +708,20 @@ public:
   }
 
   virtual bool
   RecvModifyWakeLock(const nsString& aTopic,
                      const WakeLockControl& aLockAdjust,
                      const WakeLockControl& aHiddenAdjust,
                      const uint64_t& aProcessID) MOZ_OVERRIDE
   {
+    MOZ_ASSERT(aProcessID != CONTENT_PROCESS_ID_UNKNOWN);
+
     // We allow arbitrary content to use wake locks.
-    hal::ModifyWakeLockInternal(aTopic, aLockAdjust, aHiddenAdjust, aProcessID);
+    hal::ModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust, aProcessID);
     return true;
   }
 
   virtual bool
   RecvEnableWakeLockNotifications() MOZ_OVERRIDE
   {
     // We allow arbitrary content to use wake locks.
     hal::RegisterWakeLockObserver(this);