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 121965 6480e7d33c5a02b0ff083188b7976066b5b5dc40
parent 121964 fb43c5972c2c3973ef75cac87704d8242988a526
child 121966 691f0a62b261e89137d8a5de1191e4d1578a4acc
push id1357
push userttaubert@mozilla.com
push dateSun, 17 Feb 2013 22:57:19 +0000
treeherderfx-team@de56ae61946d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs836654
milestone21.0a1
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);