Bug 793759 - Implement HalChild::ActorDestroy and prevent HalChild calls to HalParent after ActorDestroy is called. r=cjones
authorSteven Lee <slee@mozilla.com>
Sat, 06 Oct 2012 21:53:22 -0400
changeset 116407 834fb95232af9f4e02e365f86d320c662091c0fe
parent 116406 ecd4c43042193c599d446d712ac265319b70dc33
child 116408 7be4e7680b42ebb8dafbb8a84b252862d78a3175
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs793759
milestone18.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 793759 - Implement HalChild::ActorDestroy and prevent HalChild calls to HalParent after ActorDestroy is called. r=cjones
hal/Hal.cpp
hal/HalInternal.h
hal/sandbox/SandboxHal.cpp
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -27,25 +27,30 @@
 #define getpid _getpid
 #endif
 
 using namespace mozilla::services;
 
 #define PROXY_IF_SANDBOXED(_call)                 \
   do {                                            \
     if (InSandbox()) {                            \
-      hal_sandbox::_call;                         \
+      if (!hal_sandbox::IsHalChildLive()) {  \
+        hal_sandbox::_call;                       \
+      }                                           \
     } else {                                      \
       hal_impl::_call;                            \
     }                                             \
   } while (0)
 
-#define RETURN_PROXY_IF_SANDBOXED(_call)          \
+#define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
   do {                                            \
     if (InSandbox()) {                            \
+      if (hal_sandbox::IsHalChildLive()) {   \
+        return defValue;                          \
+      }                                           \
       return hal_sandbox::_call;                  \
     } else {                                      \
       return hal_impl::_call;                     \
     }                                             \
   } while (0)
 
 namespace mozilla {
 namespace hal {
@@ -358,63 +363,63 @@ NotifyBatteryChange(const BatteryInforma
   AssertMainThread();
   sBatteryObservers.CacheInformation(aInfo);
   sBatteryObservers.BroadcastCachedInformation();
 }
 
 bool GetScreenEnabled()
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled());
+  RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
 }
 
 void SetScreenEnabled(bool enabled)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(SetScreenEnabled(enabled));
 }
 
 bool GetCpuSleepAllowed()
 {
   // Generally for interfaces that are accessible by normal web content
   // we should cache the result and be notified on state changes, like
   // what the battery API does. But since this is only used by
   // privileged interface, the synchronous getter is OK here.
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed());
+  RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
 }
 
 void SetCpuSleepAllowed(bool allowed)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed));
 }
 
 double GetScreenBrightness()
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness());
+  RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
 }
 
 void SetScreenBrightness(double brightness)
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
 }
 
 bool SetLight(LightType light, const hal::LightConfiguration& aConfig)
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig));
+  RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig), false);
 }
 
 bool GetLight(LightType light, hal::LightConfiguration* aConfig)
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig));
+  RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig), false);
 }
 
 class SystemTimeObserversManager : public ObserversManager<SystemTimeChange>
 {
 protected:
   void EnableNotifications() {
     PROXY_IF_SANDBOXED(EnableSystemTimeChangeNotifications());
   }
@@ -459,17 +464,17 @@ SetTimezone(const nsCString& aTimezoneSp
   AssertMainThread();
   PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
 }
 
 nsCString
 GetTimezone()
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetTimezone());
+  RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
 }
 
 void
 EnableSensorNotifications(SensorType aSensor) {
   AssertMainThread();
   PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
 }
 
@@ -650,17 +655,17 @@ NotifyScreenConfigurationChange(const Sc
   sScreenConfigurationObservers.CacheInformation(aScreenConfiguration);
   sScreenConfigurationObservers.BroadcastCachedInformation();
 }
 
 bool
 LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation));
+  RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), false);
 }
 
 void
 UnlockScreenOrientation()
 {
   AssertMainThread();
   PROXY_IF_SANDBOXED(UnlockScreenOrientation());
 }
@@ -675,17 +680,17 @@ void
 DisableSwitchNotifications(hal::SwitchDevice aDevice) {
   AssertMainThread();
   PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
 }
 
 hal::SwitchState GetCurrentSwitchState(hal::SwitchDevice aDevice)
 {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice));
+  RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
 }
 
 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
 
 static SwitchObserverList *sSwitchObserverLists = NULL;
 
 static SwitchObserverList&
 GetSwitchObserverList(hal::SwitchDevice aDevice) {
@@ -753,17 +758,17 @@ static AlarmObserver* sAlarmObserver;
 
 bool
 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
 {
   MOZ_ASSERT(!InSandbox());
   MOZ_ASSERT(!sAlarmObserver);
 
   sAlarmObserver = aObserver;
-  RETURN_PROXY_IF_SANDBOXED(EnableAlarm());
+  RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
 }
 
 void
 UnregisterTheOneAlarmObserver()
 {
   if (sAlarmObserver) {
     sAlarmObserver = nullptr;
     PROXY_IF_SANDBOXED(DisableAlarm());
@@ -778,17 +783,17 @@ NotifyAlarmFired()
   }
 }
 
 bool
 SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
 {
   // It's pointless to program an alarm nothing is going to observe ...
   MOZ_ASSERT(sAlarmObserver);
-  RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds));
+  RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds), false);
 }
 
 void
 SetProcessPriority(int aPid, ProcessPriority aPriority)
 {
   PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
 }
 
@@ -851,29 +856,29 @@ void
 SetFMRadioFrequency(const uint32_t aFrequency) {
   AssertMainThread();
   PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
 }
 
 uint32_t
 GetFMRadioFrequency() {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency());
+  RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
 }
 
 bool
 IsFMRadioOn() {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn());
+  RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
 }
 
 uint32_t
 GetFMRadioSignalStrength() {
   AssertMainThread();
-  RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength());
+  RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
 }
 
 void
 CancelFMRadioSeek() {
   AssertMainThread();
   PROXY_IF_SANDBOXED(CancelFMRadioSeek());
 }
 
--- a/hal/HalInternal.h
+++ b/hal/HalInternal.h
@@ -79,12 +79,13 @@ void DisableAlarm();
  */
 void EnableSystemTimeChangeNotifications();
 
 /**
  * Disable system time change notifications from the backend.
  */
 void DisableSystemTimeChangeNotifications();
 
+bool IsHalChildLive();
 } // namespace MOZ_HAL_NAMESPACE
 } // namespace mozilla
 
 #endif  // mozilla_HalInternal_h
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -20,16 +20,24 @@
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 namespace mozilla {
 namespace hal_sandbox {
 
+static bool sHalChildIsLive = false;
+
+bool
+IsHalChildLive()
+{
+  return sHalChildIsLive;
+}
+
 static PHalChild* sHal;
 static PHalChild*
 Hal()
 {
   if (!sHal) {
     sHal = ContentChild::GetSingleton()->SendPHalConstructor();
   }
   return sHal;
@@ -391,16 +399,17 @@ public:
     hal::UnregisterBatteryObserver(this);
     hal::UnregisterNetworkObserver(this);
     hal::UnregisterScreenConfigurationObserver(this);
     for (int32_t sensor = SENSOR_UNKNOWN + 1;
          sensor < NUM_SENSOR_TYPE; ++sensor) {
       hal::UnregisterSensorObserver(SensorType(sensor), this);
     }
     hal::UnregisterWakeLockObserver(this);
+    hal::UnregisterSystemTimeChangeObserver(this);
   }
 
   virtual bool
   RecvVibrate(const InfallibleTArray<unsigned int>& pattern,
               const InfallibleTArray<uint64_t> &id,
               PBrowserParent *browserParent) MOZ_OVERRIDE
   {
     // We give all content vibration permission.
@@ -832,16 +841,22 @@ public:
     }
     hal::CancelFMRadioSeek();
     return true;
   }
 };
 
 class HalChild : public PHalChild {
 public:
+  virtual void
+  ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE
+  {
+    sHalChildIsLive = true;
+  }
+
   virtual bool
   RecvNotifyBatteryChange(const BatteryInformation& aBatteryInfo) MOZ_OVERRIDE {
     hal::NotifyBatteryChange(aBatteryInfo);
     return true;
   }
 
   virtual bool
   RecvNotifySensorChange(const hal::SensorData &aSensorData) MOZ_OVERRIDE;