Bumping gaia.json for 10 gaia revision(s) a=gaia-bump
[gecko.git] / hal / Hal.cpp
blob880a20bc2bbae284a0a33132147c2b43499062da
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 "HalLog.h"
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"
29 #ifdef XP_WIN
30 #include <process.h>
31 #define getpid _getpid
32 #endif
34 using namespace mozilla::services;
35 using namespace mozilla::dom;
37 #define PROXY_IF_SANDBOXED(_call) \
38 do { \
39 if (InSandbox()) { \
40 if (!hal_sandbox::HalChildDestroyed()) { \
41 hal_sandbox::_call; \
42 } \
43 } else { \
44 hal_impl::_call; \
45 } \
46 } while (0)
48 #define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
49 do { \
50 if (InSandbox()) { \
51 if (hal_sandbox::HalChildDestroyed()) { \
52 return defValue; \
53 } \
54 return hal_sandbox::_call; \
55 } else { \
56 return hal_impl::_call; \
57 } \
58 } while (0)
60 namespace mozilla {
61 namespace hal {
63 PRLogModuleInfo *
64 GetHalLog()
66 static PRLogModuleInfo *sHalLog;
67 if (!sHalLog) {
68 sHalLog = PR_NewLogModule("hal");
70 return sHalLog;
73 namespace {
75 void
76 AssertMainThread()
78 MOZ_ASSERT(NS_IsMainThread());
81 bool
82 InSandbox()
84 return GeckoProcessType_Content == XRE_GetProcessType();
87 void
88 AssertMainProcess()
90 MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
93 bool
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
115 void
116 Vibrate(const nsTArray<uint32_t>& pattern, nsIDOMWindow* window)
118 Vibrate(pattern, WindowIdentifier(window));
121 void
122 Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
124 AssertMainThread();
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.");
134 return;
137 if (!InSandbox()) {
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()));
150 void
151 CancelVibrate(nsIDOMWindow* window)
153 CancelVibrate(WindowIdentifier(window));
156 void
157 CancelVibrate(const WindowIdentifier &id)
159 AssertMainThread();
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
189 public:
190 void AddObserver(Observer<InfoType>* aObserver) {
191 if (!mObservers) {
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);
204 if (!removed) {
205 NS_WARNING("RemoveObserver() called for unregistered observer");
206 return;
209 if (mObservers->Length() == 0) {
210 DisableNotifications();
212 OnNotificationsDisabled();
214 delete mObservers;
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.
225 if (!mObservers) {
226 return;
228 mObservers->Broadcast(aInfo);
231 protected:
232 virtual void EnableNotifications() = 0;
233 virtual void DisableNotifications() = 0;
234 virtual void OnNotificationsDisabled() {}
236 private:
237 mozilla::ObserverList<InfoType>* mObservers;
240 template <class InfoType>
241 class CachingObserversManager : public ObserversManager<InfoType>
243 public:
244 InfoType GetCurrentInformation() {
245 if (mHasValidCache) {
246 return mInfo;
249 GetCurrentInformationInternal(&mInfo);
250 mHasValidCache = true;
251 return mInfo;
254 void CacheInformation(const InfoType& aInfo) {
255 mHasValidCache = true;
256 mInfo = aInfo;
259 void BroadcastCachedInformation() {
260 this->BroadcastInformation(mInfo);
263 protected:
264 virtual void GetCurrentInformationInternal(InfoType*) = 0;
266 virtual void OnNotificationsDisabled() {
267 mHasValidCache = false;
270 private:
271 InfoType mInfo;
272 bool mHasValidCache;
275 class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
277 protected:
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>
295 protected:
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>
313 protected:
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>
327 protected:
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;
343 void
344 RegisterBatteryObserver(BatteryObserver* aObserver)
346 AssertMainThread();
347 sBatteryObservers.AddObserver(aObserver);
350 void
351 UnregisterBatteryObserver(BatteryObserver* aObserver)
353 AssertMainThread();
354 sBatteryObservers.RemoveObserver(aObserver);
357 void
358 GetCurrentBatteryInformation(BatteryInformation* aInfo)
360 AssertMainThread();
361 *aInfo = sBatteryObservers.GetCurrentInformation();
364 void
365 NotifyBatteryChange(const BatteryInformation& aInfo)
367 AssertMainThread();
368 sBatteryObservers.CacheInformation(aInfo);
369 sBatteryObservers.BroadcastCachedInformation();
372 bool GetScreenEnabled()
374 AssertMainThread();
375 RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
378 void SetScreenEnabled(bool aEnabled)
380 AssertMainThread();
381 PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled));
384 bool GetKeyLightEnabled()
386 AssertMainThread();
387 RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
390 void SetKeyLightEnabled(bool aEnabled)
392 AssertMainThread();
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.
402 AssertMainThread();
403 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
406 void SetCpuSleepAllowed(bool aAllowed)
408 AssertMainThread();
409 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed));
412 double GetScreenBrightness()
414 AssertMainThread();
415 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
418 void SetScreenBrightness(double aBrightness)
420 AssertMainThread();
421 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness, 0.0, 1.0)));
424 class SystemClockChangeObserversManager : public ObserversManager<int64_t>
426 protected:
427 void EnableNotifications() {
428 PROXY_IF_SANDBOXED(EnableSystemClockChangeNotifications());
431 void DisableNotifications() {
432 PROXY_IF_SANDBOXED(DisableSystemClockChangeNotifications());
436 static SystemClockChangeObserversManager sSystemClockChangeObservers;
438 void
439 RegisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
441 AssertMainThread();
442 sSystemClockChangeObservers.AddObserver(aObserver);
445 void
446 UnregisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
448 AssertMainThread();
449 sSystemClockChangeObservers.RemoveObserver(aObserver);
452 void
453 NotifySystemClockChange(const int64_t& aClockDeltaMS)
455 sSystemClockChangeObservers.BroadcastInformation(aClockDeltaMS);
458 class SystemTimezoneChangeObserversManager : public ObserversManager<SystemTimezoneChangeInformation>
460 protected:
461 void EnableNotifications() {
462 PROXY_IF_SANDBOXED(EnableSystemTimezoneChangeNotifications());
465 void DisableNotifications() {
466 PROXY_IF_SANDBOXED(DisableSystemTimezoneChangeNotifications());
470 static SystemTimezoneChangeObserversManager sSystemTimezoneChangeObservers;
472 void
473 RegisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
475 AssertMainThread();
476 sSystemTimezoneChangeObservers.AddObserver(aObserver);
479 void
480 UnregisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
482 AssertMainThread();
483 sSystemTimezoneChangeObservers.RemoveObserver(aObserver);
486 void
487 NotifySystemTimezoneChange(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
489 sSystemTimezoneChangeObservers.BroadcastInformation(aSystemTimezoneChangeInfo);
492 void
493 AdjustSystemClock(int64_t aDeltaMilliseconds)
495 AssertMainThread();
496 PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
499 void
500 SetTimezone(const nsCString& aTimezoneSpec)
502 AssertMainThread();
503 PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
506 int32_t
507 GetTimezoneOffset()
509 AssertMainThread();
510 RETURN_PROXY_IF_SANDBOXED(GetTimezoneOffset(), 0);
513 nsCString
514 GetTimezone()
516 AssertMainThread();
517 RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
520 void
521 EnableSensorNotifications(SensorType aSensor) {
522 AssertMainThread();
523 PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
526 void
527 DisableSensorNotifications(SensorType aSensor) {
528 AssertMainThread();
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];
545 void
546 RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
547 SensorObserverList &observers = GetSensorObservers(aSensor);
549 AssertMainThread();
551 observers.AddObserver(aObserver);
552 if(observers.Length() == 1) {
553 EnableSensorNotifications(aSensor);
557 void
558 UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
559 AssertMainThread();
561 if (!gSensorObservers) {
562 return;
565 SensorObserverList &observers = GetSensorObservers(aSensor);
566 if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
567 return;
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) {
574 return;
577 delete [] gSensorObservers;
578 gSensorObservers = nullptr;
581 void
582 NotifySensorChange(const SensorData &aSensorData) {
583 SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
585 AssertMainThread();
587 observers.Broadcast(aSensorData);
590 void
591 RegisterNetworkObserver(NetworkObserver* aObserver)
593 AssertMainThread();
594 sNetworkObservers.AddObserver(aObserver);
597 void
598 UnregisterNetworkObserver(NetworkObserver* aObserver)
600 AssertMainThread();
601 sNetworkObservers.RemoveObserver(aObserver);
604 void
605 GetCurrentNetworkInformation(NetworkInformation* aInfo)
607 AssertMainThread();
608 *aInfo = sNetworkObservers.GetCurrentInformation();
611 void
612 NotifyNetworkChange(const NetworkInformation& aInfo)
614 sNetworkObservers.CacheInformation(aInfo);
615 sNetworkObservers.BroadcastCachedInformation();
618 void Reboot()
620 AssertMainProcess();
621 AssertMainThread();
622 PROXY_IF_SANDBOXED(Reboot());
625 void PowerOff()
627 AssertMainProcess();
628 AssertMainThread();
629 PROXY_IF_SANDBOXED(PowerOff());
632 void StartForceQuitWatchdog(ShutdownMode aMode, int32_t aTimeoutSecs)
634 AssertMainProcess();
635 AssertMainThread();
636 PROXY_IF_SANDBOXED(StartForceQuitWatchdog(aMode, aTimeoutSecs));
639 void StartMonitoringGamepadStatus()
641 PROXY_IF_SANDBOXED(StartMonitoringGamepadStatus());
644 void StopMonitoringGamepadStatus()
646 PROXY_IF_SANDBOXED(StopMonitoringGamepadStatus());
649 void
650 RegisterWakeLockObserver(WakeLockObserver* aObserver)
652 AssertMainThread();
653 sWakeLockObservers.AddObserver(aObserver);
656 void
657 UnregisterWakeLockObserver(WakeLockObserver* aObserver)
659 AssertMainThread();
660 sWakeLockObservers.RemoveObserver(aObserver);
663 void
664 ModifyWakeLock(const nsAString& aTopic,
665 WakeLockControl aLockAdjust,
666 WakeLockControl aHiddenAdjust,
667 uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */)
669 AssertMainThread();
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));
680 void
681 GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
683 AssertMainThread();
684 PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
687 void
688 NotifyWakeLockChange(const WakeLockInformation& aInfo)
690 AssertMainThread();
691 sWakeLockObservers.BroadcastInformation(aInfo);
694 void
695 RegisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
697 AssertMainThread();
698 sScreenConfigurationObservers.AddObserver(aObserver);
701 void
702 UnregisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
704 AssertMainThread();
705 sScreenConfigurationObservers.RemoveObserver(aObserver);
708 void
709 GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
711 AssertMainThread();
712 *aScreenConfiguration = sScreenConfigurationObservers.GetCurrentInformation();
715 void
716 NotifyScreenConfigurationChange(const ScreenConfiguration& aScreenConfiguration)
718 sScreenConfigurationObservers.CacheInformation(aScreenConfiguration);
719 sScreenConfigurationObservers.BroadcastCachedInformation();
722 bool
723 LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
725 AssertMainThread();
726 RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), false);
729 void
730 UnlockScreenOrientation()
732 AssertMainThread();
733 PROXY_IF_SANDBOXED(UnlockScreenOrientation());
736 void
737 EnableSwitchNotifications(SwitchDevice aDevice) {
738 AssertMainThread();
739 PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice));
742 void
743 DisableSwitchNotifications(SwitchDevice aDevice) {
744 AssertMainThread();
745 PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
748 SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
750 AssertMainThread();
751 RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
754 void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
756 AssertMainThread();
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];
773 static void
774 ReleaseObserversIfNeeded() {
775 for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
776 if (sSwitchObserverLists[i].Length() != 0)
777 return;
780 //The length of every list is 0, no observer in the list.
781 delete [] sSwitchObserverLists;
782 sSwitchObserverLists = nullptr;
785 void
786 RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
788 AssertMainThread();
789 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
790 observer.AddObserver(aObserver);
791 if (observer.Length() == 1) {
792 EnableSwitchNotifications(aDevice);
796 void
797 UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
799 AssertMainThread();
801 if (!sSwitchObserverLists) {
802 return;
805 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
806 if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
807 return;
810 DisableSwitchNotifications(aDevice);
811 ReleaseObserversIfNeeded();
814 void
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)
820 return;
822 SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
823 observer.Broadcast(aEvent);
826 static AlarmObserver* sAlarmObserver;
828 bool
829 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
831 MOZ_ASSERT(!InSandbox());
832 MOZ_ASSERT(!sAlarmObserver);
834 sAlarmObserver = aObserver;
835 RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
838 void
839 UnregisterTheOneAlarmObserver()
841 if (sAlarmObserver) {
842 sAlarmObserver = nullptr;
843 PROXY_IF_SANDBOXED(DisableAlarm());
847 void
848 NotifyAlarmFired()
850 if (sAlarmObserver) {
851 sAlarmObserver->Notify(void_t());
855 bool
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);
863 void
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));
871 void
872 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
874 PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
877 // From HalTypes.h.
878 const char*
879 ProcessPriorityToString(ProcessPriority aPriority)
881 switch (aPriority) {
882 case PROCESS_PRIORITY_MASTER:
883 return "MASTER";
884 case PROCESS_PRIORITY_PREALLOC:
885 return "PREALLOC";
886 case PROCESS_PRIORITY_FOREGROUND_HIGH:
887 return "FOREGROUND_HIGH";
888 case PROCESS_PRIORITY_FOREGROUND:
889 return "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:
897 return "BACKGROUND";
898 case PROCESS_PRIORITY_UNKNOWN:
899 return "UNKNOWN";
900 default:
901 MOZ_ASSERT(false);
902 return "???";
906 const char *
907 ThreadPriorityToString(ThreadPriority aPriority)
909 switch (aPriority) {
910 case THREAD_PRIORITY_COMPOSITOR:
911 return "COMPOSITOR";
912 default:
913 MOZ_ASSERT(false);
914 return "???";
918 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
919 static StaticAutoPtr<ObserverList<FMRadioRDSGroup> > sFMRadioRDSObservers;
921 static void
922 InitializeFMRadioObserver()
924 if (!sFMRadioObservers) {
925 sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
926 sFMRadioRDSObservers = new ObserverList<FMRadioRDSGroup>;
927 ClearOnShutdown(&sFMRadioRDSObservers);
928 ClearOnShutdown(&sFMRadioObservers);
932 void
933 RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
934 AssertMainThread();
935 InitializeFMRadioObserver();
936 sFMRadioObservers->AddObserver(aFMRadioObserver);
939 void
940 UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
941 AssertMainThread();
942 InitializeFMRadioObserver();
943 sFMRadioObservers->RemoveObserver(aFMRadioObserver);
946 void
947 NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
948 InitializeFMRadioObserver();
949 sFMRadioObservers->Broadcast(aFMRadioState);
952 void
953 RegisterFMRadioRDSObserver(FMRadioRDSObserver* aFMRadioRDSObserver) {
954 AssertMainThread();
955 InitializeFMRadioObserver();
956 sFMRadioRDSObservers->AddObserver(aFMRadioRDSObserver);
959 void
960 UnregisterFMRadioRDSObserver(FMRadioRDSObserver* aFMRadioRDSObserver) {
961 AssertMainThread();
962 InitializeFMRadioObserver();
963 sFMRadioRDSObservers->RemoveObserver(aFMRadioRDSObserver);
967 void
968 NotifyFMRadioRDSGroup(const FMRadioRDSGroup& aRDSGroup) {
969 InitializeFMRadioObserver();
970 sFMRadioRDSObservers->Broadcast(aRDSGroup);
973 void
974 EnableFMRadio(const FMRadioSettings& aInfo) {
975 AssertMainThread();
976 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
979 void
980 DisableFMRadio() {
981 AssertMainThread();
982 PROXY_IF_SANDBOXED(DisableFMRadio());
985 void
986 FMRadioSeek(const FMRadioSeekDirection& aDirection) {
987 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
990 void
991 GetFMRadioSettings(FMRadioSettings* aInfo) {
992 AssertMainThread();
993 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
996 void
997 SetFMRadioFrequency(const uint32_t aFrequency) {
998 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
1001 uint32_t
1002 GetFMRadioFrequency() {
1003 AssertMainThread();
1004 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
1007 bool
1008 IsFMRadioOn() {
1009 AssertMainThread();
1010 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
1013 uint32_t
1014 GetFMRadioSignalStrength() {
1015 AssertMainThread();
1016 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
1019 void
1020 CancelFMRadioSeek() {
1021 AssertMainThread();
1022 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
1025 bool
1026 EnableRDS(uint32_t aMask) {
1027 AssertMainThread();
1028 RETURN_PROXY_IF_SANDBOXED(EnableRDS(aMask), false);
1031 void
1032 DisableRDS() {
1033 AssertMainThread();
1034 PROXY_IF_SANDBOXED(DisableRDS());
1037 FMRadioSettings
1038 GetFMBandSettings(FMRadioCountry aCountry) {
1039 FMRadioSettings settings;
1041 switch (aCountry) {
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;
1048 break;
1049 case FM_RADIO_COUNTRY_JP_STANDARD:
1050 settings.upperLimit() = 76000;
1051 settings.lowerLimit() = 90000;
1052 settings.spaceType() = 100;
1053 settings.preEmphasis() = 50;
1054 break;
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;
1085 break;
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;
1093 break;
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;
1100 break;
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;
1109 break;
1110 case FM_RADIO_COUNTRY_EC:
1111 settings.upperLimit() = 108000;
1112 settings.lowerLimit() = 88000;
1113 settings.spaceType() = 200;
1114 settings.preEmphasis() = 0;
1115 break;
1116 case FM_RADIO_COUNTRY_GM:
1117 settings.upperLimit() = 108000;
1118 settings.lowerLimit() = 88000;
1119 settings.spaceType() = 0;
1120 settings.preEmphasis() = 75;
1121 break;
1122 case FM_RADIO_COUNTRY_QA:
1123 settings.upperLimit() = 108000;
1124 settings.lowerLimit() = 88000;
1125 settings.spaceType() = 200;
1126 settings.preEmphasis() = 50;
1127 break;
1128 case FM_RADIO_COUNTRY_SG:
1129 settings.upperLimit() = 108000;
1130 settings.lowerLimit() = 88000;
1131 settings.spaceType() = 200;
1132 settings.preEmphasis() = 50;
1133 break;
1134 case FM_RADIO_COUNTRY_IN:
1135 settings.upperLimit() = 100000;
1136 settings.lowerLimit() = 108000;
1137 settings.spaceType() = 100;
1138 settings.preEmphasis() = 50;
1139 break;
1140 case FM_RADIO_COUNTRY_NZ:
1141 settings.upperLimit() = 100000;
1142 settings.lowerLimit() = 88000;
1143 settings.spaceType() = 50;
1144 settings.preEmphasis() = 50;
1145 break;
1146 case FM_RADIO_COUNTRY_USER_DEFINED:
1147 break;
1148 default:
1149 MOZ_ASSERT(0);
1150 break;
1152 return settings;
1155 void FactoryReset(mozilla::dom::FactoryResetReason& aReason)
1157 AssertMainThread();
1158 PROXY_IF_SANDBOXED(FactoryReset(aReason));
1161 void
1162 StartDiskSpaceWatcher()
1164 AssertMainProcess();
1165 AssertMainThread();
1166 PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
1169 void
1170 StopDiskSpaceWatcher()
1172 AssertMainProcess();
1173 AssertMainThread();
1174 PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
1177 uint32_t
1178 GetTotalSystemMemory()
1180 return hal_impl::GetTotalSystemMemory();
1183 uint32_t
1184 GetTotalSystemMemoryLevel()
1186 return hal_impl::GetTotalSystemMemoryLevel();
1189 bool IsHeadphoneEventFromInputDev()
1191 AssertMainThread();
1192 RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
1195 } // namespace hal
1196 } // namespace mozilla