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/. */
10 #include "HalSandbox.h"
11 #include "nsThreadUtils.h"
12 #include "nsXULAppAPI.h"
13 #include "mozilla/Observer.h"
14 #include "nsIDocument.h"
15 #include "nsIDOMDocument.h"
16 #include "nsPIDOMWindow.h"
17 #include "nsIDOMWindow.h"
18 #include "mozilla/Services.h"
19 #include "nsIWebNavigation.h"
20 #include "nsITabChild.h"
21 #include "nsIDocShell.h"
22 #include "mozilla/StaticPtr.h"
23 #include "mozilla/ClearOnShutdown.h"
24 #include "WindowIdentifier.h"
25 #include "mozilla/dom/ScreenOrientation.h"
26 #include "mozilla/dom/ContentChild.h"
27 #include "mozilla/dom/ContentParent.h"
31 #define getpid _getpid
34 using namespace mozilla::services
;
35 using namespace mozilla::dom
;
37 #define PROXY_IF_SANDBOXED(_call) \
40 if (!hal_sandbox::HalChildDestroyed()) { \
48 #define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
51 if (hal_sandbox::HalChildDestroyed()) { \
54 return hal_sandbox::_call; \
56 return hal_impl::_call; \
66 static PRLogModuleInfo
*sHalLog
;
68 sHalLog
= PR_NewLogModule("hal");
78 MOZ_ASSERT(NS_IsMainThread());
84 return GeckoProcessType_Content
== XRE_GetProcessType();
90 MOZ_ASSERT(GeckoProcessType_Default
== XRE_GetProcessType());
94 WindowIsActive(nsIDOMWindow
* aWindow
)
96 nsCOMPtr
<nsPIDOMWindow
> window
= do_QueryInterface(aWindow
);
97 NS_ENSURE_TRUE(window
, false);
99 nsIDocument
* document
= window
->GetDoc();
100 NS_ENSURE_TRUE(document
, false);
102 return !document
->Hidden();
105 StaticAutoPtr
<WindowIdentifier::IDArrayType
> gLastIDToVibrate
;
107 void InitLastIDToVibrate()
109 gLastIDToVibrate
= new WindowIdentifier::IDArrayType();
110 ClearOnShutdown(&gLastIDToVibrate
);
113 } // anonymous namespace
116 Vibrate(const nsTArray
<uint32_t>& pattern
, nsIDOMWindow
* window
)
118 Vibrate(pattern
, WindowIdentifier(window
));
122 Vibrate(const nsTArray
<uint32_t>& pattern
, const WindowIdentifier
&id
)
126 // Only active windows may start vibrations. If |id| hasn't gone
127 // through the IPC layer -- that is, if our caller is the outside
128 // world, not hal_proxy -- check whether the window is active. If
129 // |id| has gone through IPC, don't check the window's visibility;
130 // only the window corresponding to the bottommost process has its
131 // visibility state set correctly.
132 if (!id
.HasTraveledThroughIPC() && !WindowIsActive(id
.GetWindow())) {
133 HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
138 if (!gLastIDToVibrate
) {
139 InitLastIDToVibrate();
141 *gLastIDToVibrate
= id
.AsArray();
144 // Don't forward our ID if we are not in the sandbox, because hal_impl
145 // doesn't need it, and we don't want it to be tempted to read it. The
146 // empty identifier will assert if it's used.
147 PROXY_IF_SANDBOXED(Vibrate(pattern
, InSandbox() ? id
: WindowIdentifier()));
151 CancelVibrate(nsIDOMWindow
* window
)
153 CancelVibrate(WindowIdentifier(window
));
157 CancelVibrate(const WindowIdentifier
&id
)
161 // Although only active windows may start vibrations, a window may
162 // cancel its own vibration even if it's no longer active.
164 // After a window is marked as inactive, it sends a CancelVibrate
165 // request. We want this request to cancel a playing vibration
166 // started by that window, so we certainly don't want to reject the
167 // cancellation request because the window is now inactive.
169 // But it could be the case that, after this window became inactive,
170 // some other window came along and started a vibration. We don't
171 // want this window's cancellation request to cancel that window's
172 // actively-playing vibration!
174 // To solve this problem, we keep track of the id of the last window
175 // to start a vibration, and only accepts cancellation requests from
176 // the same window. All other cancellation requests are ignored.
178 if (InSandbox() || (gLastIDToVibrate
&& *gLastIDToVibrate
== id
.AsArray())) {
179 // Don't forward our ID if we are not in the sandbox, because hal_impl
180 // doesn't need it, and we don't want it to be tempted to read it. The
181 // empty identifier will assert if it's used.
182 PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id
: WindowIdentifier()));
186 template <class InfoType
>
187 class ObserversManager
190 void AddObserver(Observer
<InfoType
>* aObserver
) {
192 mObservers
= new mozilla::ObserverList
<InfoType
>();
195 mObservers
->AddObserver(aObserver
);
197 if (mObservers
->Length() == 1) {
198 EnableNotifications();
202 void RemoveObserver(Observer
<InfoType
>* aObserver
) {
203 bool removed
= mObservers
&& mObservers
->RemoveObserver(aObserver
);
205 NS_WARNING("RemoveObserver() called for unregistered observer");
209 if (mObservers
->Length() == 0) {
210 DisableNotifications();
212 OnNotificationsDisabled();
215 mObservers
= nullptr;
219 void BroadcastInformation(const InfoType
& aInfo
) {
220 // It is possible for mObservers to be nullptr here on some platforms,
221 // because a call to BroadcastInformation gets queued up asynchronously
222 // while RemoveObserver is running (and before the notifications are
223 // disabled). The queued call can then get run after mObservers has
224 // been nulled out. See bug 757025.
228 mObservers
->Broadcast(aInfo
);
232 virtual void EnableNotifications() = 0;
233 virtual void DisableNotifications() = 0;
234 virtual void OnNotificationsDisabled() {}
237 mozilla::ObserverList
<InfoType
>* mObservers
;
240 template <class InfoType
>
241 class CachingObserversManager
: public ObserversManager
<InfoType
>
244 InfoType
GetCurrentInformation() {
245 if (mHasValidCache
) {
249 GetCurrentInformationInternal(&mInfo
);
250 mHasValidCache
= true;
254 void CacheInformation(const InfoType
& aInfo
) {
255 mHasValidCache
= true;
259 void BroadcastCachedInformation() {
260 this->BroadcastInformation(mInfo
);
264 virtual void GetCurrentInformationInternal(InfoType
*) = 0;
266 virtual void OnNotificationsDisabled() {
267 mHasValidCache
= false;
275 class BatteryObserversManager
: public CachingObserversManager
<BatteryInformation
>
278 void EnableNotifications() {
279 PROXY_IF_SANDBOXED(EnableBatteryNotifications());
282 void DisableNotifications() {
283 PROXY_IF_SANDBOXED(DisableBatteryNotifications());
286 void GetCurrentInformationInternal(BatteryInformation
* aInfo
) {
287 PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo
));
291 static BatteryObserversManager sBatteryObservers
;
293 class NetworkObserversManager
: public CachingObserversManager
<NetworkInformation
>
296 void EnableNotifications() {
297 PROXY_IF_SANDBOXED(EnableNetworkNotifications());
300 void DisableNotifications() {
301 PROXY_IF_SANDBOXED(DisableNetworkNotifications());
304 void GetCurrentInformationInternal(NetworkInformation
* aInfo
) {
305 PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo
));
309 static NetworkObserversManager sNetworkObservers
;
311 class WakeLockObserversManager
: public ObserversManager
<WakeLockInformation
>
314 void EnableNotifications() {
315 PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
318 void DisableNotifications() {
319 PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
323 static WakeLockObserversManager sWakeLockObservers
;
325 class ScreenConfigurationObserversManager
: public CachingObserversManager
<ScreenConfiguration
>
328 void EnableNotifications() {
329 PROXY_IF_SANDBOXED(EnableScreenConfigurationNotifications());
332 void DisableNotifications() {
333 PROXY_IF_SANDBOXED(DisableScreenConfigurationNotifications());
336 void GetCurrentInformationInternal(ScreenConfiguration
* aInfo
) {
337 PROXY_IF_SANDBOXED(GetCurrentScreenConfiguration(aInfo
));
341 static ScreenConfigurationObserversManager sScreenConfigurationObservers
;
344 RegisterBatteryObserver(BatteryObserver
* aObserver
)
347 sBatteryObservers
.AddObserver(aObserver
);
351 UnregisterBatteryObserver(BatteryObserver
* aObserver
)
354 sBatteryObservers
.RemoveObserver(aObserver
);
358 GetCurrentBatteryInformation(BatteryInformation
* aInfo
)
361 *aInfo
= sBatteryObservers
.GetCurrentInformation();
365 NotifyBatteryChange(const BatteryInformation
& aInfo
)
368 sBatteryObservers
.CacheInformation(aInfo
);
369 sBatteryObservers
.BroadcastCachedInformation();
372 bool GetScreenEnabled()
375 RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
378 void SetScreenEnabled(bool aEnabled
)
381 PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled
));
384 bool GetKeyLightEnabled()
387 RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
390 void SetKeyLightEnabled(bool aEnabled
)
393 PROXY_IF_SANDBOXED(SetKeyLightEnabled(aEnabled
));
396 bool GetCpuSleepAllowed()
398 // Generally for interfaces that are accessible by normal web content
399 // we should cache the result and be notified on state changes, like
400 // what the battery API does. But since this is only used by
401 // privileged interface, the synchronous getter is OK here.
403 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
406 void SetCpuSleepAllowed(bool aAllowed
)
409 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed
));
412 double GetScreenBrightness()
415 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
418 void SetScreenBrightness(double aBrightness
)
421 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness
, 0.0, 1.0)));
424 class SystemClockChangeObserversManager
: public ObserversManager
<int64_t>
427 void EnableNotifications() {
428 PROXY_IF_SANDBOXED(EnableSystemClockChangeNotifications());
431 void DisableNotifications() {
432 PROXY_IF_SANDBOXED(DisableSystemClockChangeNotifications());
436 static SystemClockChangeObserversManager sSystemClockChangeObservers
;
439 RegisterSystemClockChangeObserver(SystemClockChangeObserver
* aObserver
)
442 sSystemClockChangeObservers
.AddObserver(aObserver
);
446 UnregisterSystemClockChangeObserver(SystemClockChangeObserver
* aObserver
)
449 sSystemClockChangeObservers
.RemoveObserver(aObserver
);
453 NotifySystemClockChange(const int64_t& aClockDeltaMS
)
455 sSystemClockChangeObservers
.BroadcastInformation(aClockDeltaMS
);
458 class SystemTimezoneChangeObserversManager
: public ObserversManager
<SystemTimezoneChangeInformation
>
461 void EnableNotifications() {
462 PROXY_IF_SANDBOXED(EnableSystemTimezoneChangeNotifications());
465 void DisableNotifications() {
466 PROXY_IF_SANDBOXED(DisableSystemTimezoneChangeNotifications());
470 static SystemTimezoneChangeObserversManager sSystemTimezoneChangeObservers
;
473 RegisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver
* aObserver
)
476 sSystemTimezoneChangeObservers
.AddObserver(aObserver
);
480 UnregisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver
* aObserver
)
483 sSystemTimezoneChangeObservers
.RemoveObserver(aObserver
);
487 NotifySystemTimezoneChange(const SystemTimezoneChangeInformation
& aSystemTimezoneChangeInfo
)
489 sSystemTimezoneChangeObservers
.BroadcastInformation(aSystemTimezoneChangeInfo
);
493 AdjustSystemClock(int64_t aDeltaMilliseconds
)
496 PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds
));
500 SetTimezone(const nsCString
& aTimezoneSpec
)
503 PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec
));
510 RETURN_PROXY_IF_SANDBOXED(GetTimezoneOffset(), 0);
517 RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
521 EnableSensorNotifications(SensorType aSensor
) {
523 PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor
));
527 DisableSensorNotifications(SensorType aSensor
) {
529 PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor
));
532 typedef mozilla::ObserverList
<SensorData
> SensorObserverList
;
533 static SensorObserverList
* gSensorObservers
= nullptr;
535 static SensorObserverList
&
536 GetSensorObservers(SensorType sensor_type
) {
537 MOZ_ASSERT(sensor_type
< NUM_SENSOR_TYPE
);
539 if(!gSensorObservers
) {
540 gSensorObservers
= new SensorObserverList
[NUM_SENSOR_TYPE
];
542 return gSensorObservers
[sensor_type
];
546 RegisterSensorObserver(SensorType aSensor
, ISensorObserver
*aObserver
) {
547 SensorObserverList
&observers
= GetSensorObservers(aSensor
);
551 observers
.AddObserver(aObserver
);
552 if(observers
.Length() == 1) {
553 EnableSensorNotifications(aSensor
);
558 UnregisterSensorObserver(SensorType aSensor
, ISensorObserver
*aObserver
) {
561 if (!gSensorObservers
) {
565 SensorObserverList
&observers
= GetSensorObservers(aSensor
);
566 if (!observers
.RemoveObserver(aObserver
) || observers
.Length() > 0) {
569 DisableSensorNotifications(aSensor
);
571 // Destroy sSensorObservers only if all observer lists are empty.
572 for (int i
= 0; i
< NUM_SENSOR_TYPE
; i
++) {
573 if (gSensorObservers
[i
].Length() > 0) {
577 delete [] gSensorObservers
;
578 gSensorObservers
= nullptr;
582 NotifySensorChange(const SensorData
&aSensorData
) {
583 SensorObserverList
&observers
= GetSensorObservers(aSensorData
.sensor());
587 observers
.Broadcast(aSensorData
);
591 RegisterNetworkObserver(NetworkObserver
* aObserver
)
594 sNetworkObservers
.AddObserver(aObserver
);
598 UnregisterNetworkObserver(NetworkObserver
* aObserver
)
601 sNetworkObservers
.RemoveObserver(aObserver
);
605 GetCurrentNetworkInformation(NetworkInformation
* aInfo
)
608 *aInfo
= sNetworkObservers
.GetCurrentInformation();
612 NotifyNetworkChange(const NetworkInformation
& aInfo
)
614 sNetworkObservers
.CacheInformation(aInfo
);
615 sNetworkObservers
.BroadcastCachedInformation();
622 PROXY_IF_SANDBOXED(Reboot());
629 PROXY_IF_SANDBOXED(PowerOff());
632 void StartForceQuitWatchdog(ShutdownMode aMode
, int32_t aTimeoutSecs
)
636 PROXY_IF_SANDBOXED(StartForceQuitWatchdog(aMode
, aTimeoutSecs
));
639 void StartMonitoringGamepadStatus()
641 PROXY_IF_SANDBOXED(StartMonitoringGamepadStatus());
644 void StopMonitoringGamepadStatus()
646 PROXY_IF_SANDBOXED(StopMonitoringGamepadStatus());
650 RegisterWakeLockObserver(WakeLockObserver
* aObserver
)
653 sWakeLockObservers
.AddObserver(aObserver
);
657 UnregisterWakeLockObserver(WakeLockObserver
* aObserver
)
660 sWakeLockObservers
.RemoveObserver(aObserver
);
664 ModifyWakeLock(const nsAString
& aTopic
,
665 WakeLockControl aLockAdjust
,
666 WakeLockControl aHiddenAdjust
,
667 uint64_t aProcessID
/* = CONTENT_PROCESS_ID_UNKNOWN */)
671 if (aProcessID
== CONTENT_PROCESS_ID_UNKNOWN
) {
672 aProcessID
= InSandbox() ? ContentChild::GetSingleton()->GetID() :
673 CONTENT_PROCESS_ID_MAIN
;
676 PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic
, aLockAdjust
,
677 aHiddenAdjust
, aProcessID
));
681 GetWakeLockInfo(const nsAString
& aTopic
, WakeLockInformation
* aWakeLockInfo
)
684 PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic
, aWakeLockInfo
));
688 NotifyWakeLockChange(const WakeLockInformation
& aInfo
)
691 sWakeLockObservers
.BroadcastInformation(aInfo
);
695 RegisterScreenConfigurationObserver(ScreenConfigurationObserver
* aObserver
)
698 sScreenConfigurationObservers
.AddObserver(aObserver
);
702 UnregisterScreenConfigurationObserver(ScreenConfigurationObserver
* aObserver
)
705 sScreenConfigurationObservers
.RemoveObserver(aObserver
);
709 GetCurrentScreenConfiguration(ScreenConfiguration
* aScreenConfiguration
)
712 *aScreenConfiguration
= sScreenConfigurationObservers
.GetCurrentInformation();
716 NotifyScreenConfigurationChange(const ScreenConfiguration
& aScreenConfiguration
)
718 sScreenConfigurationObservers
.CacheInformation(aScreenConfiguration
);
719 sScreenConfigurationObservers
.BroadcastCachedInformation();
723 LockScreenOrientation(const dom::ScreenOrientation
& aOrientation
)
726 RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation
), false);
730 UnlockScreenOrientation()
733 PROXY_IF_SANDBOXED(UnlockScreenOrientation());
737 EnableSwitchNotifications(SwitchDevice aDevice
) {
739 PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice
));
743 DisableSwitchNotifications(SwitchDevice aDevice
) {
745 PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice
));
748 SwitchState
GetCurrentSwitchState(SwitchDevice aDevice
)
751 RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice
), SWITCH_STATE_UNKNOWN
);
754 void NotifySwitchStateFromInputDevice(SwitchDevice aDevice
, SwitchState aState
)
757 PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice
, aState
));
760 typedef mozilla::ObserverList
<SwitchEvent
> SwitchObserverList
;
762 static SwitchObserverList
*sSwitchObserverLists
= nullptr;
764 static SwitchObserverList
&
765 GetSwitchObserverList(SwitchDevice aDevice
) {
766 MOZ_ASSERT(0 <= aDevice
&& aDevice
< NUM_SWITCH_DEVICE
);
767 if (sSwitchObserverLists
== nullptr) {
768 sSwitchObserverLists
= new SwitchObserverList
[NUM_SWITCH_DEVICE
];
770 return sSwitchObserverLists
[aDevice
];
774 ReleaseObserversIfNeeded() {
775 for (int i
= 0; i
< NUM_SWITCH_DEVICE
; i
++) {
776 if (sSwitchObserverLists
[i
].Length() != 0)
780 //The length of every list is 0, no observer in the list.
781 delete [] sSwitchObserverLists
;
782 sSwitchObserverLists
= nullptr;
786 RegisterSwitchObserver(SwitchDevice aDevice
, SwitchObserver
*aObserver
)
789 SwitchObserverList
& observer
= GetSwitchObserverList(aDevice
);
790 observer
.AddObserver(aObserver
);
791 if (observer
.Length() == 1) {
792 EnableSwitchNotifications(aDevice
);
797 UnregisterSwitchObserver(SwitchDevice aDevice
, SwitchObserver
*aObserver
)
801 if (!sSwitchObserverLists
) {
805 SwitchObserverList
& observer
= GetSwitchObserverList(aDevice
);
806 if (!observer
.RemoveObserver(aObserver
) || observer
.Length() > 0) {
810 DisableSwitchNotifications(aDevice
);
811 ReleaseObserversIfNeeded();
815 NotifySwitchChange(const SwitchEvent
& aEvent
)
817 // When callback this notification, main thread may call unregister function
818 // first. We should check if this pointer is valid.
819 if (!sSwitchObserverLists
)
822 SwitchObserverList
& observer
= GetSwitchObserverList(aEvent
.device());
823 observer
.Broadcast(aEvent
);
826 static AlarmObserver
* sAlarmObserver
;
829 RegisterTheOneAlarmObserver(AlarmObserver
* aObserver
)
831 MOZ_ASSERT(!InSandbox());
832 MOZ_ASSERT(!sAlarmObserver
);
834 sAlarmObserver
= aObserver
;
835 RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
839 UnregisterTheOneAlarmObserver()
841 if (sAlarmObserver
) {
842 sAlarmObserver
= nullptr;
843 PROXY_IF_SANDBOXED(DisableAlarm());
850 if (sAlarmObserver
) {
851 sAlarmObserver
->Notify(void_t());
856 SetAlarm(int32_t aSeconds
, int32_t aNanoseconds
)
858 // It's pointless to program an alarm nothing is going to observe ...
859 MOZ_ASSERT(sAlarmObserver
);
860 RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds
, aNanoseconds
), false);
864 SetProcessPriority(int aPid
, ProcessPriority aPriority
, uint32_t aLRU
)
866 // n.b. The sandboxed implementation crashes; SetProcessPriority works only
867 // from the main process.
868 PROXY_IF_SANDBOXED(SetProcessPriority(aPid
, aPriority
, aLRU
));
872 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority
)
874 PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority
));
879 ProcessPriorityToString(ProcessPriority aPriority
)
882 case PROCESS_PRIORITY_MASTER
:
884 case PROCESS_PRIORITY_PREALLOC
:
886 case PROCESS_PRIORITY_FOREGROUND_HIGH
:
887 return "FOREGROUND_HIGH";
888 case PROCESS_PRIORITY_FOREGROUND
:
890 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD
:
891 return "FOREGROUND_KEYBOARD";
892 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE
:
893 return "BACKGROUND_PERCEIVABLE";
894 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN
:
895 return "BACKGROUND_HOMESCREEN";
896 case PROCESS_PRIORITY_BACKGROUND
:
898 case PROCESS_PRIORITY_UNKNOWN
:
907 ThreadPriorityToString(ThreadPriority aPriority
)
910 case THREAD_PRIORITY_COMPOSITOR
:
918 static StaticAutoPtr
<ObserverList
<FMRadioOperationInformation
> > sFMRadioObservers
;
919 static StaticAutoPtr
<ObserverList
<FMRadioRDSGroup
> > sFMRadioRDSObservers
;
922 InitializeFMRadioObserver()
924 if (!sFMRadioObservers
) {
925 sFMRadioObservers
= new ObserverList
<FMRadioOperationInformation
>;
926 sFMRadioRDSObservers
= new ObserverList
<FMRadioRDSGroup
>;
927 ClearOnShutdown(&sFMRadioRDSObservers
);
928 ClearOnShutdown(&sFMRadioObservers
);
933 RegisterFMRadioObserver(FMRadioObserver
* aFMRadioObserver
) {
935 InitializeFMRadioObserver();
936 sFMRadioObservers
->AddObserver(aFMRadioObserver
);
940 UnregisterFMRadioObserver(FMRadioObserver
* aFMRadioObserver
) {
942 InitializeFMRadioObserver();
943 sFMRadioObservers
->RemoveObserver(aFMRadioObserver
);
947 NotifyFMRadioStatus(const FMRadioOperationInformation
& aFMRadioState
) {
948 InitializeFMRadioObserver();
949 sFMRadioObservers
->Broadcast(aFMRadioState
);
953 RegisterFMRadioRDSObserver(FMRadioRDSObserver
* aFMRadioRDSObserver
) {
955 InitializeFMRadioObserver();
956 sFMRadioRDSObservers
->AddObserver(aFMRadioRDSObserver
);
960 UnregisterFMRadioRDSObserver(FMRadioRDSObserver
* aFMRadioRDSObserver
) {
962 InitializeFMRadioObserver();
963 sFMRadioRDSObservers
->RemoveObserver(aFMRadioRDSObserver
);
968 NotifyFMRadioRDSGroup(const FMRadioRDSGroup
& aRDSGroup
) {
969 InitializeFMRadioObserver();
970 sFMRadioRDSObservers
->Broadcast(aRDSGroup
);
974 EnableFMRadio(const FMRadioSettings
& aInfo
) {
976 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo
));
982 PROXY_IF_SANDBOXED(DisableFMRadio());
986 FMRadioSeek(const FMRadioSeekDirection
& aDirection
) {
987 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection
));
991 GetFMRadioSettings(FMRadioSettings
* aInfo
) {
993 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo
));
997 SetFMRadioFrequency(const uint32_t aFrequency
) {
998 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency
));
1002 GetFMRadioFrequency() {
1004 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
1010 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
1014 GetFMRadioSignalStrength() {
1016 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
1020 CancelFMRadioSeek() {
1022 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
1026 EnableRDS(uint32_t aMask
) {
1028 RETURN_PROXY_IF_SANDBOXED(EnableRDS(aMask
), false);
1034 PROXY_IF_SANDBOXED(DisableRDS());
1038 GetFMBandSettings(FMRadioCountry aCountry
) {
1039 FMRadioSettings settings
;
1042 case FM_RADIO_COUNTRY_US
:
1043 case FM_RADIO_COUNTRY_EU
:
1044 settings
.upperLimit() = 108000;
1045 settings
.lowerLimit() = 87800;
1046 settings
.spaceType() = 200;
1047 settings
.preEmphasis() = 75;
1049 case FM_RADIO_COUNTRY_JP_STANDARD
:
1050 settings
.upperLimit() = 76000;
1051 settings
.lowerLimit() = 90000;
1052 settings
.spaceType() = 100;
1053 settings
.preEmphasis() = 50;
1055 case FM_RADIO_COUNTRY_CY
:
1056 case FM_RADIO_COUNTRY_DE
:
1057 case FM_RADIO_COUNTRY_DK
:
1058 case FM_RADIO_COUNTRY_ES
:
1059 case FM_RADIO_COUNTRY_FI
:
1060 case FM_RADIO_COUNTRY_FR
:
1061 case FM_RADIO_COUNTRY_HU
:
1062 case FM_RADIO_COUNTRY_IR
:
1063 case FM_RADIO_COUNTRY_IT
:
1064 case FM_RADIO_COUNTRY_KW
:
1065 case FM_RADIO_COUNTRY_LT
:
1066 case FM_RADIO_COUNTRY_ML
:
1067 case FM_RADIO_COUNTRY_NO
:
1068 case FM_RADIO_COUNTRY_OM
:
1069 case FM_RADIO_COUNTRY_PG
:
1070 case FM_RADIO_COUNTRY_NL
:
1071 case FM_RADIO_COUNTRY_CZ
:
1072 case FM_RADIO_COUNTRY_UK
:
1073 case FM_RADIO_COUNTRY_RW
:
1074 case FM_RADIO_COUNTRY_SN
:
1075 case FM_RADIO_COUNTRY_SI
:
1076 case FM_RADIO_COUNTRY_ZA
:
1077 case FM_RADIO_COUNTRY_SE
:
1078 case FM_RADIO_COUNTRY_CH
:
1079 case FM_RADIO_COUNTRY_TW
:
1080 case FM_RADIO_COUNTRY_UA
:
1081 settings
.upperLimit() = 108000;
1082 settings
.lowerLimit() = 87500;
1083 settings
.spaceType() = 100;
1084 settings
.preEmphasis() = 50;
1086 case FM_RADIO_COUNTRY_VA
:
1087 case FM_RADIO_COUNTRY_MA
:
1088 case FM_RADIO_COUNTRY_TR
:
1089 settings
.upperLimit() = 10800;
1090 settings
.lowerLimit() = 87500;
1091 settings
.spaceType() = 100;
1092 settings
.preEmphasis() = 75;
1094 case FM_RADIO_COUNTRY_AU
:
1095 case FM_RADIO_COUNTRY_BD
:
1096 settings
.upperLimit() = 108000;
1097 settings
.lowerLimit() = 87500;
1098 settings
.spaceType() = 200;
1099 settings
.preEmphasis() = 75;
1101 case FM_RADIO_COUNTRY_AW
:
1102 case FM_RADIO_COUNTRY_BS
:
1103 case FM_RADIO_COUNTRY_CO
:
1104 case FM_RADIO_COUNTRY_KR
:
1105 settings
.upperLimit() = 108000;
1106 settings
.lowerLimit() = 88000;
1107 settings
.spaceType() = 200;
1108 settings
.preEmphasis() = 75;
1110 case FM_RADIO_COUNTRY_EC
:
1111 settings
.upperLimit() = 108000;
1112 settings
.lowerLimit() = 88000;
1113 settings
.spaceType() = 200;
1114 settings
.preEmphasis() = 0;
1116 case FM_RADIO_COUNTRY_GM
:
1117 settings
.upperLimit() = 108000;
1118 settings
.lowerLimit() = 88000;
1119 settings
.spaceType() = 0;
1120 settings
.preEmphasis() = 75;
1122 case FM_RADIO_COUNTRY_QA
:
1123 settings
.upperLimit() = 108000;
1124 settings
.lowerLimit() = 88000;
1125 settings
.spaceType() = 200;
1126 settings
.preEmphasis() = 50;
1128 case FM_RADIO_COUNTRY_SG
:
1129 settings
.upperLimit() = 108000;
1130 settings
.lowerLimit() = 88000;
1131 settings
.spaceType() = 200;
1132 settings
.preEmphasis() = 50;
1134 case FM_RADIO_COUNTRY_IN
:
1135 settings
.upperLimit() = 100000;
1136 settings
.lowerLimit() = 108000;
1137 settings
.spaceType() = 100;
1138 settings
.preEmphasis() = 50;
1140 case FM_RADIO_COUNTRY_NZ
:
1141 settings
.upperLimit() = 100000;
1142 settings
.lowerLimit() = 88000;
1143 settings
.spaceType() = 50;
1144 settings
.preEmphasis() = 50;
1146 case FM_RADIO_COUNTRY_USER_DEFINED
:
1155 void FactoryReset(mozilla::dom::FactoryResetReason
& aReason
)
1158 PROXY_IF_SANDBOXED(FactoryReset(aReason
));
1162 StartDiskSpaceWatcher()
1164 AssertMainProcess();
1166 PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
1170 StopDiskSpaceWatcher()
1172 AssertMainProcess();
1174 PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
1178 GetTotalSystemMemory()
1180 return hal_impl::GetTotalSystemMemory();
1184 GetTotalSystemMemoryLevel()
1186 return hal_impl::GetTotalSystemMemoryLevel();
1189 bool IsHeadphoneEventFromInputDev()
1192 RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
1196 } // namespace mozilla