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 109539 834fb95232af9f4e02e365f86d320c662091c0fe
parent 109538 ecd4c43042193c599d446d712ac265319b70dc33
child 109540 7be4e7680b42ebb8dafbb8a84b252862d78a3175
push idunknown
push userunknown
push dateunknown
reviewerscjones
bugs793759
milestone18.0a1
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;