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/. */
9 #include "HalSandbox.h"
10 #include "mozilla/Util.h"
11 #include "nsThreadUtils.h"
12 #include "nsXULAppAPI.h"
13 #include "mozilla/Observer.h"
14 #include "nsIDOMDocument.h"
15 #include "nsIDOMWindow.h"
16 #include "mozilla/Services.h"
17 #include "nsIWebNavigation.h"
18 #include "nsITabChild.h"
19 #include "nsIDocShell.h"
20 #include "mozilla/StaticPtr.h"
21 #include "mozilla/ClearOnShutdown.h"
22 #include "WindowIdentifier.h"
23 #include "mozilla/dom/ScreenOrientation.h"
27 #define getpid _getpid
30 using namespace mozilla::services
;
32 #define PROXY_IF_SANDBOXED(_call) \
41 #define RETURN_PROXY_IF_SANDBOXED(_call) \
44 return hal_sandbox::_call; \
46 return hal_impl::_call; \
53 PRLogModuleInfo
*sHalLog
= PR_LOG_DEFINE("hal");
60 MOZ_ASSERT(NS_IsMainThread());
66 return GeckoProcessType_Content
== XRE_GetProcessType();
72 MOZ_ASSERT(GeckoProcessType_Default
== XRE_GetProcessType());
76 WindowIsActive(nsIDOMWindow
*window
)
78 NS_ENSURE_TRUE(window
, false);
80 nsCOMPtr
<nsIDOMDocument
> doc
;
81 window
->GetDocument(getter_AddRefs(doc
));
82 NS_ENSURE_TRUE(doc
, false);
85 doc
->GetMozHidden(&hidden
);
89 StaticAutoPtr
<WindowIdentifier::IDArrayType
> gLastIDToVibrate
;
91 void InitLastIDToVibrate()
93 gLastIDToVibrate
= new WindowIdentifier::IDArrayType();
94 ClearOnShutdown(&gLastIDToVibrate
);
97 } // anonymous namespace
100 Vibrate(const nsTArray
<uint32_t>& pattern
, nsIDOMWindow
* window
)
102 Vibrate(pattern
, WindowIdentifier(window
));
106 Vibrate(const nsTArray
<uint32_t>& pattern
, const WindowIdentifier
&id
)
110 // Only active windows may start vibrations. If |id| hasn't gone
111 // through the IPC layer -- that is, if our caller is the outside
112 // world, not hal_proxy -- check whether the window is active. If
113 // |id| has gone through IPC, don't check the window's visibility;
114 // only the window corresponding to the bottommost process has its
115 // visibility state set correctly.
116 if (!id
.HasTraveledThroughIPC() && !WindowIsActive(id
.GetWindow())) {
117 HAL_LOG(("Vibrate: Window is inactive, dropping vibrate."));
122 hal_sandbox::Vibrate(pattern
, id
);
125 if (!gLastIDToVibrate
)
126 InitLastIDToVibrate();
127 *gLastIDToVibrate
= id
.AsArray();
129 HAL_LOG(("Vibrate: Forwarding to hal_impl."));
131 // hal_impl doesn't need |id|. Send it an empty id, which will
132 // assert if it's used.
133 hal_impl::Vibrate(pattern
, WindowIdentifier());
138 CancelVibrate(nsIDOMWindow
* window
)
140 CancelVibrate(WindowIdentifier(window
));
144 CancelVibrate(const WindowIdentifier
&id
)
148 // Although only active windows may start vibrations, a window may
149 // cancel its own vibration even if it's no longer active.
151 // After a window is marked as inactive, it sends a CancelVibrate
152 // request. We want this request to cancel a playing vibration
153 // started by that window, so we certainly don't want to reject the
154 // cancellation request because the window is now inactive.
156 // But it could be the case that, after this window became inactive,
157 // some other window came along and started a vibration. We don't
158 // want this window's cancellation request to cancel that window's
159 // actively-playing vibration!
161 // To solve this problem, we keep track of the id of the last window
162 // to start a vibration, and only accepts cancellation requests from
163 // the same window. All other cancellation requests are ignored.
166 hal_sandbox::CancelVibrate(id
);
168 else if (gLastIDToVibrate
&& *gLastIDToVibrate
== id
.AsArray()) {
169 // Don't forward our ID to hal_impl. It doesn't need it, and we
170 // don't want it to be tempted to read it. The empty identifier
171 // will assert if it's used.
172 HAL_LOG(("CancelVibrate: Forwarding to hal_impl."));
173 hal_impl::CancelVibrate(WindowIdentifier());
177 template <class InfoType
>
178 class ObserversManager
181 void AddObserver(Observer
<InfoType
>* aObserver
) {
183 mObservers
= new mozilla::ObserverList
<InfoType
>();
186 mObservers
->AddObserver(aObserver
);
188 if (mObservers
->Length() == 1) {
189 EnableNotifications();
193 void RemoveObserver(Observer
<InfoType
>* aObserver
) {
194 bool removed
= mObservers
&& mObservers
->RemoveObserver(aObserver
);
196 NS_WARNING("RemoveObserver() called for unregistered observer");
200 if (mObservers
->Length() == 0) {
201 DisableNotifications();
203 OnNotificationsDisabled();
206 mObservers
= nullptr;
210 void BroadcastInformation(const InfoType
& aInfo
) {
211 // It is possible for mObservers to be NULL here on some platforms,
212 // because a call to BroadcastInformation gets queued up asynchronously
213 // while RemoveObserver is running (and before the notifications are
214 // disabled). The queued call can then get run after mObservers has
215 // been nulled out. See bug 757025.
219 mObservers
->Broadcast(aInfo
);
223 virtual void EnableNotifications() = 0;
224 virtual void DisableNotifications() = 0;
225 virtual void OnNotificationsDisabled() {}
228 mozilla::ObserverList
<InfoType
>* mObservers
;
231 template <class InfoType
>
232 class CachingObserversManager
: public ObserversManager
<InfoType
>
235 InfoType
GetCurrentInformation() {
236 if (mHasValidCache
) {
240 GetCurrentInformationInternal(&mInfo
);
241 mHasValidCache
= true;
245 void CacheInformation(const InfoType
& aInfo
) {
246 mHasValidCache
= true;
250 void BroadcastCachedInformation() {
251 this->BroadcastInformation(mInfo
);
255 virtual void GetCurrentInformationInternal(InfoType
*) = 0;
257 virtual void OnNotificationsDisabled() {
258 mHasValidCache
= false;
266 class BatteryObserversManager
: public CachingObserversManager
<BatteryInformation
>
269 void EnableNotifications() {
270 PROXY_IF_SANDBOXED(EnableBatteryNotifications());
273 void DisableNotifications() {
274 PROXY_IF_SANDBOXED(DisableBatteryNotifications());
277 void GetCurrentInformationInternal(BatteryInformation
* aInfo
) {
278 PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo
));
282 static BatteryObserversManager sBatteryObservers
;
284 class NetworkObserversManager
: public CachingObserversManager
<NetworkInformation
>
287 void EnableNotifications() {
288 PROXY_IF_SANDBOXED(EnableNetworkNotifications());
291 void DisableNotifications() {
292 PROXY_IF_SANDBOXED(DisableNetworkNotifications());
295 void GetCurrentInformationInternal(NetworkInformation
* aInfo
) {
296 PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo
));
300 static NetworkObserversManager sNetworkObservers
;
302 class WakeLockObserversManager
: public ObserversManager
<WakeLockInformation
>
305 void EnableNotifications() {
306 PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
309 void DisableNotifications() {
310 PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
314 static WakeLockObserversManager sWakeLockObservers
;
316 class ScreenConfigurationObserversManager
: public CachingObserversManager
<ScreenConfiguration
>
319 void EnableNotifications() {
320 PROXY_IF_SANDBOXED(EnableScreenConfigurationNotifications());
323 void DisableNotifications() {
324 PROXY_IF_SANDBOXED(DisableScreenConfigurationNotifications());
327 void GetCurrentInformationInternal(ScreenConfiguration
* aInfo
) {
328 PROXY_IF_SANDBOXED(GetCurrentScreenConfiguration(aInfo
));
332 static ScreenConfigurationObserversManager sScreenConfigurationObservers
;
335 RegisterBatteryObserver(BatteryObserver
* aObserver
)
338 sBatteryObservers
.AddObserver(aObserver
);
342 UnregisterBatteryObserver(BatteryObserver
* aObserver
)
345 sBatteryObservers
.RemoveObserver(aObserver
);
349 GetCurrentBatteryInformation(BatteryInformation
* aInfo
)
352 *aInfo
= sBatteryObservers
.GetCurrentInformation();
356 NotifyBatteryChange(const BatteryInformation
& aInfo
)
359 sBatteryObservers
.CacheInformation(aInfo
);
360 sBatteryObservers
.BroadcastCachedInformation();
363 bool GetScreenEnabled()
366 RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled());
369 void SetScreenEnabled(bool enabled
)
372 PROXY_IF_SANDBOXED(SetScreenEnabled(enabled
));
375 bool GetCpuSleepAllowed()
377 // Generally for interfaces that are accessible by normal web content
378 // we should cache the result and be notified on state changes, like
379 // what the battery API does. But since this is only used by
380 // privileged interface, the synchronous getter is OK here.
382 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed());
385 void SetCpuSleepAllowed(bool allowed
)
388 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed
));
391 double GetScreenBrightness()
394 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness());
397 void SetScreenBrightness(double brightness
)
400 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness
, 0.0, 1.0)));
403 bool SetLight(LightType light
, const hal::LightConfiguration
& aConfig
)
406 RETURN_PROXY_IF_SANDBOXED(SetLight(light
, aConfig
));
409 bool GetLight(LightType light
, hal::LightConfiguration
* aConfig
)
412 RETURN_PROXY_IF_SANDBOXED(GetLight(light
, aConfig
));
415 class SystemTimeObserversManager
: public ObserversManager
<SystemTimeChange
>
418 void EnableNotifications() {
419 PROXY_IF_SANDBOXED(EnableSystemTimeChangeNotifications());
422 void DisableNotifications() {
423 PROXY_IF_SANDBOXED(DisableSystemTimeChangeNotifications());
427 static SystemTimeObserversManager sSystemTimeObservers
;
430 RegisterSystemTimeChangeObserver(SystemTimeObserver
*aObserver
)
433 sSystemTimeObservers
.AddObserver(aObserver
);
437 UnregisterSystemTimeChangeObserver(SystemTimeObserver
*aObserver
)
440 sSystemTimeObservers
.RemoveObserver(aObserver
);
444 NotifySystemTimeChange(const hal::SystemTimeChange
& aReason
)
446 sSystemTimeObservers
.BroadcastInformation(aReason
);
450 AdjustSystemClock(int64_t aDeltaMilliseconds
)
453 PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds
));
457 SetTimezone(const nsCString
& aTimezoneSpec
)
460 PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec
));
467 RETURN_PROXY_IF_SANDBOXED(GetTimezone());
471 EnableSensorNotifications(SensorType aSensor
) {
473 PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor
));
477 DisableSensorNotifications(SensorType aSensor
) {
479 PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor
));
482 typedef mozilla::ObserverList
<SensorData
> SensorObserverList
;
483 static SensorObserverList
* gSensorObservers
= nullptr;
485 static SensorObserverList
&
486 GetSensorObservers(SensorType sensor_type
) {
487 MOZ_ASSERT(sensor_type
< NUM_SENSOR_TYPE
);
489 if(!gSensorObservers
) {
490 gSensorObservers
= new SensorObserverList
[NUM_SENSOR_TYPE
];
492 return gSensorObservers
[sensor_type
];
496 RegisterSensorObserver(SensorType aSensor
, ISensorObserver
*aObserver
) {
497 SensorObserverList
&observers
= GetSensorObservers(aSensor
);
501 observers
.AddObserver(aObserver
);
502 if(observers
.Length() == 1) {
503 EnableSensorNotifications(aSensor
);
508 UnregisterSensorObserver(SensorType aSensor
, ISensorObserver
*aObserver
) {
511 if (!gSensorObservers
) {
515 SensorObserverList
&observers
= GetSensorObservers(aSensor
);
516 if (!observers
.RemoveObserver(aObserver
) || observers
.Length() > 0) {
519 DisableSensorNotifications(aSensor
);
521 // Destroy sSensorObservers only if all observer lists are empty.
522 for (int i
= 0; i
< NUM_SENSOR_TYPE
; i
++) {
523 if (gSensorObservers
[i
].Length() > 0) {
527 delete [] gSensorObservers
;
528 gSensorObservers
= nullptr;
532 NotifySensorChange(const SensorData
&aSensorData
) {
533 SensorObserverList
&observers
= GetSensorObservers(aSensorData
.sensor());
537 observers
.Broadcast(aSensorData
);
541 RegisterNetworkObserver(NetworkObserver
* aObserver
)
544 sNetworkObservers
.AddObserver(aObserver
);
548 UnregisterNetworkObserver(NetworkObserver
* aObserver
)
551 sNetworkObservers
.RemoveObserver(aObserver
);
555 GetCurrentNetworkInformation(NetworkInformation
* aInfo
)
558 *aInfo
= sNetworkObservers
.GetCurrentInformation();
562 NotifyNetworkChange(const NetworkInformation
& aInfo
)
564 sNetworkObservers
.CacheInformation(aInfo
);
565 sNetworkObservers
.BroadcastCachedInformation();
572 PROXY_IF_SANDBOXED(Reboot());
579 PROXY_IF_SANDBOXED(PowerOff());
583 RegisterWakeLockObserver(WakeLockObserver
* aObserver
)
586 sWakeLockObservers
.AddObserver(aObserver
);
590 UnregisterWakeLockObserver(WakeLockObserver
* aObserver
)
593 sWakeLockObservers
.RemoveObserver(aObserver
);
597 ModifyWakeLock(const nsAString
&aTopic
,
598 hal::WakeLockControl aLockAdjust
,
599 hal::WakeLockControl aHiddenAdjust
)
602 PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic
, aLockAdjust
, aHiddenAdjust
));
606 GetWakeLockInfo(const nsAString
&aTopic
, WakeLockInformation
*aWakeLockInfo
)
609 PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic
, aWakeLockInfo
));
613 NotifyWakeLockChange(const WakeLockInformation
& aInfo
)
616 sWakeLockObservers
.BroadcastInformation(aInfo
);
620 RegisterScreenConfigurationObserver(ScreenConfigurationObserver
* aObserver
)
623 sScreenConfigurationObservers
.AddObserver(aObserver
);
627 UnregisterScreenConfigurationObserver(ScreenConfigurationObserver
* aObserver
)
630 sScreenConfigurationObservers
.RemoveObserver(aObserver
);
634 GetCurrentScreenConfiguration(ScreenConfiguration
* aScreenConfiguration
)
637 *aScreenConfiguration
= sScreenConfigurationObservers
.GetCurrentInformation();
641 NotifyScreenConfigurationChange(const ScreenConfiguration
& aScreenConfiguration
)
643 sScreenConfigurationObservers
.CacheInformation(aScreenConfiguration
);
644 sScreenConfigurationObservers
.BroadcastCachedInformation();
648 LockScreenOrientation(const dom::ScreenOrientation
& aOrientation
)
651 RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation
));
655 UnlockScreenOrientation()
658 PROXY_IF_SANDBOXED(UnlockScreenOrientation());
662 EnableSwitchNotifications(hal::SwitchDevice aDevice
) {
664 PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice
));
668 DisableSwitchNotifications(hal::SwitchDevice aDevice
) {
670 PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice
));
673 hal::SwitchState
GetCurrentSwitchState(hal::SwitchDevice aDevice
)
676 RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice
));
679 typedef mozilla::ObserverList
<SwitchEvent
> SwitchObserverList
;
681 static SwitchObserverList
*sSwitchObserverLists
= NULL
;
683 static SwitchObserverList
&
684 GetSwitchObserverList(hal::SwitchDevice aDevice
) {
685 MOZ_ASSERT(0 <= aDevice
&& aDevice
< NUM_SWITCH_DEVICE
);
686 if (sSwitchObserverLists
== NULL
) {
687 sSwitchObserverLists
= new SwitchObserverList
[NUM_SWITCH_DEVICE
];
689 return sSwitchObserverLists
[aDevice
];
693 ReleaseObserversIfNeeded() {
694 for (int i
= 0; i
< NUM_SWITCH_DEVICE
; i
++) {
695 if (sSwitchObserverLists
[i
].Length() != 0)
699 //The length of every list is 0, no observer in the list.
700 delete [] sSwitchObserverLists
;
701 sSwitchObserverLists
= NULL
;
705 RegisterSwitchObserver(hal::SwitchDevice aDevice
, hal::SwitchObserver
*aObserver
)
708 SwitchObserverList
& observer
= GetSwitchObserverList(aDevice
);
709 observer
.AddObserver(aObserver
);
710 if (observer
.Length() == 1) {
711 EnableSwitchNotifications(aDevice
);
716 UnregisterSwitchObserver(hal::SwitchDevice aDevice
, hal::SwitchObserver
*aObserver
)
720 if (!sSwitchObserverLists
) {
724 SwitchObserverList
& observer
= GetSwitchObserverList(aDevice
);
725 if (!observer
.RemoveObserver(aObserver
) || observer
.Length() > 0) {
729 DisableSwitchNotifications(aDevice
);
730 ReleaseObserversIfNeeded();
734 NotifySwitchChange(const hal::SwitchEvent
& aEvent
)
736 // When callback this notification, main thread may call unregister function
737 // first. We should check if this pointer is valid.
738 if (!sSwitchObserverLists
)
741 SwitchObserverList
& observer
= GetSwitchObserverList(aEvent
.device());
742 observer
.Broadcast(aEvent
);
745 static AlarmObserver
* sAlarmObserver
;
748 RegisterTheOneAlarmObserver(AlarmObserver
* aObserver
)
750 MOZ_ASSERT(!InSandbox());
751 MOZ_ASSERT(!sAlarmObserver
);
753 sAlarmObserver
= aObserver
;
754 RETURN_PROXY_IF_SANDBOXED(EnableAlarm());
758 UnregisterTheOneAlarmObserver()
760 if (sAlarmObserver
) {
761 sAlarmObserver
= nullptr;
762 PROXY_IF_SANDBOXED(DisableAlarm());
769 if (sAlarmObserver
) {
770 sAlarmObserver
->Notify(void_t());
775 SetAlarm(int32_t aSeconds
, int32_t aNanoseconds
)
777 // It's pointless to program an alarm nothing is going to observe ...
778 MOZ_ASSERT(sAlarmObserver
);
779 RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds
, aNanoseconds
));
783 SetProcessPriority(int aPid
, ProcessPriority aPriority
)
785 PROXY_IF_SANDBOXED(SetProcessPriority(aPid
, aPriority
));
788 static StaticAutoPtr
<ObserverList
<FMRadioOperationInformation
> > sFMRadioObservers
;
791 InitializeFMRadioObserver()
793 if (!sFMRadioObservers
) {
794 sFMRadioObservers
= new ObserverList
<FMRadioOperationInformation
>;
795 ClearOnShutdown(&sFMRadioObservers
);
800 RegisterFMRadioObserver(FMRadioObserver
* aFMRadioObserver
) {
802 InitializeFMRadioObserver();
803 sFMRadioObservers
->AddObserver(aFMRadioObserver
);
807 UnregisterFMRadioObserver(FMRadioObserver
* aFMRadioObserver
) {
809 InitializeFMRadioObserver();
810 sFMRadioObservers
->RemoveObserver(aFMRadioObserver
);
814 NotifyFMRadioStatus(const FMRadioOperationInformation
& aFMRadioState
) {
815 InitializeFMRadioObserver();
816 sFMRadioObservers
->Broadcast(aFMRadioState
);
820 EnableFMRadio(const FMRadioSettings
& aInfo
) {
822 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo
));
828 PROXY_IF_SANDBOXED(DisableFMRadio());
832 FMRadioSeek(const FMRadioSeekDirection
& aDirection
) {
834 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection
));
838 GetFMRadioSettings(FMRadioSettings
* aInfo
) {
840 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo
));
844 SetFMRadioFrequency(const uint32_t aFrequency
) {
846 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency
));
850 GetFMRadioFrequency() {
852 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency());
858 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn());
862 GetFMRadioSignalStrength() {
864 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength());
868 CancelFMRadioSeek() {
870 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
874 GetFMBandSettings(FMRadioCountry aCountry
) {
875 FMRadioSettings settings
;
878 case FM_RADIO_COUNTRY_US
:
879 case FM_RADIO_COUNTRY_EU
:
880 settings
.upperLimit() = 108000;
881 settings
.lowerLimit() = 87800;
882 settings
.spaceType() = 200;
883 settings
.preEmphasis() = 75;
885 case FM_RADIO_COUNTRY_JP_STANDARD
:
886 settings
.upperLimit() = 76000;
887 settings
.lowerLimit() = 90000;
888 settings
.spaceType() = 100;
889 settings
.preEmphasis() = 50;
891 case FM_RADIO_COUNTRY_CY
:
892 case FM_RADIO_COUNTRY_DE
:
893 case FM_RADIO_COUNTRY_DK
:
894 case FM_RADIO_COUNTRY_ES
:
895 case FM_RADIO_COUNTRY_FI
:
896 case FM_RADIO_COUNTRY_FR
:
897 case FM_RADIO_COUNTRY_HU
:
898 case FM_RADIO_COUNTRY_IR
:
899 case FM_RADIO_COUNTRY_IT
:
900 case FM_RADIO_COUNTRY_KW
:
901 case FM_RADIO_COUNTRY_LT
:
902 case FM_RADIO_COUNTRY_ML
:
903 case FM_RADIO_COUNTRY_NO
:
904 case FM_RADIO_COUNTRY_OM
:
905 case FM_RADIO_COUNTRY_PG
:
906 case FM_RADIO_COUNTRY_NL
:
907 case FM_RADIO_COUNTRY_CZ
:
908 case FM_RADIO_COUNTRY_UK
:
909 case FM_RADIO_COUNTRY_RW
:
910 case FM_RADIO_COUNTRY_SN
:
911 case FM_RADIO_COUNTRY_SI
:
912 case FM_RADIO_COUNTRY_ZA
:
913 case FM_RADIO_COUNTRY_SE
:
914 case FM_RADIO_COUNTRY_CH
:
915 case FM_RADIO_COUNTRY_TW
:
916 case FM_RADIO_COUNTRY_UA
:
917 settings
.upperLimit() = 108000;
918 settings
.lowerLimit() = 87500;
919 settings
.spaceType() = 100;
920 settings
.preEmphasis() = 50;
922 case FM_RADIO_COUNTRY_VA
:
923 case FM_RADIO_COUNTRY_MA
:
924 case FM_RADIO_COUNTRY_TR
:
925 settings
.upperLimit() = 10800;
926 settings
.lowerLimit() = 87500;
927 settings
.spaceType() = 100;
928 settings
.preEmphasis() = 75;
930 case FM_RADIO_COUNTRY_AU
:
931 case FM_RADIO_COUNTRY_BD
:
932 settings
.upperLimit() = 108000;
933 settings
.lowerLimit() = 87500;
934 settings
.spaceType() = 200;
935 settings
.preEmphasis() = 75;
937 case FM_RADIO_COUNTRY_AW
:
938 case FM_RADIO_COUNTRY_BS
:
939 case FM_RADIO_COUNTRY_CO
:
940 case FM_RADIO_COUNTRY_KR
:
941 settings
.upperLimit() = 108000;
942 settings
.lowerLimit() = 88000;
943 settings
.spaceType() = 200;
944 settings
.preEmphasis() = 75;
946 case FM_RADIO_COUNTRY_EC
:
947 settings
.upperLimit() = 108000;
948 settings
.lowerLimit() = 88000;
949 settings
.spaceType() = 200;
950 settings
.preEmphasis() = 0;
952 case FM_RADIO_COUNTRY_GM
:
953 settings
.upperLimit() = 108000;
954 settings
.lowerLimit() = 88000;
955 settings
.spaceType() = 0;
956 settings
.preEmphasis() = 75;
958 case FM_RADIO_COUNTRY_QA
:
959 settings
.upperLimit() = 108000;
960 settings
.lowerLimit() = 88000;
961 settings
.spaceType() = 200;
962 settings
.preEmphasis() = 50;
964 case FM_RADIO_COUNTRY_SG
:
965 settings
.upperLimit() = 108000;
966 settings
.lowerLimit() = 88000;
967 settings
.spaceType() = 200;
968 settings
.preEmphasis() = 50;
970 case FM_RADIO_COUNTRY_IN
:
971 settings
.upperLimit() = 100000;
972 settings
.lowerLimit() = 108000;
973 settings
.spaceType() = 100;
974 settings
.preEmphasis() = 50;
976 case FM_RADIO_COUNTRY_NZ
:
977 settings
.upperLimit() = 100000;
978 settings
.lowerLimit() = 88000;
979 settings
.spaceType() = 50;
980 settings
.preEmphasis() = 50;
982 case FM_RADIO_COUNTRY_USER_DEFINED
:
992 } // namespace mozilla