Bug 1011130 - Fix video seek problem in OmxDecoder r=cajbir
[gecko.git] / hal / Hal.cpp
blob58834564addbd974f7bfa754f730c48883be12df
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 "nsThreadUtils.h"
11 #include "nsXULAppAPI.h"
12 #include "mozilla/Observer.h"
13 #include "nsIDocument.h"
14 #include "nsIDOMDocument.h"
15 #include "nsPIDOMWindow.h"
16 #include "nsIDOMWindow.h"
17 #include "mozilla/Services.h"
18 #include "nsIWebNavigation.h"
19 #include "nsITabChild.h"
20 #include "nsIDocShell.h"
21 #include "mozilla/StaticPtr.h"
22 #include "mozilla/ClearOnShutdown.h"
23 #include "WindowIdentifier.h"
24 #include "mozilla/dom/ScreenOrientation.h"
25 #include "mozilla/dom/ContentChild.h"
26 #include "mozilla/dom/ContentParent.h"
28 #ifdef XP_WIN
29 #include <process.h>
30 #define getpid _getpid
31 #endif
33 using namespace mozilla::services;
34 using namespace mozilla::dom;
36 #define PROXY_IF_SANDBOXED(_call) \
37 do { \
38 if (InSandbox()) { \
39 if (!hal_sandbox::HalChildDestroyed()) { \
40 hal_sandbox::_call; \
41 } \
42 } else { \
43 hal_impl::_call; \
44 } \
45 } while (0)
47 #define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
48 do { \
49 if (InSandbox()) { \
50 if (hal_sandbox::HalChildDestroyed()) { \
51 return defValue; \
52 } \
53 return hal_sandbox::_call; \
54 } else { \
55 return hal_impl::_call; \
56 } \
57 } while (0)
59 namespace mozilla {
60 namespace hal {
62 PRLogModuleInfo *
63 GetHalLog()
65 static PRLogModuleInfo *sHalLog;
66 if (!sHalLog) {
67 sHalLog = PR_NewLogModule("hal");
69 return sHalLog;
72 namespace {
74 void
75 AssertMainThread()
77 MOZ_ASSERT(NS_IsMainThread());
80 bool
81 InSandbox()
83 return GeckoProcessType_Content == XRE_GetProcessType();
86 void
87 AssertMainProcess()
89 MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
92 bool
93 WindowIsActive(nsIDOMWindow* aWindow)
95 nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
96 NS_ENSURE_TRUE(window, false);
98 nsIDocument* document = window->GetDoc();
99 NS_ENSURE_TRUE(document, false);
101 return !document->Hidden();
104 StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
106 void InitLastIDToVibrate()
108 gLastIDToVibrate = new WindowIdentifier::IDArrayType();
109 ClearOnShutdown(&gLastIDToVibrate);
112 } // anonymous namespace
114 void
115 Vibrate(const nsTArray<uint32_t>& pattern, nsIDOMWindow* window)
117 Vibrate(pattern, WindowIdentifier(window));
120 void
121 Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
123 AssertMainThread();
125 // Only active windows may start vibrations. If |id| hasn't gone
126 // through the IPC layer -- that is, if our caller is the outside
127 // world, not hal_proxy -- check whether the window is active. If
128 // |id| has gone through IPC, don't check the window's visibility;
129 // only the window corresponding to the bottommost process has its
130 // visibility state set correctly.
131 if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
132 HAL_LOG(("Vibrate: Window is inactive, dropping vibrate."));
133 return;
136 if (!InSandbox()) {
137 if (!gLastIDToVibrate) {
138 InitLastIDToVibrate();
140 *gLastIDToVibrate = id.AsArray();
143 // Don't forward our ID if we are not in the sandbox, because hal_impl
144 // doesn't need it, and we don't want it to be tempted to read it. The
145 // empty identifier will assert if it's used.
146 PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
149 void
150 CancelVibrate(nsIDOMWindow* window)
152 CancelVibrate(WindowIdentifier(window));
155 void
156 CancelVibrate(const WindowIdentifier &id)
158 AssertMainThread();
160 // Although only active windows may start vibrations, a window may
161 // cancel its own vibration even if it's no longer active.
163 // After a window is marked as inactive, it sends a CancelVibrate
164 // request. We want this request to cancel a playing vibration
165 // started by that window, so we certainly don't want to reject the
166 // cancellation request because the window is now inactive.
168 // But it could be the case that, after this window became inactive,
169 // some other window came along and started a vibration. We don't
170 // want this window's cancellation request to cancel that window's
171 // actively-playing vibration!
173 // To solve this problem, we keep track of the id of the last window
174 // to start a vibration, and only accepts cancellation requests from
175 // the same window. All other cancellation requests are ignored.
177 if (InSandbox() || (gLastIDToVibrate && *gLastIDToVibrate == id.AsArray())) {
178 // Don't forward our ID if we are not in the sandbox, because hal_impl
179 // doesn't need it, and we don't want it to be tempted to read it. The
180 // empty identifier will assert if it's used.
181 PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id : WindowIdentifier()));
185 template <class InfoType>
186 class ObserversManager
188 public:
189 void AddObserver(Observer<InfoType>* aObserver) {
190 if (!mObservers) {
191 mObservers = new mozilla::ObserverList<InfoType>();
194 mObservers->AddObserver(aObserver);
196 if (mObservers->Length() == 1) {
197 EnableNotifications();
201 void RemoveObserver(Observer<InfoType>* aObserver) {
202 bool removed = mObservers && mObservers->RemoveObserver(aObserver);
203 if (!removed) {
204 NS_WARNING("RemoveObserver() called for unregistered observer");
205 return;
208 if (mObservers->Length() == 0) {
209 DisableNotifications();
211 OnNotificationsDisabled();
213 delete mObservers;
214 mObservers = nullptr;
218 void BroadcastInformation(const InfoType& aInfo) {
219 // It is possible for mObservers to be nullptr here on some platforms,
220 // because a call to BroadcastInformation gets queued up asynchronously
221 // while RemoveObserver is running (and before the notifications are
222 // disabled). The queued call can then get run after mObservers has
223 // been nulled out. See bug 757025.
224 if (!mObservers) {
225 return;
227 mObservers->Broadcast(aInfo);
230 protected:
231 virtual void EnableNotifications() = 0;
232 virtual void DisableNotifications() = 0;
233 virtual void OnNotificationsDisabled() {}
235 private:
236 mozilla::ObserverList<InfoType>* mObservers;
239 template <class InfoType>
240 class CachingObserversManager : public ObserversManager<InfoType>
242 public:
243 InfoType GetCurrentInformation() {
244 if (mHasValidCache) {
245 return mInfo;
248 GetCurrentInformationInternal(&mInfo);
249 mHasValidCache = true;
250 return mInfo;
253 void CacheInformation(const InfoType& aInfo) {
254 mHasValidCache = true;
255 mInfo = aInfo;
258 void BroadcastCachedInformation() {
259 this->BroadcastInformation(mInfo);
262 protected:
263 virtual void GetCurrentInformationInternal(InfoType*) = 0;
265 virtual void OnNotificationsDisabled() {
266 mHasValidCache = false;
269 private:
270 InfoType mInfo;
271 bool mHasValidCache;
274 class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
276 protected:
277 void EnableNotifications() {
278 PROXY_IF_SANDBOXED(EnableBatteryNotifications());
281 void DisableNotifications() {
282 PROXY_IF_SANDBOXED(DisableBatteryNotifications());
285 void GetCurrentInformationInternal(BatteryInformation* aInfo) {
286 PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
290 static BatteryObserversManager sBatteryObservers;
292 class NetworkObserversManager : public CachingObserversManager<NetworkInformation>
294 protected:
295 void EnableNotifications() {
296 PROXY_IF_SANDBOXED(EnableNetworkNotifications());
299 void DisableNotifications() {
300 PROXY_IF_SANDBOXED(DisableNetworkNotifications());
303 void GetCurrentInformationInternal(NetworkInformation* aInfo) {
304 PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
308 static NetworkObserversManager sNetworkObservers;
310 class WakeLockObserversManager : public ObserversManager<WakeLockInformation>
312 protected:
313 void EnableNotifications() {
314 PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
317 void DisableNotifications() {
318 PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
322 static WakeLockObserversManager sWakeLockObservers;
324 class ScreenConfigurationObserversManager : public CachingObserversManager<ScreenConfiguration>
326 protected:
327 void EnableNotifications() {
328 PROXY_IF_SANDBOXED(EnableScreenConfigurationNotifications());
331 void DisableNotifications() {
332 PROXY_IF_SANDBOXED(DisableScreenConfigurationNotifications());
335 void GetCurrentInformationInternal(ScreenConfiguration* aInfo) {
336 PROXY_IF_SANDBOXED(GetCurrentScreenConfiguration(aInfo));
340 static ScreenConfigurationObserversManager sScreenConfigurationObservers;
342 void
343 RegisterBatteryObserver(BatteryObserver* aObserver)
345 AssertMainThread();
346 sBatteryObservers.AddObserver(aObserver);
349 void
350 UnregisterBatteryObserver(BatteryObserver* aObserver)
352 AssertMainThread();
353 sBatteryObservers.RemoveObserver(aObserver);
356 void
357 GetCurrentBatteryInformation(BatteryInformation* aInfo)
359 AssertMainThread();
360 *aInfo = sBatteryObservers.GetCurrentInformation();
363 void
364 NotifyBatteryChange(const BatteryInformation& aInfo)
366 AssertMainThread();
367 sBatteryObservers.CacheInformation(aInfo);
368 sBatteryObservers.BroadcastCachedInformation();
371 bool GetScreenEnabled()
373 AssertMainThread();
374 RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
377 void SetScreenEnabled(bool enabled)
379 AssertMainThread();
380 PROXY_IF_SANDBOXED(SetScreenEnabled(enabled));
383 bool GetCpuSleepAllowed()
385 // Generally for interfaces that are accessible by normal web content
386 // we should cache the result and be notified on state changes, like
387 // what the battery API does. But since this is only used by
388 // privileged interface, the synchronous getter is OK here.
389 AssertMainThread();
390 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
393 void SetCpuSleepAllowed(bool allowed)
395 AssertMainThread();
396 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(allowed));
399 double GetScreenBrightness()
401 AssertMainThread();
402 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
405 void SetScreenBrightness(double brightness)
407 AssertMainThread();
408 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
411 bool SetLight(LightType light, const LightConfiguration& aConfig)
413 AssertMainThread();
414 RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig), false);
417 bool GetLight(LightType light, LightConfiguration* aConfig)
419 AssertMainThread();
420 RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig), false);
423 class SystemClockChangeObserversManager : public ObserversManager<int64_t>
425 protected:
426 void EnableNotifications() {
427 PROXY_IF_SANDBOXED(EnableSystemClockChangeNotifications());
430 void DisableNotifications() {
431 PROXY_IF_SANDBOXED(DisableSystemClockChangeNotifications());
435 static SystemClockChangeObserversManager sSystemClockChangeObservers;
437 void
438 RegisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
440 AssertMainThread();
441 sSystemClockChangeObservers.AddObserver(aObserver);
444 void
445 UnregisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
447 AssertMainThread();
448 sSystemClockChangeObservers.RemoveObserver(aObserver);
451 void
452 NotifySystemClockChange(const int64_t& aClockDeltaMS)
454 sSystemClockChangeObservers.BroadcastInformation(aClockDeltaMS);
457 class SystemTimezoneChangeObserversManager : public ObserversManager<SystemTimezoneChangeInformation>
459 protected:
460 void EnableNotifications() {
461 PROXY_IF_SANDBOXED(EnableSystemTimezoneChangeNotifications());
464 void DisableNotifications() {
465 PROXY_IF_SANDBOXED(DisableSystemTimezoneChangeNotifications());
469 static SystemTimezoneChangeObserversManager sSystemTimezoneChangeObservers;
471 void
472 RegisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
474 AssertMainThread();
475 sSystemTimezoneChangeObservers.AddObserver(aObserver);
478 void
479 UnregisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
481 AssertMainThread();
482 sSystemTimezoneChangeObservers.RemoveObserver(aObserver);
485 void
486 NotifySystemTimezoneChange(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
488 sSystemTimezoneChangeObservers.BroadcastInformation(aSystemTimezoneChangeInfo);
491 void
492 AdjustSystemClock(int64_t aDeltaMilliseconds)
494 AssertMainThread();
495 PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
498 void
499 SetTimezone(const nsCString& aTimezoneSpec)
501 AssertMainThread();
502 PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
505 int32_t
506 GetTimezoneOffset()
508 AssertMainThread();
509 RETURN_PROXY_IF_SANDBOXED(GetTimezoneOffset(), 0);
512 nsCString
513 GetTimezone()
515 AssertMainThread();
516 RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
519 void
520 EnableSensorNotifications(SensorType aSensor) {
521 AssertMainThread();
522 PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
525 void
526 DisableSensorNotifications(SensorType aSensor) {
527 AssertMainThread();
528 PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
531 typedef mozilla::ObserverList<SensorData> SensorObserverList;
532 static SensorObserverList* gSensorObservers = nullptr;
534 static SensorObserverList &
535 GetSensorObservers(SensorType sensor_type) {
536 MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
538 if(!gSensorObservers) {
539 gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
541 return gSensorObservers[sensor_type];
544 void
545 RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
546 SensorObserverList &observers = GetSensorObservers(aSensor);
548 AssertMainThread();
550 observers.AddObserver(aObserver);
551 if(observers.Length() == 1) {
552 EnableSensorNotifications(aSensor);
556 void
557 UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
558 AssertMainThread();
560 if (!gSensorObservers) {
561 return;
564 SensorObserverList &observers = GetSensorObservers(aSensor);
565 if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
566 return;
568 DisableSensorNotifications(aSensor);
570 // Destroy sSensorObservers only if all observer lists are empty.
571 for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
572 if (gSensorObservers[i].Length() > 0) {
573 return;
576 delete [] gSensorObservers;
577 gSensorObservers = nullptr;
580 void
581 NotifySensorChange(const SensorData &aSensorData) {
582 SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
584 AssertMainThread();
586 observers.Broadcast(aSensorData);
589 void
590 RegisterNetworkObserver(NetworkObserver* aObserver)
592 AssertMainThread();
593 sNetworkObservers.AddObserver(aObserver);
596 void
597 UnregisterNetworkObserver(NetworkObserver* aObserver)
599 AssertMainThread();
600 sNetworkObservers.RemoveObserver(aObserver);
603 void
604 GetCurrentNetworkInformation(NetworkInformation* aInfo)
606 AssertMainThread();
607 *aInfo = sNetworkObservers.GetCurrentInformation();
610 void
611 NotifyNetworkChange(const NetworkInformation& aInfo)
613 sNetworkObservers.CacheInformation(aInfo);
614 sNetworkObservers.BroadcastCachedInformation();
617 void Reboot()
619 AssertMainProcess();
620 AssertMainThread();
621 PROXY_IF_SANDBOXED(Reboot());
624 void PowerOff()
626 AssertMainProcess();
627 AssertMainThread();
628 PROXY_IF_SANDBOXED(PowerOff());
631 void StartForceQuitWatchdog(ShutdownMode aMode, int32_t aTimeoutSecs)
633 AssertMainProcess();
634 AssertMainThread();
635 PROXY_IF_SANDBOXED(StartForceQuitWatchdog(aMode, aTimeoutSecs));
638 void StartMonitoringGamepadStatus()
640 PROXY_IF_SANDBOXED(StartMonitoringGamepadStatus());
643 void StopMonitoringGamepadStatus()
645 PROXY_IF_SANDBOXED(StopMonitoringGamepadStatus());
648 void
649 RegisterWakeLockObserver(WakeLockObserver* aObserver)
651 AssertMainThread();
652 sWakeLockObservers.AddObserver(aObserver);
655 void
656 UnregisterWakeLockObserver(WakeLockObserver* aObserver)
658 AssertMainThread();
659 sWakeLockObservers.RemoveObserver(aObserver);
662 void
663 ModifyWakeLock(const nsAString& aTopic,
664 WakeLockControl aLockAdjust,
665 WakeLockControl aHiddenAdjust,
666 uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */)
668 AssertMainThread();
670 if (aProcessID == CONTENT_PROCESS_ID_UNKNOWN) {
671 aProcessID = InSandbox() ? ContentChild::GetSingleton()->GetID() :
672 CONTENT_PROCESS_ID_MAIN;
675 PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust,
676 aHiddenAdjust, aProcessID));
679 void
680 GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
682 AssertMainThread();
683 PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
686 void
687 NotifyWakeLockChange(const WakeLockInformation& aInfo)
689 AssertMainThread();
690 sWakeLockObservers.BroadcastInformation(aInfo);
693 void
694 RegisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
696 AssertMainThread();
697 sScreenConfigurationObservers.AddObserver(aObserver);
700 void
701 UnregisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
703 AssertMainThread();
704 sScreenConfigurationObservers.RemoveObserver(aObserver);
707 void
708 GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
710 AssertMainThread();
711 *aScreenConfiguration = sScreenConfigurationObservers.GetCurrentInformation();
714 void
715 NotifyScreenConfigurationChange(const ScreenConfiguration& aScreenConfiguration)
717 sScreenConfigurationObservers.CacheInformation(aScreenConfiguration);
718 sScreenConfigurationObservers.BroadcastCachedInformation();
721 bool
722 LockScreenOrientation(const dom::ScreenOrientation& aOrientation)
724 AssertMainThread();
725 RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), false);
728 void
729 UnlockScreenOrientation()
731 AssertMainThread();
732 PROXY_IF_SANDBOXED(UnlockScreenOrientation());
735 void
736 EnableSwitchNotifications(SwitchDevice aDevice) {
737 AssertMainThread();
738 PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice));
741 void
742 DisableSwitchNotifications(SwitchDevice aDevice) {
743 AssertMainThread();
744 PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
747 SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
749 AssertMainThread();
750 RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
753 void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
755 PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
758 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
760 static SwitchObserverList *sSwitchObserverLists = nullptr;
762 static SwitchObserverList&
763 GetSwitchObserverList(SwitchDevice aDevice) {
764 MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
765 if (sSwitchObserverLists == nullptr) {
766 sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
768 return sSwitchObserverLists[aDevice];
771 static void
772 ReleaseObserversIfNeeded() {
773 for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
774 if (sSwitchObserverLists[i].Length() != 0)
775 return;
778 //The length of every list is 0, no observer in the list.
779 delete [] sSwitchObserverLists;
780 sSwitchObserverLists = nullptr;
783 void
784 RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
786 AssertMainThread();
787 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
788 observer.AddObserver(aObserver);
789 if (observer.Length() == 1) {
790 EnableSwitchNotifications(aDevice);
794 void
795 UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
797 AssertMainThread();
799 if (!sSwitchObserverLists) {
800 return;
803 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
804 if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
805 return;
808 DisableSwitchNotifications(aDevice);
809 ReleaseObserversIfNeeded();
812 void
813 NotifySwitchChange(const SwitchEvent& aEvent)
815 // When callback this notification, main thread may call unregister function
816 // first. We should check if this pointer is valid.
817 if (!sSwitchObserverLists)
818 return;
820 SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
821 observer.Broadcast(aEvent);
824 static AlarmObserver* sAlarmObserver;
826 bool
827 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
829 MOZ_ASSERT(!InSandbox());
830 MOZ_ASSERT(!sAlarmObserver);
832 sAlarmObserver = aObserver;
833 RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
836 void
837 UnregisterTheOneAlarmObserver()
839 if (sAlarmObserver) {
840 sAlarmObserver = nullptr;
841 PROXY_IF_SANDBOXED(DisableAlarm());
845 void
846 NotifyAlarmFired()
848 if (sAlarmObserver) {
849 sAlarmObserver->Notify(void_t());
853 bool
854 SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
856 // It's pointless to program an alarm nothing is going to observe ...
857 MOZ_ASSERT(sAlarmObserver);
858 RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds), false);
861 void
862 SetProcessPriority(int aPid,
863 ProcessPriority aPriority,
864 ProcessCPUPriority aCPUPriority,
865 uint32_t aBackgroundLRU)
867 // n.b. The sandboxed implementation crashes; SetProcessPriority works only
868 // from the main process.
869 MOZ_ASSERT(aBackgroundLRU == 0 || aPriority == PROCESS_PRIORITY_BACKGROUND);
870 PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority, aCPUPriority,
871 aBackgroundLRU));
874 void
875 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
877 PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
880 // From HalTypes.h.
881 const char*
882 ProcessPriorityToString(ProcessPriority aPriority)
884 switch (aPriority) {
885 case PROCESS_PRIORITY_MASTER:
886 return "MASTER";
887 case PROCESS_PRIORITY_PREALLOC:
888 return "PREALLOC";
889 case PROCESS_PRIORITY_FOREGROUND_HIGH:
890 return "FOREGROUND_HIGH";
891 case PROCESS_PRIORITY_FOREGROUND:
892 return "FOREGROUND";
893 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
894 return "FOREGROUND_KEYBOARD";
895 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
896 return "BACKGROUND_PERCEIVABLE";
897 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
898 return "BACKGROUND_HOMESCREEN";
899 case PROCESS_PRIORITY_BACKGROUND:
900 return "BACKGROUND";
901 case PROCESS_PRIORITY_UNKNOWN:
902 return "UNKNOWN";
903 default:
904 MOZ_ASSERT(false);
905 return "???";
909 const char *
910 ThreadPriorityToString(ThreadPriority aPriority)
912 switch (aPriority) {
913 case THREAD_PRIORITY_COMPOSITOR:
914 return "COMPOSITOR";
915 default:
916 MOZ_ASSERT(false);
917 return "???";
921 // From HalTypes.h.
922 const char*
923 ProcessPriorityToString(ProcessPriority aPriority,
924 ProcessCPUPriority aCPUPriority)
926 // Sorry this is ugly. At least it's all in one place.
928 // We intentionally fall through if aCPUPriority is invalid; we won't hit any
929 // of the if statements further down, so it's OK.
931 switch (aPriority) {
932 case PROCESS_PRIORITY_MASTER:
933 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
934 return "MASTER:CPU_NORMAL";
936 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
937 return "MASTER:CPU_LOW";
939 case PROCESS_PRIORITY_PREALLOC:
940 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
941 return "PREALLOC:CPU_NORMAL";
943 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
944 return "PREALLOC:CPU_LOW";
946 case PROCESS_PRIORITY_FOREGROUND_HIGH:
947 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
948 return "FOREGROUND_HIGH:CPU_NORMAL";
950 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
951 return "FOREGROUND_HIGH:CPU_LOW";
953 case PROCESS_PRIORITY_FOREGROUND:
954 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
955 return "FOREGROUND:CPU_NORMAL";
957 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
958 return "FOREGROUND:CPU_LOW";
960 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
961 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
962 return "FOREGROUND_KEYBOARD:CPU_NORMAL";
964 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
965 return "FOREGROUND_KEYBOARD:CPU_LOW";
967 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
968 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
969 return "BACKGROUND_PERCEIVABLE:CPU_NORMAL";
971 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
972 return "BACKGROUND_PERCEIVABLE:CPU_LOW";
974 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
975 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
976 return "BACKGROUND_HOMESCREEN:CPU_NORMAL";
978 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
979 return "BACKGROUND_HOMESCREEN:CPU_LOW";
981 case PROCESS_PRIORITY_BACKGROUND:
982 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
983 return "BACKGROUND:CPU_NORMAL";
985 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
986 return "BACKGROUND:CPU_LOW";
988 case PROCESS_PRIORITY_UNKNOWN:
989 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
990 return "UNKNOWN:CPU_NORMAL";
992 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
993 return "UNKNOWN:CPU_LOW";
995 default:
996 // Fall through. (|default| is here to silence warnings.)
997 break;
1000 MOZ_ASSERT(false);
1001 return "???";
1004 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
1006 static void
1007 InitializeFMRadioObserver()
1009 if (!sFMRadioObservers) {
1010 sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
1011 ClearOnShutdown(&sFMRadioObservers);
1015 void
1016 RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
1017 AssertMainThread();
1018 InitializeFMRadioObserver();
1019 sFMRadioObservers->AddObserver(aFMRadioObserver);
1022 void
1023 UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
1024 AssertMainThread();
1025 InitializeFMRadioObserver();
1026 sFMRadioObservers->RemoveObserver(aFMRadioObserver);
1029 void
1030 NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
1031 InitializeFMRadioObserver();
1032 sFMRadioObservers->Broadcast(aFMRadioState);
1035 void
1036 EnableFMRadio(const FMRadioSettings& aInfo) {
1037 AssertMainThread();
1038 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
1041 void
1042 DisableFMRadio() {
1043 AssertMainThread();
1044 PROXY_IF_SANDBOXED(DisableFMRadio());
1047 void
1048 FMRadioSeek(const FMRadioSeekDirection& aDirection) {
1049 AssertMainThread();
1050 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
1053 void
1054 GetFMRadioSettings(FMRadioSettings* aInfo) {
1055 AssertMainThread();
1056 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
1059 void
1060 SetFMRadioFrequency(const uint32_t aFrequency) {
1061 AssertMainThread();
1062 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
1065 uint32_t
1066 GetFMRadioFrequency() {
1067 AssertMainThread();
1068 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
1071 bool
1072 IsFMRadioOn() {
1073 AssertMainThread();
1074 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
1077 uint32_t
1078 GetFMRadioSignalStrength() {
1079 AssertMainThread();
1080 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
1083 void
1084 CancelFMRadioSeek() {
1085 AssertMainThread();
1086 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
1089 FMRadioSettings
1090 GetFMBandSettings(FMRadioCountry aCountry) {
1091 FMRadioSettings settings;
1093 switch (aCountry) {
1094 case FM_RADIO_COUNTRY_US:
1095 case FM_RADIO_COUNTRY_EU:
1096 settings.upperLimit() = 108000;
1097 settings.lowerLimit() = 87800;
1098 settings.spaceType() = 200;
1099 settings.preEmphasis() = 75;
1100 break;
1101 case FM_RADIO_COUNTRY_JP_STANDARD:
1102 settings.upperLimit() = 76000;
1103 settings.lowerLimit() = 90000;
1104 settings.spaceType() = 100;
1105 settings.preEmphasis() = 50;
1106 break;
1107 case FM_RADIO_COUNTRY_CY:
1108 case FM_RADIO_COUNTRY_DE:
1109 case FM_RADIO_COUNTRY_DK:
1110 case FM_RADIO_COUNTRY_ES:
1111 case FM_RADIO_COUNTRY_FI:
1112 case FM_RADIO_COUNTRY_FR:
1113 case FM_RADIO_COUNTRY_HU:
1114 case FM_RADIO_COUNTRY_IR:
1115 case FM_RADIO_COUNTRY_IT:
1116 case FM_RADIO_COUNTRY_KW:
1117 case FM_RADIO_COUNTRY_LT:
1118 case FM_RADIO_COUNTRY_ML:
1119 case FM_RADIO_COUNTRY_NO:
1120 case FM_RADIO_COUNTRY_OM:
1121 case FM_RADIO_COUNTRY_PG:
1122 case FM_RADIO_COUNTRY_NL:
1123 case FM_RADIO_COUNTRY_CZ:
1124 case FM_RADIO_COUNTRY_UK:
1125 case FM_RADIO_COUNTRY_RW:
1126 case FM_RADIO_COUNTRY_SN:
1127 case FM_RADIO_COUNTRY_SI:
1128 case FM_RADIO_COUNTRY_ZA:
1129 case FM_RADIO_COUNTRY_SE:
1130 case FM_RADIO_COUNTRY_CH:
1131 case FM_RADIO_COUNTRY_TW:
1132 case FM_RADIO_COUNTRY_UA:
1133 settings.upperLimit() = 108000;
1134 settings.lowerLimit() = 87500;
1135 settings.spaceType() = 100;
1136 settings.preEmphasis() = 50;
1137 break;
1138 case FM_RADIO_COUNTRY_VA:
1139 case FM_RADIO_COUNTRY_MA:
1140 case FM_RADIO_COUNTRY_TR:
1141 settings.upperLimit() = 10800;
1142 settings.lowerLimit() = 87500;
1143 settings.spaceType() = 100;
1144 settings.preEmphasis() = 75;
1145 break;
1146 case FM_RADIO_COUNTRY_AU:
1147 case FM_RADIO_COUNTRY_BD:
1148 settings.upperLimit() = 108000;
1149 settings.lowerLimit() = 87500;
1150 settings.spaceType() = 200;
1151 settings.preEmphasis() = 75;
1152 break;
1153 case FM_RADIO_COUNTRY_AW:
1154 case FM_RADIO_COUNTRY_BS:
1155 case FM_RADIO_COUNTRY_CO:
1156 case FM_RADIO_COUNTRY_KR:
1157 settings.upperLimit() = 108000;
1158 settings.lowerLimit() = 88000;
1159 settings.spaceType() = 200;
1160 settings.preEmphasis() = 75;
1161 break;
1162 case FM_RADIO_COUNTRY_EC:
1163 settings.upperLimit() = 108000;
1164 settings.lowerLimit() = 88000;
1165 settings.spaceType() = 200;
1166 settings.preEmphasis() = 0;
1167 break;
1168 case FM_RADIO_COUNTRY_GM:
1169 settings.upperLimit() = 108000;
1170 settings.lowerLimit() = 88000;
1171 settings.spaceType() = 0;
1172 settings.preEmphasis() = 75;
1173 break;
1174 case FM_RADIO_COUNTRY_QA:
1175 settings.upperLimit() = 108000;
1176 settings.lowerLimit() = 88000;
1177 settings.spaceType() = 200;
1178 settings.preEmphasis() = 50;
1179 break;
1180 case FM_RADIO_COUNTRY_SG:
1181 settings.upperLimit() = 108000;
1182 settings.lowerLimit() = 88000;
1183 settings.spaceType() = 200;
1184 settings.preEmphasis() = 50;
1185 break;
1186 case FM_RADIO_COUNTRY_IN:
1187 settings.upperLimit() = 100000;
1188 settings.lowerLimit() = 108000;
1189 settings.spaceType() = 100;
1190 settings.preEmphasis() = 50;
1191 break;
1192 case FM_RADIO_COUNTRY_NZ:
1193 settings.upperLimit() = 100000;
1194 settings.lowerLimit() = 88000;
1195 settings.spaceType() = 50;
1196 settings.preEmphasis() = 50;
1197 break;
1198 case FM_RADIO_COUNTRY_USER_DEFINED:
1199 break;
1200 default:
1201 MOZ_ASSERT(0);
1202 break;
1204 return settings;
1207 void FactoryReset()
1209 AssertMainThread();
1210 PROXY_IF_SANDBOXED(FactoryReset());
1213 void
1214 StartDiskSpaceWatcher()
1216 AssertMainProcess();
1217 AssertMainThread();
1218 PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
1221 void
1222 StopDiskSpaceWatcher()
1224 AssertMainProcess();
1225 AssertMainThread();
1226 PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
1229 uint32_t
1230 GetTotalSystemMemory()
1232 return hal_impl::GetTotalSystemMemory();
1236 } // namespace hal
1237 } // namespace mozilla