LCOV - code coverage report
Current view: top level - hal - Hal.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 69 453 15.2 %
Date: 2017-07-14 16:53:18 Functions: 28 159 17.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et ft=cpp : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "Hal.h"
       8             : 
       9             : #include "HalImpl.h"
      10             : #include "HalLog.h"
      11             : #include "HalSandbox.h"
      12             : #include "nsIDOMDocument.h"
      13             : #include "nsIDOMWindow.h"
      14             : #include "nsIDocument.h"
      15             : #include "nsIDocShell.h"
      16             : #include "nsITabChild.h"
      17             : #include "nsIWebNavigation.h"
      18             : #include "nsThreadUtils.h"
      19             : #include "nsXULAppAPI.h"
      20             : #include "nsPIDOMWindow.h"
      21             : #include "nsJSUtils.h"
      22             : #include "mozilla/ClearOnShutdown.h"
      23             : #include "mozilla/Observer.h"
      24             : #include "mozilla/Services.h"
      25             : #include "mozilla/StaticPtr.h"
      26             : #include "mozilla/dom/ContentChild.h"
      27             : #include "mozilla/dom/ContentParent.h"
      28             : #include "mozilla/dom/ScreenOrientation.h"
      29             : #include "WindowIdentifier.h"
      30             : 
      31             : #ifdef XP_WIN
      32             : #include <process.h>
      33             : #define getpid _getpid
      34             : #endif
      35             : 
      36             : using namespace mozilla::services;
      37             : using namespace mozilla::dom;
      38             : 
      39             : #define PROXY_IF_SANDBOXED(_call)                 \
      40             :   do {                                            \
      41             :     if (InSandbox()) {                            \
      42             :       if (!hal_sandbox::HalChildDestroyed()) {    \
      43             :         hal_sandbox::_call;                       \
      44             :       }                                           \
      45             :     } else {                                      \
      46             :       hal_impl::_call;                            \
      47             :     }                                             \
      48             :   } while (0)
      49             : 
      50             : #define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
      51             :   do {                                            \
      52             :     if (InSandbox()) {                            \
      53             :       if (hal_sandbox::HalChildDestroyed()) {     \
      54             :         return defValue;                          \
      55             :       }                                           \
      56             :       return hal_sandbox::_call;                  \
      57             :     } else {                                      \
      58             :       return hal_impl::_call;                     \
      59             :     }                                             \
      60             :   } while (0)
      61             : 
      62             : namespace mozilla {
      63             : namespace hal {
      64             : 
      65             : mozilla::LogModule *
      66           1 : GetHalLog()
      67             : {
      68             :   static mozilla::LazyLogModule sHalLog("hal");
      69           1 :   return sHalLog;
      70             : }
      71             : 
      72             : namespace {
      73             : 
      74             : void
      75          76 : AssertMainThread()
      76             : {
      77          76 :   MOZ_ASSERT(NS_IsMainThread());
      78          76 : }
      79             : 
      80             : bool
      81           7 : InSandbox()
      82             : {
      83           7 :   return GeckoProcessType_Content == XRE_GetProcessType();
      84             : }
      85             : 
      86             : void
      87           0 : AssertMainProcess()
      88             : {
      89           0 :   MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
      90           0 : }
      91             : 
      92             : #if !defined(MOZ_WIDGET_GONK)
      93             : 
      94             : bool
      95           0 : WindowIsActive(nsPIDOMWindowInner* aWindow)
      96             : {
      97           0 :   nsIDocument* document = aWindow->GetDoc();
      98           0 :   NS_ENSURE_TRUE(document, false);
      99             : 
     100           0 :   return !document->Hidden();
     101             : }
     102             : 
     103             : #endif // !defined(MOZ_WIDGET_GONK)
     104             : 
     105           3 : StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
     106             : 
     107           0 : void InitLastIDToVibrate()
     108             : {
     109           0 :   gLastIDToVibrate = new WindowIdentifier::IDArrayType();
     110           0 :   ClearOnShutdown(&gLastIDToVibrate);
     111           0 : }
     112             : 
     113             : } // namespace
     114             : 
     115             : void
     116           0 : Vibrate(const nsTArray<uint32_t>& pattern, nsPIDOMWindowInner* window)
     117             : {
     118           0 :   Vibrate(pattern, WindowIdentifier(window));
     119           0 : }
     120             : 
     121             : void
     122           0 : Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
     123             : {
     124           0 :   AssertMainThread();
     125             : 
     126             : #if !defined(MOZ_WIDGET_GONK)
     127             :   // Only active windows may start vibrations.  If |id| hasn't gone
     128             :   // through the IPC layer -- that is, if our caller is the outside
     129             :   // world, not hal_proxy -- check whether the window is active.  If
     130             :   // |id| has gone through IPC, don't check the window's visibility;
     131             :   // only the window corresponding to the bottommost process has its
     132             :   // visibility state set correctly.
     133           0 :   if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
     134           0 :     HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
     135           0 :     return;
     136             :   }
     137             : #endif // !defined(MOZ_WIDGET_GONK)
     138             : 
     139           0 :   if (!InSandbox()) {
     140           0 :     if (!gLastIDToVibrate) {
     141           0 :       InitLastIDToVibrate();
     142             :     }
     143           0 :     *gLastIDToVibrate = id.AsArray();
     144             :   }
     145             : 
     146             :   // Don't forward our ID if we are not in the sandbox, because hal_impl
     147             :   // doesn't need it, and we don't want it to be tempted to read it.  The
     148             :   // empty identifier will assert if it's used.
     149           0 :   PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
     150             : }
     151             : 
     152             : void
     153           0 : CancelVibrate(nsPIDOMWindowInner* window)
     154             : {
     155           0 :   CancelVibrate(WindowIdentifier(window));
     156           0 : }
     157             : 
     158             : void
     159           0 : CancelVibrate(const WindowIdentifier &id)
     160             : {
     161           0 :   AssertMainThread();
     162             : 
     163             :   // Although only active windows may start vibrations, a window may
     164             :   // cancel its own vibration even if it's no longer active.
     165             :   //
     166             :   // After a window is marked as inactive, it sends a CancelVibrate
     167             :   // request.  We want this request to cancel a playing vibration
     168             :   // started by that window, so we certainly don't want to reject the
     169             :   // cancellation request because the window is now inactive.
     170             :   //
     171             :   // But it could be the case that, after this window became inactive,
     172             :   // some other window came along and started a vibration.  We don't
     173             :   // want this window's cancellation request to cancel that window's
     174             :   // actively-playing vibration!
     175             :   //
     176             :   // To solve this problem, we keep track of the id of the last window
     177             :   // to start a vibration, and only accepts cancellation requests from
     178             :   // the same window.  All other cancellation requests are ignored.
     179             : 
     180           0 :   if (InSandbox() || (gLastIDToVibrate && *gLastIDToVibrate == id.AsArray())) {
     181             :     // Don't forward our ID if we are not in the sandbox, because hal_impl
     182             :     // doesn't need it, and we don't want it to be tempted to read it.  The
     183             :     // empty identifier will assert if it's used.
     184           0 :     PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id : WindowIdentifier()));
     185             :   }
     186           0 : }
     187             : 
     188             : template <class InfoType>
     189           5 : class ObserversManager
     190             : {
     191             : public:
     192           6 :   void AddObserver(Observer<InfoType>* aObserver) {
     193           6 :     if (!mObservers) {
     194           5 :       mObservers = new mozilla::ObserverList<InfoType>();
     195             :     }
     196             : 
     197           6 :     mObservers->AddObserver(aObserver);
     198             : 
     199           6 :     if (mObservers->Length() == 1) {
     200           5 :       EnableNotifications();
     201             :     }
     202           6 :   }
     203             : 
     204           0 :   void RemoveObserver(Observer<InfoType>* aObserver) {
     205           0 :     bool removed = mObservers && mObservers->RemoveObserver(aObserver);
     206           0 :     if (!removed) {
     207           0 :       return;
     208             :     }
     209             : 
     210           0 :     if (mObservers->Length() == 0) {
     211           0 :       DisableNotifications();
     212             : 
     213           0 :       OnNotificationsDisabled();
     214             : 
     215           0 :       delete mObservers;
     216           0 :       mObservers = nullptr;
     217             :     }
     218             :   }
     219             : 
     220           0 :   void BroadcastInformation(const InfoType& aInfo) {
     221             :     // It is possible for mObservers to be nullptr here on some platforms,
     222             :     // because a call to BroadcastInformation gets queued up asynchronously
     223             :     // while RemoveObserver is running (and before the notifications are
     224             :     // disabled). The queued call can then get run after mObservers has
     225             :     // been nulled out. See bug 757025.
     226           0 :     if (!mObservers) {
     227           0 :       return;
     228             :     }
     229           0 :     mObservers->Broadcast(aInfo);
     230             :   }
     231             : 
     232             : protected:
     233             :   virtual void EnableNotifications() = 0;
     234             :   virtual void DisableNotifications() = 0;
     235           0 :   virtual void OnNotificationsDisabled() {}
     236             : 
     237             : private:
     238             :   mozilla::ObserverList<InfoType>* mObservers;
     239             : };
     240             : 
     241             : template <class InfoType>
     242           1 : class CachingObserversManager : public ObserversManager<InfoType>
     243             : {
     244             : public:
     245          34 :   InfoType GetCurrentInformation() {
     246          34 :     if (mHasValidCache) {
     247          33 :       return mInfo;
     248             :     }
     249             : 
     250           1 :     GetCurrentInformationInternal(&mInfo);
     251           1 :     mHasValidCache = true;
     252           1 :     return mInfo;
     253             :   }
     254             : 
     255           0 :   void CacheInformation(const InfoType& aInfo) {
     256           0 :     mHasValidCache = true;
     257           0 :     mInfo = aInfo;
     258           0 :   }
     259             : 
     260           0 :   void BroadcastCachedInformation() {
     261           0 :     this->BroadcastInformation(mInfo);
     262           0 :   }
     263             : 
     264             : protected:
     265             :   virtual void GetCurrentInformationInternal(InfoType*) = 0;
     266             : 
     267           0 :   void OnNotificationsDisabled() override {
     268           0 :     mHasValidCache = false;
     269           0 :   }
     270             : 
     271             : private:
     272             :   InfoType                mInfo;
     273             :   bool                    mHasValidCache;
     274             : };
     275             : 
     276           0 : class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
     277             : {
     278             : protected:
     279           0 :   void EnableNotifications() override {
     280           0 :     PROXY_IF_SANDBOXED(EnableBatteryNotifications());
     281           0 :   }
     282             : 
     283           0 :   void DisableNotifications() override {
     284           0 :     PROXY_IF_SANDBOXED(DisableBatteryNotifications());
     285           0 :   }
     286             : 
     287           0 :   void GetCurrentInformationInternal(BatteryInformation* aInfo) override {
     288           0 :     PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
     289           0 :   }
     290             : };
     291             : 
     292             : static BatteryObserversManager&
     293           0 : BatteryObservers()
     294             : {
     295           0 :   static BatteryObserversManager sBatteryObservers;
     296           0 :   AssertMainThread();
     297           0 :   return sBatteryObservers;
     298             : }
     299             : 
     300           0 : class NetworkObserversManager : public CachingObserversManager<NetworkInformation>
     301             : {
     302             : protected:
     303           0 :   void EnableNotifications() override {
     304           0 :     PROXY_IF_SANDBOXED(EnableNetworkNotifications());
     305           0 :   }
     306             : 
     307           0 :   void DisableNotifications() override {
     308           0 :     PROXY_IF_SANDBOXED(DisableNetworkNotifications());
     309           0 :   }
     310             : 
     311           0 :   void GetCurrentInformationInternal(NetworkInformation* aInfo) override {
     312           0 :     PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
     313           0 :   }
     314             : };
     315             : 
     316             : static NetworkObserversManager&
     317           0 : NetworkObservers()
     318             : {
     319           0 :   static NetworkObserversManager sNetworkObservers;
     320           0 :   AssertMainThread();
     321           0 :   return sNetworkObservers;
     322             : }
     323             : 
     324           1 : class WakeLockObserversManager : public ObserversManager<WakeLockInformation>
     325             : {
     326             : protected:
     327           1 :   void EnableNotifications() override {
     328           1 :     PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
     329           1 :   }
     330             : 
     331           0 :   void DisableNotifications() override {
     332           0 :     PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
     333           0 :   }
     334             : };
     335             : 
     336             : static WakeLockObserversManager&
     337           1 : WakeLockObservers()
     338             : {
     339           1 :   static WakeLockObserversManager sWakeLockObservers;
     340           1 :   AssertMainThread();
     341           1 :   return sWakeLockObservers;
     342             : }
     343             : 
     344           1 : class ScreenConfigurationObserversManager : public CachingObserversManager<ScreenConfiguration>
     345             : {
     346             : protected:
     347           1 :   void EnableNotifications() override {
     348           1 :     PROXY_IF_SANDBOXED(EnableScreenConfigurationNotifications());
     349           1 :   }
     350             : 
     351           0 :   void DisableNotifications() override {
     352           0 :     PROXY_IF_SANDBOXED(DisableScreenConfigurationNotifications());
     353           0 :   }
     354             : 
     355           1 :   void GetCurrentInformationInternal(ScreenConfiguration* aInfo) override {
     356           1 :     PROXY_IF_SANDBOXED(GetCurrentScreenConfiguration(aInfo));
     357           1 :   }
     358             : };
     359             : 
     360             : static ScreenConfigurationObserversManager&
     361          35 : ScreenConfigurationObservers()
     362             : {
     363          35 :   AssertMainThread();
     364          35 :   static ScreenConfigurationObserversManager sScreenConfigurationObservers;
     365          35 :   return sScreenConfigurationObservers;
     366             : }
     367             : 
     368             : void
     369           0 : RegisterBatteryObserver(BatteryObserver* aObserver)
     370             : {
     371           0 :   AssertMainThread();
     372           0 :   BatteryObservers().AddObserver(aObserver);
     373           0 : }
     374             : 
     375             : void
     376           0 : UnregisterBatteryObserver(BatteryObserver* aObserver)
     377             : {
     378           0 :   AssertMainThread();
     379           0 :   BatteryObservers().RemoveObserver(aObserver);
     380           0 : }
     381             : 
     382             : void
     383           0 : GetCurrentBatteryInformation(BatteryInformation* aInfo)
     384             : {
     385           0 :   AssertMainThread();
     386           0 :   *aInfo = BatteryObservers().GetCurrentInformation();
     387           0 : }
     388             : 
     389             : void
     390           0 : NotifyBatteryChange(const BatteryInformation& aInfo)
     391             : {
     392           0 :   AssertMainThread();
     393           0 :   BatteryObservers().CacheInformation(aInfo);
     394           0 :   BatteryObservers().BroadcastCachedInformation();
     395           0 : }
     396             : 
     397           0 : bool GetScreenEnabled()
     398             : {
     399           0 :   AssertMainThread();
     400           0 :   RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
     401             : }
     402             : 
     403           0 : void SetScreenEnabled(bool aEnabled)
     404             : {
     405           0 :   AssertMainThread();
     406           0 :   PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled));
     407           0 : }
     408             : 
     409           0 : bool GetKeyLightEnabled()
     410             : {
     411           0 :   AssertMainThread();
     412           0 :   RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
     413             : }
     414             : 
     415           0 : void SetKeyLightEnabled(bool aEnabled)
     416             : {
     417           0 :   AssertMainThread();
     418           0 :   PROXY_IF_SANDBOXED(SetKeyLightEnabled(aEnabled));
     419           0 : }
     420             : 
     421           0 : bool GetCpuSleepAllowed()
     422             : {
     423             :   // Generally for interfaces that are accessible by normal web content
     424             :   // we should cache the result and be notified on state changes, like
     425             :   // what the battery API does. But since this is only used by
     426             :   // privileged interface, the synchronous getter is OK here.
     427           0 :   AssertMainThread();
     428           0 :   RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
     429             : }
     430             : 
     431           0 : void SetCpuSleepAllowed(bool aAllowed)
     432             : {
     433           0 :   AssertMainThread();
     434           0 :   PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed));
     435           0 : }
     436             : 
     437           0 : double GetScreenBrightness()
     438             : {
     439           0 :   AssertMainThread();
     440           0 :   RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
     441             : }
     442             : 
     443           0 : void SetScreenBrightness(double aBrightness)
     444             : {
     445           0 :   AssertMainThread();
     446           0 :   PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness, 0.0, 1.0)));
     447           0 : }
     448             : 
     449           0 : class SystemClockChangeObserversManager : public ObserversManager<int64_t>
     450             : {
     451             : protected:
     452           0 :   void EnableNotifications() override {
     453           0 :     PROXY_IF_SANDBOXED(EnableSystemClockChangeNotifications());
     454           0 :   }
     455             : 
     456           0 :   void DisableNotifications() override {
     457           0 :     PROXY_IF_SANDBOXED(DisableSystemClockChangeNotifications());
     458           0 :   }
     459             : };
     460             : 
     461             : static SystemClockChangeObserversManager&
     462           0 : SystemClockChangeObservers()
     463             : {
     464           0 :   static SystemClockChangeObserversManager sSystemClockChangeObservers;
     465           0 :   AssertMainThread();
     466           0 :   return sSystemClockChangeObservers;
     467             : }
     468             : 
     469             : void
     470           0 : RegisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
     471             : {
     472           0 :   AssertMainThread();
     473           0 :   SystemClockChangeObservers().AddObserver(aObserver);
     474           0 : }
     475             : 
     476             : void
     477           0 : UnregisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
     478             : {
     479           0 :   AssertMainThread();
     480           0 :   SystemClockChangeObservers().RemoveObserver(aObserver);
     481           0 : }
     482             : 
     483             : void
     484           0 : NotifySystemClockChange(const int64_t& aClockDeltaMS)
     485             : {
     486           0 :   SystemClockChangeObservers().BroadcastInformation(aClockDeltaMS);
     487           0 : }
     488             : 
     489           3 : class SystemTimezoneChangeObserversManager : public ObserversManager<SystemTimezoneChangeInformation>
     490             : {
     491             : protected:
     492           3 :   void EnableNotifications() override {
     493           3 :     PROXY_IF_SANDBOXED(EnableSystemTimezoneChangeNotifications());
     494           3 :   }
     495             : 
     496           0 :   void DisableNotifications() override {
     497           0 :     PROXY_IF_SANDBOXED(DisableSystemTimezoneChangeNotifications());
     498           0 :   }
     499             : };
     500             : 
     501             : static SystemTimezoneChangeObserversManager&
     502           4 : SystemTimezoneChangeObservers()
     503             : {
     504           4 :   static SystemTimezoneChangeObserversManager sSystemTimezoneChangeObservers;
     505           4 :   return sSystemTimezoneChangeObservers;
     506             : }
     507             : 
     508             : void
     509           4 : RegisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
     510             : {
     511           4 :   AssertMainThread();
     512           4 :   SystemTimezoneChangeObservers().AddObserver(aObserver);
     513           4 : }
     514             : 
     515             : void
     516           0 : UnregisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
     517             : {
     518           0 :   AssertMainThread();
     519           0 :   SystemTimezoneChangeObservers().RemoveObserver(aObserver);
     520           0 : }
     521             : 
     522             : void
     523           0 : NotifySystemTimezoneChange(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
     524             : {
     525           0 :   nsJSUtils::ResetTimeZone();
     526           0 :   SystemTimezoneChangeObservers().BroadcastInformation(aSystemTimezoneChangeInfo);
     527           0 : }
     528             : 
     529             : void
     530           0 : AdjustSystemClock(int64_t aDeltaMilliseconds)
     531             : {
     532           0 :   AssertMainThread();
     533           0 :   PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
     534           0 : }
     535             : 
     536             : void
     537           0 : SetTimezone(const nsCString& aTimezoneSpec)
     538             : {
     539           0 :   AssertMainThread();
     540           0 :   PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
     541           0 : }
     542             : 
     543             : int32_t
     544           0 : GetTimezoneOffset()
     545             : {
     546           0 :   AssertMainThread();
     547           0 :   RETURN_PROXY_IF_SANDBOXED(GetTimezoneOffset(), 0);
     548             : }
     549             : 
     550             : nsCString
     551           0 : GetTimezone()
     552             : {
     553           0 :   AssertMainThread();
     554           0 :   RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
     555             : }
     556             : 
     557             : void
     558           0 : EnableSensorNotifications(SensorType aSensor) {
     559           0 :   AssertMainThread();
     560           0 :   PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
     561           0 : }
     562             : 
     563             : void
     564           0 : DisableSensorNotifications(SensorType aSensor) {
     565           0 :   AssertMainThread();
     566           0 :   PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
     567           0 : }
     568             : 
     569             : typedef mozilla::ObserverList<SensorData> SensorObserverList;
     570             : static SensorObserverList* gSensorObservers = nullptr;
     571             : 
     572             : static SensorObserverList &
     573           0 : GetSensorObservers(SensorType sensor_type) {
     574           0 :   MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
     575             : 
     576           0 :   if(!gSensorObservers) {
     577           0 :     gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
     578             :   }
     579           0 :   return gSensorObservers[sensor_type];
     580             : }
     581             : 
     582             : void
     583           0 : RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
     584           0 :   SensorObserverList &observers = GetSensorObservers(aSensor);
     585             : 
     586           0 :   AssertMainThread();
     587             : 
     588           0 :   observers.AddObserver(aObserver);
     589           0 :   if(observers.Length() == 1) {
     590           0 :     EnableSensorNotifications(aSensor);
     591             :   }
     592           0 : }
     593             : 
     594             : void
     595           0 : UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
     596           0 :   AssertMainThread();
     597             : 
     598           0 :   if (!gSensorObservers) {
     599           0 :     return;
     600             :   }
     601             : 
     602           0 :   SensorObserverList &observers = GetSensorObservers(aSensor);
     603           0 :   if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
     604           0 :     return;
     605             :   }
     606           0 :   DisableSensorNotifications(aSensor);
     607             : 
     608             :   // Destroy sSensorObservers only if all observer lists are empty.
     609           0 :   for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
     610           0 :     if (gSensorObservers[i].Length() > 0) {
     611           0 :       return;
     612             :     }
     613             :   }
     614           0 :   delete [] gSensorObservers;
     615           0 :   gSensorObservers = nullptr;
     616             : }
     617             : 
     618             : void
     619           0 : NotifySensorChange(const SensorData &aSensorData) {
     620           0 :   SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
     621             : 
     622           0 :   AssertMainThread();
     623             : 
     624           0 :   observers.Broadcast(aSensorData);
     625           0 : }
     626             : 
     627             : void
     628           0 : RegisterNetworkObserver(NetworkObserver* aObserver)
     629             : {
     630           0 :   AssertMainThread();
     631           0 :   NetworkObservers().AddObserver(aObserver);
     632           0 : }
     633             : 
     634             : void
     635           0 : UnregisterNetworkObserver(NetworkObserver* aObserver)
     636             : {
     637           0 :   AssertMainThread();
     638           0 :   NetworkObservers().RemoveObserver(aObserver);
     639           0 : }
     640             : 
     641             : void
     642           0 : GetCurrentNetworkInformation(NetworkInformation* aInfo)
     643             : {
     644           0 :   AssertMainThread();
     645           0 :   *aInfo = NetworkObservers().GetCurrentInformation();
     646           0 : }
     647             : 
     648             : void
     649           0 : NotifyNetworkChange(const NetworkInformation& aInfo)
     650             : {
     651           0 :   NetworkObservers().CacheInformation(aInfo);
     652           0 :   NetworkObservers().BroadcastCachedInformation();
     653           0 : }
     654             : 
     655           0 : void Reboot()
     656             : {
     657           0 :   AssertMainProcess();
     658           0 :   AssertMainThread();
     659           0 :   PROXY_IF_SANDBOXED(Reboot());
     660           0 : }
     661             : 
     662           0 : void PowerOff()
     663             : {
     664           0 :   AssertMainProcess();
     665           0 :   AssertMainThread();
     666           0 :   PROXY_IF_SANDBOXED(PowerOff());
     667           0 : }
     668             : 
     669           0 : void StartForceQuitWatchdog(ShutdownMode aMode, int32_t aTimeoutSecs)
     670             : {
     671           0 :   AssertMainProcess();
     672           0 :   AssertMainThread();
     673           0 :   PROXY_IF_SANDBOXED(StartForceQuitWatchdog(aMode, aTimeoutSecs));
     674           0 : }
     675             : 
     676             : void
     677           1 : RegisterWakeLockObserver(WakeLockObserver* aObserver)
     678             : {
     679           1 :   AssertMainThread();
     680           1 :   WakeLockObservers().AddObserver(aObserver);
     681           1 : }
     682             : 
     683             : void
     684           0 : UnregisterWakeLockObserver(WakeLockObserver* aObserver)
     685             : {
     686           0 :   AssertMainThread();
     687           0 :   WakeLockObservers().RemoveObserver(aObserver);
     688           0 : }
     689             : 
     690             : void
     691           0 : ModifyWakeLock(const nsAString& aTopic,
     692             :                WakeLockControl aLockAdjust,
     693             :                WakeLockControl aHiddenAdjust,
     694             :                uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */)
     695             : {
     696           0 :   AssertMainThread();
     697             : 
     698           0 :   if (aProcessID == CONTENT_PROCESS_ID_UNKNOWN) {
     699           0 :     aProcessID = InSandbox() ? ContentChild::GetSingleton()->GetID() :
     700           0 :                                CONTENT_PROCESS_ID_MAIN;
     701             :   }
     702             : 
     703           0 :   PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust,
     704             :                                     aHiddenAdjust, aProcessID));
     705           0 : }
     706             : 
     707             : void
     708           0 : GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
     709             : {
     710           0 :   AssertMainThread();
     711           0 :   PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
     712           0 : }
     713             : 
     714             : void
     715           0 : NotifyWakeLockChange(const WakeLockInformation& aInfo)
     716             : {
     717           0 :   AssertMainThread();
     718           0 :   WakeLockObservers().BroadcastInformation(aInfo);
     719           0 : }
     720             : 
     721             : void
     722           1 : RegisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
     723             : {
     724           1 :   AssertMainThread();
     725           1 :   ScreenConfigurationObservers().AddObserver(aObserver);
     726           1 : }
     727             : 
     728             : void
     729           0 : UnregisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
     730             : {
     731           0 :   AssertMainThread();
     732           0 :   ScreenConfigurationObservers().RemoveObserver(aObserver);
     733           0 : }
     734             : 
     735             : void
     736          34 : GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
     737             : {
     738          34 :   AssertMainThread();
     739          34 :   *aScreenConfiguration = ScreenConfigurationObservers().GetCurrentInformation();
     740          34 : }
     741             : 
     742             : void
     743           0 : NotifyScreenConfigurationChange(const ScreenConfiguration& aScreenConfiguration)
     744             : {
     745           0 :   ScreenConfigurationObservers().CacheInformation(aScreenConfiguration);
     746           0 :   ScreenConfigurationObservers().BroadcastCachedInformation();
     747           0 : }
     748             : 
     749             : bool
     750           0 : LockScreenOrientation(const dom::ScreenOrientationInternal& aOrientation)
     751             : {
     752           0 :   AssertMainThread();
     753           0 :   RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), false);
     754             : }
     755             : 
     756             : void
     757           0 : UnlockScreenOrientation()
     758             : {
     759           0 :   AssertMainThread();
     760           0 :   PROXY_IF_SANDBOXED(UnlockScreenOrientation());
     761           0 : }
     762             : 
     763             : void
     764           0 : EnableSwitchNotifications(SwitchDevice aDevice) {
     765           0 :   AssertMainThread();
     766           0 :   PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice));
     767           0 : }
     768             : 
     769             : void
     770           0 : DisableSwitchNotifications(SwitchDevice aDevice) {
     771           0 :   AssertMainThread();
     772           0 :   PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
     773           0 : }
     774             : 
     775           0 : SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
     776             : {
     777           0 :   AssertMainThread();
     778           0 :   RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
     779             : }
     780             : 
     781           0 : void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
     782             : {
     783           0 :   AssertMainThread();
     784           0 :   PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
     785           0 : }
     786             : 
     787             : typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
     788             : 
     789             : static SwitchObserverList *sSwitchObserverLists = nullptr;
     790             : 
     791             : static SwitchObserverList&
     792           0 : GetSwitchObserverList(SwitchDevice aDevice) {
     793           0 :   MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
     794           0 :   if (sSwitchObserverLists == nullptr) {
     795           0 :     sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
     796             :   }
     797           0 :   return sSwitchObserverLists[aDevice];
     798             : }
     799             : 
     800             : static void
     801           0 : ReleaseObserversIfNeeded() {
     802           0 :   for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
     803           0 :     if (sSwitchObserverLists[i].Length() != 0)
     804           0 :       return;
     805             :   }
     806             : 
     807             :   //The length of every list is 0, no observer in the list.
     808           0 :   delete [] sSwitchObserverLists;
     809           0 :   sSwitchObserverLists = nullptr;
     810             : }
     811             : 
     812             : void
     813           0 : RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
     814             : {
     815           0 :   AssertMainThread();
     816           0 :   SwitchObserverList& observer = GetSwitchObserverList(aDevice);
     817           0 :   observer.AddObserver(aObserver);
     818           0 :   if (observer.Length() == 1) {
     819           0 :     EnableSwitchNotifications(aDevice);
     820             :   }
     821           0 : }
     822             : 
     823             : void
     824           0 : UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
     825             : {
     826           0 :   AssertMainThread();
     827             : 
     828           0 :   if (!sSwitchObserverLists) {
     829           0 :     return;
     830             :   }
     831             : 
     832           0 :   SwitchObserverList& observer = GetSwitchObserverList(aDevice);
     833           0 :   if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
     834           0 :     return;
     835             :   }
     836             : 
     837           0 :   DisableSwitchNotifications(aDevice);
     838           0 :   ReleaseObserversIfNeeded();
     839             : }
     840             : 
     841             : void
     842           0 : NotifySwitchChange(const SwitchEvent& aEvent)
     843             : {
     844             :   // When callback this notification, main thread may call unregister function
     845             :   // first. We should check if this pointer is valid.
     846           0 :   if (!sSwitchObserverLists)
     847           0 :     return;
     848             : 
     849           0 :   SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
     850           0 :   observer.Broadcast(aEvent);
     851             : }
     852             : 
     853             : bool
     854           0 : SetProcessPrioritySupported()
     855             : {
     856           0 :   RETURN_PROXY_IF_SANDBOXED(SetProcessPrioritySupported(), false);
     857             : }
     858             : 
     859             : void
     860           0 : SetProcessPriority(int aPid, ProcessPriority aPriority)
     861             : {
     862             :   // n.b. The sandboxed implementation crashes; SetProcessPriority works only
     863             :   // from the main process.
     864           0 :   PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
     865           0 : }
     866             : 
     867             : void
     868           1 : SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
     869             : {
     870           1 :   PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
     871           1 : }
     872             : 
     873             : void
     874           0 : SetThreadPriority(PlatformThreadId aThreadId,
     875             :                   hal::ThreadPriority aThreadPriority)
     876             : {
     877           0 :   PROXY_IF_SANDBOXED(SetThreadPriority(aThreadId, aThreadPriority));
     878           0 : }
     879             : 
     880             : // From HalTypes.h.
     881             : const char*
     882           0 : ProcessPriorityToString(ProcessPriority aPriority)
     883             : {
     884           0 :   switch (aPriority) {
     885             :   case PROCESS_PRIORITY_MASTER:
     886           0 :     return "MASTER";
     887             :   case PROCESS_PRIORITY_PREALLOC:
     888           0 :     return "PREALLOC";
     889             :   case PROCESS_PRIORITY_FOREGROUND_HIGH:
     890           0 :     return "FOREGROUND_HIGH";
     891             :   case PROCESS_PRIORITY_FOREGROUND:
     892           0 :     return "FOREGROUND";
     893             :   case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
     894           0 :     return "FOREGROUND_KEYBOARD";
     895             :   case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
     896           0 :     return "BACKGROUND_PERCEIVABLE";
     897             :   case PROCESS_PRIORITY_BACKGROUND:
     898           0 :     return "BACKGROUND";
     899             :   case PROCESS_PRIORITY_UNKNOWN:
     900           0 :     return "UNKNOWN";
     901             :   default:
     902           0 :     MOZ_ASSERT(false);
     903             :     return "???";
     904             :   }
     905             : }
     906             : 
     907             : const char *
     908           0 : ThreadPriorityToString(ThreadPriority aPriority)
     909             : {
     910           0 :   switch (aPriority) {
     911             :     case THREAD_PRIORITY_COMPOSITOR:
     912           0 :       return "COMPOSITOR";
     913             :     default:
     914           0 :       MOZ_ASSERT(false);
     915             :       return "???";
     916             :   }
     917             : }
     918             : 
     919           0 : void FactoryReset(mozilla::dom::FactoryResetReason& aReason)
     920             : {
     921           0 :   AssertMainThread();
     922           0 :   PROXY_IF_SANDBOXED(FactoryReset(aReason));
     923           0 : }
     924             : 
     925             : void
     926           0 : StartDiskSpaceWatcher()
     927             : {
     928           0 :   AssertMainProcess();
     929           0 :   AssertMainThread();
     930           0 :   PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
     931           0 : }
     932             : 
     933             : void
     934           0 : StopDiskSpaceWatcher()
     935             : {
     936           0 :   AssertMainProcess();
     937           0 :   AssertMainThread();
     938           0 :   PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
     939           0 : }
     940             : 
     941             : uint32_t
     942           0 : GetTotalSystemMemory()
     943             : {
     944           0 :   return hal_impl::GetTotalSystemMemory();
     945             : }
     946             : 
     947           0 : bool IsHeadphoneEventFromInputDev()
     948             : {
     949           0 :   AssertMainThread();
     950           0 :   RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
     951             : }
     952             : 
     953           0 : nsresult StartSystemService(const char* aSvcName, const char* aArgs)
     954             : {
     955           0 :   AssertMainThread();
     956           0 :   RETURN_PROXY_IF_SANDBOXED(StartSystemService(aSvcName, aArgs), NS_ERROR_FAILURE);
     957             : }
     958             : 
     959           0 : void StopSystemService(const char* aSvcName)
     960             : {
     961           0 :   AssertMainThread();
     962           0 :   PROXY_IF_SANDBOXED(StopSystemService(aSvcName));
     963           0 : }
     964             : 
     965           0 : bool SystemServiceIsRunning(const char* aSvcName)
     966             : {
     967           0 :   AssertMainThread();
     968           0 :   RETURN_PROXY_IF_SANDBOXED(SystemServiceIsRunning(aSvcName), false);
     969             : }
     970             : 
     971             : } // namespace hal
     972           9 : } // namespace mozilla

Generated by: LCOV version 1.13