Backed out changeset ad0d9f62c29c (bug 206659) for B2G desktop mochitest orange.
[gecko.git] / hal / Hal.cpp
blob1673b450969114d5f9a49b7dab91758df0568074
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 "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 enabled)
380 AssertMainThread();
381 PROXY_IF_SANDBOXED(SetScreenEnabled(enabled));
384 bool GetCpuSleepAllowed()
386 // Generally for interfaces that are accessible by normal web content
387 // we should cache the result and be notified on state changes, like
388 // what the battery API does. But since this is only used by
389 // privileged interface, the synchronous getter is OK here.
390 AssertMainThread();
391 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
394 void SetCpuSleepAllowed(bool allowed)
396 AssertMainThread();
397 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed));
400 double GetScreenBrightness()
402 AssertMainThread();
403 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
406 void SetScreenBrightness(double brightness)
408 AssertMainThread();
409 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
412 bool SetLight(LightType light, const LightConfiguration& aConfig)
414 AssertMainThread();
415 RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig), false);
418 bool GetLight(LightType light, LightConfiguration* aConfig)
420 AssertMainThread();
421 RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig), false);
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 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
756 static SwitchObserverList *sSwitchObserverLists = nullptr;
758 static SwitchObserverList&
759 GetSwitchObserverList(SwitchDevice aDevice) {
760 MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
761 if (sSwitchObserverLists == nullptr) {
762 sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
764 return sSwitchObserverLists[aDevice];
767 static void
768 ReleaseObserversIfNeeded() {
769 for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
770 if (sSwitchObserverLists[i].Length() != 0)
771 return;
774 //The length of every list is 0, no observer in the list.
775 delete [] sSwitchObserverLists;
776 sSwitchObserverLists = nullptr;
779 void
780 RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
782 AssertMainThread();
783 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
784 observer.AddObserver(aObserver);
785 if (observer.Length() == 1) {
786 EnableSwitchNotifications(aDevice);
790 void
791 UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
793 AssertMainThread();
795 if (!sSwitchObserverLists) {
796 return;
799 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
800 if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
801 return;
804 DisableSwitchNotifications(aDevice);
805 ReleaseObserversIfNeeded();
808 void
809 NotifySwitchChange(const SwitchEvent& aEvent)
811 // When callback this notification, main thread may call unregister function
812 // first. We should check if this pointer is valid.
813 if (!sSwitchObserverLists)
814 return;
816 SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
817 observer.Broadcast(aEvent);
820 static AlarmObserver* sAlarmObserver;
822 bool
823 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
825 MOZ_ASSERT(!InSandbox());
826 MOZ_ASSERT(!sAlarmObserver);
828 sAlarmObserver = aObserver;
829 RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
832 void
833 UnregisterTheOneAlarmObserver()
835 if (sAlarmObserver) {
836 sAlarmObserver = nullptr;
837 PROXY_IF_SANDBOXED(DisableAlarm());
841 void
842 NotifyAlarmFired()
844 if (sAlarmObserver) {
845 sAlarmObserver->Notify(void_t());
849 bool
850 SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
852 // It's pointless to program an alarm nothing is going to observe ...
853 MOZ_ASSERT(sAlarmObserver);
854 RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds), false);
857 void
858 SetProcessPriority(int aPid,
859 ProcessPriority aPriority,
860 ProcessCPUPriority aCPUPriority,
861 uint32_t aBackgroundLRU)
863 // n.b. The sandboxed implementation crashes; SetProcessPriority works only
864 // from the main process.
865 MOZ_ASSERT(aBackgroundLRU == 0 || aPriority == PROCESS_PRIORITY_BACKGROUND);
866 PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority, aCPUPriority,
867 aBackgroundLRU));
870 // From HalTypes.h.
871 const char*
872 ProcessPriorityToString(ProcessPriority aPriority)
874 switch (aPriority) {
875 case PROCESS_PRIORITY_MASTER:
876 return "MASTER";
877 case PROCESS_PRIORITY_FOREGROUND_HIGH:
878 return "FOREGROUND_HIGH";
879 case PROCESS_PRIORITY_FOREGROUND:
880 return "FOREGROUND";
881 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
882 return "FOREGROUND_KEYBOARD";
883 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
884 return "BACKGROUND_PERCEIVABLE";
885 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
886 return "BACKGROUND_HOMESCREEN";
887 case PROCESS_PRIORITY_BACKGROUND:
888 return "BACKGROUND";
889 case PROCESS_PRIORITY_UNKNOWN:
890 return "UNKNOWN";
891 default:
892 MOZ_ASSERT(false);
893 return "???";
897 // From HalTypes.h.
898 const char*
899 ProcessPriorityToString(ProcessPriority aPriority,
900 ProcessCPUPriority aCPUPriority)
902 // Sorry this is ugly. At least it's all in one place.
904 // We intentionally fall through if aCPUPriority is invalid; we won't hit any
905 // of the if statements further down, so it's OK.
907 switch (aPriority) {
908 case PROCESS_PRIORITY_MASTER:
909 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
910 return "MASTER:CPU_NORMAL";
912 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
913 return "MASTER:CPU_LOW";
915 case PROCESS_PRIORITY_FOREGROUND_HIGH:
916 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
917 return "FOREGROUND_HIGH:CPU_NORMAL";
919 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
920 return "FOREGROUND_HIGH:CPU_LOW";
922 case PROCESS_PRIORITY_FOREGROUND:
923 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
924 return "FOREGROUND:CPU_NORMAL";
926 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
927 return "FOREGROUND:CPU_LOW";
929 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
930 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
931 return "FOREGROUND_KEYBOARD:CPU_NORMAL";
933 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
934 return "FOREGROUND_KEYBOARD:CPU_LOW";
936 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
937 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
938 return "BACKGROUND_PERCEIVABLE:CPU_NORMAL";
940 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
941 return "BACKGROUND_PERCEIVABLE:CPU_LOW";
943 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
944 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
945 return "BACKGROUND_HOMESCREEN:CPU_NORMAL";
947 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
948 return "BACKGROUND_HOMESCREEN:CPU_LOW";
950 case PROCESS_PRIORITY_BACKGROUND:
951 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
952 return "BACKGROUND:CPU_NORMAL";
954 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
955 return "BACKGROUND:CPU_LOW";
957 case PROCESS_PRIORITY_UNKNOWN:
958 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
959 return "UNKNOWN:CPU_NORMAL";
961 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
962 return "UNKNOWN:CPU_LOW";
964 default:
965 // Fall through. (|default| is here to silence warnings.)
966 break;
969 MOZ_ASSERT(false);
970 return "???";
973 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
975 static void
976 InitializeFMRadioObserver()
978 if (!sFMRadioObservers) {
979 sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
980 ClearOnShutdown(&sFMRadioObservers);
984 void
985 RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
986 AssertMainThread();
987 InitializeFMRadioObserver();
988 sFMRadioObservers->AddObserver(aFMRadioObserver);
991 void
992 UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
993 AssertMainThread();
994 InitializeFMRadioObserver();
995 sFMRadioObservers->RemoveObserver(aFMRadioObserver);
998 void
999 NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
1000 InitializeFMRadioObserver();
1001 sFMRadioObservers->Broadcast(aFMRadioState);
1004 void
1005 EnableFMRadio(const FMRadioSettings& aInfo) {
1006 AssertMainThread();
1007 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
1010 void
1011 DisableFMRadio() {
1012 AssertMainThread();
1013 PROXY_IF_SANDBOXED(DisableFMRadio());
1016 void
1017 FMRadioSeek(const FMRadioSeekDirection& aDirection) {
1018 AssertMainThread();
1019 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
1022 void
1023 GetFMRadioSettings(FMRadioSettings* aInfo) {
1024 AssertMainThread();
1025 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
1028 void
1029 SetFMRadioFrequency(const uint32_t aFrequency) {
1030 AssertMainThread();
1031 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
1034 uint32_t
1035 GetFMRadioFrequency() {
1036 AssertMainThread();
1037 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
1040 bool
1041 IsFMRadioOn() {
1042 AssertMainThread();
1043 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
1046 uint32_t
1047 GetFMRadioSignalStrength() {
1048 AssertMainThread();
1049 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
1052 void
1053 CancelFMRadioSeek() {
1054 AssertMainThread();
1055 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
1058 FMRadioSettings
1059 GetFMBandSettings(FMRadioCountry aCountry) {
1060 FMRadioSettings settings;
1062 switch (aCountry) {
1063 case FM_RADIO_COUNTRY_US:
1064 case FM_RADIO_COUNTRY_EU:
1065 settings.upperLimit() = 108000;
1066 settings.lowerLimit() = 87800;
1067 settings.spaceType() = 200;
1068 settings.preEmphasis() = 75;
1069 break;
1070 case FM_RADIO_COUNTRY_JP_STANDARD:
1071 settings.upperLimit() = 76000;
1072 settings.lowerLimit() = 90000;
1073 settings.spaceType() = 100;
1074 settings.preEmphasis() = 50;
1075 break;
1076 case FM_RADIO_COUNTRY_CY:
1077 case FM_RADIO_COUNTRY_DE:
1078 case FM_RADIO_COUNTRY_DK:
1079 case FM_RADIO_COUNTRY_ES:
1080 case FM_RADIO_COUNTRY_FI:
1081 case FM_RADIO_COUNTRY_FR:
1082 case FM_RADIO_COUNTRY_HU:
1083 case FM_RADIO_COUNTRY_IR:
1084 case FM_RADIO_COUNTRY_IT:
1085 case FM_RADIO_COUNTRY_KW:
1086 case FM_RADIO_COUNTRY_LT:
1087 case FM_RADIO_COUNTRY_ML:
1088 case FM_RADIO_COUNTRY_NO:
1089 case FM_RADIO_COUNTRY_OM:
1090 case FM_RADIO_COUNTRY_PG:
1091 case FM_RADIO_COUNTRY_NL:
1092 case FM_RADIO_COUNTRY_CZ:
1093 case FM_RADIO_COUNTRY_UK:
1094 case FM_RADIO_COUNTRY_RW:
1095 case FM_RADIO_COUNTRY_SN:
1096 case FM_RADIO_COUNTRY_SI:
1097 case FM_RADIO_COUNTRY_ZA:
1098 case FM_RADIO_COUNTRY_SE:
1099 case FM_RADIO_COUNTRY_CH:
1100 case FM_RADIO_COUNTRY_TW:
1101 case FM_RADIO_COUNTRY_UA:
1102 settings.upperLimit() = 108000;
1103 settings.lowerLimit() = 87500;
1104 settings.spaceType() = 100;
1105 settings.preEmphasis() = 50;
1106 break;
1107 case FM_RADIO_COUNTRY_VA:
1108 case FM_RADIO_COUNTRY_MA:
1109 case FM_RADIO_COUNTRY_TR:
1110 settings.upperLimit() = 10800;
1111 settings.lowerLimit() = 87500;
1112 settings.spaceType() = 100;
1113 settings.preEmphasis() = 75;
1114 break;
1115 case FM_RADIO_COUNTRY_AU:
1116 case FM_RADIO_COUNTRY_BD:
1117 settings.upperLimit() = 108000;
1118 settings.lowerLimit() = 87500;
1119 settings.spaceType() = 200;
1120 settings.preEmphasis() = 75;
1121 break;
1122 case FM_RADIO_COUNTRY_AW:
1123 case FM_RADIO_COUNTRY_BS:
1124 case FM_RADIO_COUNTRY_CO:
1125 case FM_RADIO_COUNTRY_KR:
1126 settings.upperLimit() = 108000;
1127 settings.lowerLimit() = 88000;
1128 settings.spaceType() = 200;
1129 settings.preEmphasis() = 75;
1130 break;
1131 case FM_RADIO_COUNTRY_EC:
1132 settings.upperLimit() = 108000;
1133 settings.lowerLimit() = 88000;
1134 settings.spaceType() = 200;
1135 settings.preEmphasis() = 0;
1136 break;
1137 case FM_RADIO_COUNTRY_GM:
1138 settings.upperLimit() = 108000;
1139 settings.lowerLimit() = 88000;
1140 settings.spaceType() = 0;
1141 settings.preEmphasis() = 75;
1142 break;
1143 case FM_RADIO_COUNTRY_QA:
1144 settings.upperLimit() = 108000;
1145 settings.lowerLimit() = 88000;
1146 settings.spaceType() = 200;
1147 settings.preEmphasis() = 50;
1148 break;
1149 case FM_RADIO_COUNTRY_SG:
1150 settings.upperLimit() = 108000;
1151 settings.lowerLimit() = 88000;
1152 settings.spaceType() = 200;
1153 settings.preEmphasis() = 50;
1154 break;
1155 case FM_RADIO_COUNTRY_IN:
1156 settings.upperLimit() = 100000;
1157 settings.lowerLimit() = 108000;
1158 settings.spaceType() = 100;
1159 settings.preEmphasis() = 50;
1160 break;
1161 case FM_RADIO_COUNTRY_NZ:
1162 settings.upperLimit() = 100000;
1163 settings.lowerLimit() = 88000;
1164 settings.spaceType() = 50;
1165 settings.preEmphasis() = 50;
1166 break;
1167 case FM_RADIO_COUNTRY_USER_DEFINED:
1168 break;
1169 default:
1170 MOZ_ASSERT(0);
1171 break;
1173 return settings;
1176 void FactoryReset()
1178 AssertMainThread();
1179 PROXY_IF_SANDBOXED(FactoryReset());
1182 void
1183 StartDiskSpaceWatcher()
1185 AssertMainProcess();
1186 AssertMainThread();
1187 PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
1190 void
1191 StopDiskSpaceWatcher()
1193 AssertMainProcess();
1194 AssertMainThread();
1195 PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
1198 uint32_t
1199 GetTotalSystemMemory()
1201 return hal_impl::GetTotalSystemMemory();
1205 } // namespace hal
1206 } // namespace mozilla