Bug 754472 - Implement multiple plugin click-to-play UI. r=jaws r=margaret r=dietrich
[gecko.git] / hal / Hal.cpp
blobfd89760dba0d4ae0fae35cdb0dfed44b8d402caa
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/. */
7 #include "Hal.h"
8 #include "HalImpl.h"
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"
25 #ifdef XP_WIN
26 #include <process.h>
27 #define getpid _getpid
28 #endif
30 using namespace mozilla::services;
32 #define PROXY_IF_SANDBOXED(_call) \
33 do { \
34 if (InSandbox()) { \
35 hal_sandbox::_call; \
36 } else { \
37 hal_impl::_call; \
38 } \
39 } while (0)
41 #define RETURN_PROXY_IF_SANDBOXED(_call) \
42 do { \
43 if (InSandbox()) { \
44 return hal_sandbox::_call; \
45 } else { \
46 return hal_impl::_call; \
47 } \
48 } while (0)
50 namespace mozilla {
51 namespace hal {
53 PRLogModuleInfo *sHalLog = PR_LOG_DEFINE("hal");
55 namespace {
57 void
58 AssertMainThread()
60 MOZ_ASSERT(NS_IsMainThread());
63 bool
64 InSandbox()
66 return GeckoProcessType_Content == XRE_GetProcessType();
69 void
70 AssertMainProcess()
72 MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
75 bool
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);
84 bool hidden = true;
85 doc->GetMozHidden(&hidden);
86 return !hidden;
89 StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
91 void InitLastIDToVibrate()
93 gLastIDToVibrate = new WindowIdentifier::IDArrayType();
94 ClearOnShutdown(&gLastIDToVibrate);
97 } // anonymous namespace
99 void
100 Vibrate(const nsTArray<uint32_t>& pattern, nsIDOMWindow* window)
102 Vibrate(pattern, WindowIdentifier(window));
105 void
106 Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
108 AssertMainThread();
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."));
118 return;
121 if (InSandbox()) {
122 hal_sandbox::Vibrate(pattern, id);
124 else {
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());
137 void
138 CancelVibrate(nsIDOMWindow* window)
140 CancelVibrate(WindowIdentifier(window));
143 void
144 CancelVibrate(const WindowIdentifier &id)
146 AssertMainThread();
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.
165 if (InSandbox()) {
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
180 public:
181 void AddObserver(Observer<InfoType>* aObserver) {
182 if (!mObservers) {
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);
195 if (!removed) {
196 NS_WARNING("RemoveObserver() called for unregistered observer");
197 return;
200 if (mObservers->Length() == 0) {
201 DisableNotifications();
203 OnNotificationsDisabled();
205 delete mObservers;
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.
216 if (!mObservers) {
217 return;
219 mObservers->Broadcast(aInfo);
222 protected:
223 virtual void EnableNotifications() = 0;
224 virtual void DisableNotifications() = 0;
225 virtual void OnNotificationsDisabled() {}
227 private:
228 mozilla::ObserverList<InfoType>* mObservers;
231 template <class InfoType>
232 class CachingObserversManager : public ObserversManager<InfoType>
234 public:
235 InfoType GetCurrentInformation() {
236 if (mHasValidCache) {
237 return mInfo;
240 GetCurrentInformationInternal(&mInfo);
241 mHasValidCache = true;
242 return mInfo;
245 void CacheInformation(const InfoType& aInfo) {
246 mHasValidCache = true;
247 mInfo = aInfo;
250 void BroadcastCachedInformation() {
251 this->BroadcastInformation(mInfo);
254 protected:
255 virtual void GetCurrentInformationInternal(InfoType*) = 0;
257 virtual void OnNotificationsDisabled() {
258 mHasValidCache = false;
261 private:
262 InfoType mInfo;
263 bool mHasValidCache;
266 class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
268 protected:
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>
286 protected:
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>
304 protected:
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>
318 protected:
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;
334 void
335 RegisterBatteryObserver(BatteryObserver* aObserver)
337 AssertMainThread();
338 sBatteryObservers.AddObserver(aObserver);
341 void
342 UnregisterBatteryObserver(BatteryObserver* aObserver)
344 AssertMainThread();
345 sBatteryObservers.RemoveObserver(aObserver);
348 void
349 GetCurrentBatteryInformation(BatteryInformation* aInfo)
351 AssertMainThread();
352 *aInfo = sBatteryObservers.GetCurrentInformation();
355 void
356 NotifyBatteryChange(const BatteryInformation& aInfo)
358 AssertMainThread();
359 sBatteryObservers.CacheInformation(aInfo);
360 sBatteryObservers.BroadcastCachedInformation();
363 bool GetScreenEnabled()
365 AssertMainThread();
366 RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled());
369 void SetScreenEnabled(bool enabled)
371 AssertMainThread();
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.
381 AssertMainThread();
382 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed());
385 void SetCpuSleepAllowed(bool allowed)
387 AssertMainThread();
388 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed));
391 double GetScreenBrightness()
393 AssertMainThread();
394 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness());
397 void SetScreenBrightness(double brightness)
399 AssertMainThread();
400 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
403 bool SetLight(LightType light, const hal::LightConfiguration& aConfig)
405 AssertMainThread();
406 RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig));
409 bool GetLight(LightType light, hal::LightConfiguration* aConfig)
411 AssertMainThread();
412 RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig));
415 class SystemTimeObserversManager : public ObserversManager<SystemTimeChange>
417 protected:
418 void EnableNotifications() {
419 PROXY_IF_SANDBOXED(EnableSystemTimeChangeNotifications());
422 void DisableNotifications() {
423 PROXY_IF_SANDBOXED(DisableSystemTimeChangeNotifications());
427 static SystemTimeObserversManager sSystemTimeObservers;
429 void
430 RegisterSystemTimeChangeObserver(SystemTimeObserver *aObserver)
432 AssertMainThread();
433 sSystemTimeObservers.AddObserver(aObserver);
436 void
437 UnregisterSystemTimeChangeObserver(SystemTimeObserver *aObserver)
439 AssertMainThread();
440 sSystemTimeObservers.RemoveObserver(aObserver);
443 void
444 NotifySystemTimeChange(const hal::SystemTimeChange& aReason)
446 sSystemTimeObservers.BroadcastInformation(aReason);
449 void
450 AdjustSystemClock(int64_t aDeltaMilliseconds)
452 AssertMainThread();
453 PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
456 void
457 SetTimezone(const nsCString& aTimezoneSpec)
459 AssertMainThread();
460 PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
463 nsCString
464 GetTimezone()
466 AssertMainThread();
467 RETURN_PROXY_IF_SANDBOXED(GetTimezone());
470 void
471 EnableSensorNotifications(SensorType aSensor) {
472 AssertMainThread();
473 PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
476 void
477 DisableSensorNotifications(SensorType aSensor) {
478 AssertMainThread();
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];
495 void
496 RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
497 SensorObserverList &observers = GetSensorObservers(aSensor);
499 AssertMainThread();
501 observers.AddObserver(aObserver);
502 if(observers.Length() == 1) {
503 EnableSensorNotifications(aSensor);
507 void
508 UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
509 AssertMainThread();
511 if (!gSensorObservers) {
512 return;
515 SensorObserverList &observers = GetSensorObservers(aSensor);
516 if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
517 return;
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) {
524 return;
527 delete [] gSensorObservers;
528 gSensorObservers = nullptr;
531 void
532 NotifySensorChange(const SensorData &aSensorData) {
533 SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
535 AssertMainThread();
537 observers.Broadcast(aSensorData);
540 void
541 RegisterNetworkObserver(NetworkObserver* aObserver)
543 AssertMainThread();
544 sNetworkObservers.AddObserver(aObserver);
547 void
548 UnregisterNetworkObserver(NetworkObserver* aObserver)
550 AssertMainThread();
551 sNetworkObservers.RemoveObserver(aObserver);
554 void
555 GetCurrentNetworkInformation(NetworkInformation* aInfo)
557 AssertMainThread();
558 *aInfo = sNetworkObservers.GetCurrentInformation();
561 void
562 NotifyNetworkChange(const NetworkInformation& aInfo)
564 sNetworkObservers.CacheInformation(aInfo);
565 sNetworkObservers.BroadcastCachedInformation();
568 void Reboot()
570 AssertMainProcess();
571 AssertMainThread();
572 PROXY_IF_SANDBOXED(Reboot());
575 void PowerOff()
577 AssertMainProcess();
578 AssertMainThread();
579 PROXY_IF_SANDBOXED(PowerOff());
582 void
583 RegisterWakeLockObserver(WakeLockObserver* aObserver)
585 AssertMainThread();
586 sWakeLockObservers.AddObserver(aObserver);
589 void
590 UnregisterWakeLockObserver(WakeLockObserver* aObserver)
592 AssertMainThread();
593 sWakeLockObservers.RemoveObserver(aObserver);
596 void
597 ModifyWakeLock(const nsAString &aTopic,
598 hal::WakeLockControl aLockAdjust,
599 hal::WakeLockControl aHiddenAdjust)
601 AssertMainThread();
602 PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust));
605 void
606 GetWakeLockInfo(const nsAString &aTopic, WakeLockInformation *aWakeLockInfo)
608 AssertMainThread();
609 PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
612 void
613 NotifyWakeLockChange(const WakeLockInformation& aInfo)
615 AssertMainThread();
616 sWakeLockObservers.BroadcastInformation(aInfo);
619 void
620 RegisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
622 AssertMainThread();
623 sScreenConfigurationObservers.AddObserver(aObserver);
626 void
627 UnregisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
629 AssertMainThread();
630 sScreenConfigurationObservers.RemoveObserver(aObserver);
633 void
634 GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
636 AssertMainThread();
637 *aScreenConfiguration = sScreenConfigurationObservers.GetCurrentInformation();
640 void
641 NotifyScreenConfigurationChange(const ScreenConfiguration& aScreenConfiguration)
643 sScreenConfigurationObservers.CacheInformation(aScreenConfiguration);
644 sScreenConfigurationObservers.BroadcastCachedInformation();
647 bool
648 LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
650 AssertMainThread();
651 RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation));
654 void
655 UnlockScreenOrientation()
657 AssertMainThread();
658 PROXY_IF_SANDBOXED(UnlockScreenOrientation());
661 void
662 EnableSwitchNotifications(hal::SwitchDevice aDevice) {
663 AssertMainThread();
664 PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice));
667 void
668 DisableSwitchNotifications(hal::SwitchDevice aDevice) {
669 AssertMainThread();
670 PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
673 hal::SwitchState GetCurrentSwitchState(hal::SwitchDevice aDevice)
675 AssertMainThread();
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];
692 static void
693 ReleaseObserversIfNeeded() {
694 for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
695 if (sSwitchObserverLists[i].Length() != 0)
696 return;
699 //The length of every list is 0, no observer in the list.
700 delete [] sSwitchObserverLists;
701 sSwitchObserverLists = NULL;
704 void
705 RegisterSwitchObserver(hal::SwitchDevice aDevice, hal::SwitchObserver *aObserver)
707 AssertMainThread();
708 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
709 observer.AddObserver(aObserver);
710 if (observer.Length() == 1) {
711 EnableSwitchNotifications(aDevice);
715 void
716 UnregisterSwitchObserver(hal::SwitchDevice aDevice, hal::SwitchObserver *aObserver)
718 AssertMainThread();
720 if (!sSwitchObserverLists) {
721 return;
724 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
725 if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
726 return;
729 DisableSwitchNotifications(aDevice);
730 ReleaseObserversIfNeeded();
733 void
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)
739 return;
741 SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
742 observer.Broadcast(aEvent);
745 static AlarmObserver* sAlarmObserver;
747 bool
748 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
750 MOZ_ASSERT(!InSandbox());
751 MOZ_ASSERT(!sAlarmObserver);
753 sAlarmObserver = aObserver;
754 RETURN_PROXY_IF_SANDBOXED(EnableAlarm());
757 void
758 UnregisterTheOneAlarmObserver()
760 if (sAlarmObserver) {
761 sAlarmObserver = nullptr;
762 PROXY_IF_SANDBOXED(DisableAlarm());
766 void
767 NotifyAlarmFired()
769 if (sAlarmObserver) {
770 sAlarmObserver->Notify(void_t());
774 bool
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));
782 void
783 SetProcessPriority(int aPid, ProcessPriority aPriority)
785 PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
788 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
790 static void
791 InitializeFMRadioObserver()
793 if (!sFMRadioObservers) {
794 sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
795 ClearOnShutdown(&sFMRadioObservers);
799 void
800 RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
801 AssertMainThread();
802 InitializeFMRadioObserver();
803 sFMRadioObservers->AddObserver(aFMRadioObserver);
806 void
807 UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
808 AssertMainThread();
809 InitializeFMRadioObserver();
810 sFMRadioObservers->RemoveObserver(aFMRadioObserver);
813 void
814 NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
815 InitializeFMRadioObserver();
816 sFMRadioObservers->Broadcast(aFMRadioState);
819 void
820 EnableFMRadio(const FMRadioSettings& aInfo) {
821 AssertMainThread();
822 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
825 void
826 DisableFMRadio() {
827 AssertMainThread();
828 PROXY_IF_SANDBOXED(DisableFMRadio());
831 void
832 FMRadioSeek(const FMRadioSeekDirection& aDirection) {
833 AssertMainThread();
834 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
837 void
838 GetFMRadioSettings(FMRadioSettings* aInfo) {
839 AssertMainThread();
840 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
843 void
844 SetFMRadioFrequency(const uint32_t aFrequency) {
845 AssertMainThread();
846 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
849 uint32_t
850 GetFMRadioFrequency() {
851 AssertMainThread();
852 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency());
855 bool
856 IsFMRadioOn() {
857 AssertMainThread();
858 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn());
861 uint32_t
862 GetFMRadioSignalStrength() {
863 AssertMainThread();
864 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength());
867 void
868 CancelFMRadioSeek() {
869 AssertMainThread();
870 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
873 FMRadioSettings
874 GetFMBandSettings(FMRadioCountry aCountry) {
875 FMRadioSettings settings;
877 switch (aCountry) {
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;
884 break;
885 case FM_RADIO_COUNTRY_JP_STANDARD:
886 settings.upperLimit() = 76000;
887 settings.lowerLimit() = 90000;
888 settings.spaceType() = 100;
889 settings.preEmphasis() = 50;
890 break;
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;
921 break;
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;
929 break;
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;
936 break;
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;
945 break;
946 case FM_RADIO_COUNTRY_EC:
947 settings.upperLimit() = 108000;
948 settings.lowerLimit() = 88000;
949 settings.spaceType() = 200;
950 settings.preEmphasis() = 0;
951 break;
952 case FM_RADIO_COUNTRY_GM:
953 settings.upperLimit() = 108000;
954 settings.lowerLimit() = 88000;
955 settings.spaceType() = 0;
956 settings.preEmphasis() = 75;
957 break;
958 case FM_RADIO_COUNTRY_QA:
959 settings.upperLimit() = 108000;
960 settings.lowerLimit() = 88000;
961 settings.spaceType() = 200;
962 settings.preEmphasis() = 50;
963 break;
964 case FM_RADIO_COUNTRY_SG:
965 settings.upperLimit() = 108000;
966 settings.lowerLimit() = 88000;
967 settings.spaceType() = 200;
968 settings.preEmphasis() = 50;
969 break;
970 case FM_RADIO_COUNTRY_IN:
971 settings.upperLimit() = 100000;
972 settings.lowerLimit() = 108000;
973 settings.spaceType() = 100;
974 settings.preEmphasis() = 50;
975 break;
976 case FM_RADIO_COUNTRY_NZ:
977 settings.upperLimit() = 100000;
978 settings.lowerLimit() = 88000;
979 settings.spaceType() = 50;
980 settings.preEmphasis() = 50;
981 break;
982 case FM_RADIO_COUNTRY_USER_DEFINED:
983 break;
984 default:
985 MOZ_ASSERT(0);
986 break;
988 return settings;
991 } // namespace hal
992 } // namespace mozilla