Bug 1066410 - Serious color distortion happened when plays WebRTC. r=jesup, a=bajaj
[gecko.git] / hal / Hal.cpp
blob83ca7701cb53a924a43a0ce8f2814029834f7043
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 aEnabled)
379 AssertMainThread();
380 PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled));
383 bool GetKeyLightEnabled()
385 AssertMainThread();
386 RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
389 void SetKeyLightEnabled(bool aEnabled)
391 AssertMainThread();
392 PROXY_IF_SANDBOXED(SetKeyLightEnabled(aEnabled));
395 bool GetCpuSleepAllowed()
397 // Generally for interfaces that are accessible by normal web content
398 // we should cache the result and be notified on state changes, like
399 // what the battery API does. But since this is only used by
400 // privileged interface, the synchronous getter is OK here.
401 AssertMainThread();
402 RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
405 void SetCpuSleepAllowed(bool aAllowed)
407 AssertMainThread();
408 PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed));
411 double GetScreenBrightness()
413 AssertMainThread();
414 RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
417 void SetScreenBrightness(double aBrightness)
419 AssertMainThread();
420 PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness, 0.0, 1.0)));
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 AssertMainThread();
756 PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
759 typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
761 static SwitchObserverList *sSwitchObserverLists = nullptr;
763 static SwitchObserverList&
764 GetSwitchObserverList(SwitchDevice aDevice) {
765 MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
766 if (sSwitchObserverLists == nullptr) {
767 sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
769 return sSwitchObserverLists[aDevice];
772 static void
773 ReleaseObserversIfNeeded() {
774 for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
775 if (sSwitchObserverLists[i].Length() != 0)
776 return;
779 //The length of every list is 0, no observer in the list.
780 delete [] sSwitchObserverLists;
781 sSwitchObserverLists = nullptr;
784 void
785 RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
787 AssertMainThread();
788 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
789 observer.AddObserver(aObserver);
790 if (observer.Length() == 1) {
791 EnableSwitchNotifications(aDevice);
795 void
796 UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
798 AssertMainThread();
800 if (!sSwitchObserverLists) {
801 return;
804 SwitchObserverList& observer = GetSwitchObserverList(aDevice);
805 if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
806 return;
809 DisableSwitchNotifications(aDevice);
810 ReleaseObserversIfNeeded();
813 void
814 NotifySwitchChange(const SwitchEvent& aEvent)
816 // When callback this notification, main thread may call unregister function
817 // first. We should check if this pointer is valid.
818 if (!sSwitchObserverLists)
819 return;
821 SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
822 observer.Broadcast(aEvent);
825 static AlarmObserver* sAlarmObserver;
827 bool
828 RegisterTheOneAlarmObserver(AlarmObserver* aObserver)
830 MOZ_ASSERT(!InSandbox());
831 MOZ_ASSERT(!sAlarmObserver);
833 sAlarmObserver = aObserver;
834 RETURN_PROXY_IF_SANDBOXED(EnableAlarm(), false);
837 void
838 UnregisterTheOneAlarmObserver()
840 if (sAlarmObserver) {
841 sAlarmObserver = nullptr;
842 PROXY_IF_SANDBOXED(DisableAlarm());
846 void
847 NotifyAlarmFired()
849 if (sAlarmObserver) {
850 sAlarmObserver->Notify(void_t());
854 bool
855 SetAlarm(int32_t aSeconds, int32_t aNanoseconds)
857 // It's pointless to program an alarm nothing is going to observe ...
858 MOZ_ASSERT(sAlarmObserver);
859 RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds), false);
862 void
863 SetProcessPriority(int aPid,
864 ProcessPriority aPriority,
865 ProcessCPUPriority aCPUPriority,
866 uint32_t aBackgroundLRU)
868 // n.b. The sandboxed implementation crashes; SetProcessPriority works only
869 // from the main process.
870 MOZ_ASSERT(aBackgroundLRU == 0 || aPriority == PROCESS_PRIORITY_BACKGROUND);
871 PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority, aCPUPriority,
872 aBackgroundLRU));
875 void
876 SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
878 PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
881 // From HalTypes.h.
882 const char*
883 ProcessPriorityToString(ProcessPriority aPriority)
885 switch (aPriority) {
886 case PROCESS_PRIORITY_MASTER:
887 return "MASTER";
888 case PROCESS_PRIORITY_PREALLOC:
889 return "PREALLOC";
890 case PROCESS_PRIORITY_FOREGROUND_HIGH:
891 return "FOREGROUND_HIGH";
892 case PROCESS_PRIORITY_FOREGROUND:
893 return "FOREGROUND";
894 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
895 return "FOREGROUND_KEYBOARD";
896 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
897 return "BACKGROUND_PERCEIVABLE";
898 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
899 return "BACKGROUND_HOMESCREEN";
900 case PROCESS_PRIORITY_BACKGROUND:
901 return "BACKGROUND";
902 case PROCESS_PRIORITY_UNKNOWN:
903 return "UNKNOWN";
904 default:
905 MOZ_ASSERT(false);
906 return "???";
910 const char *
911 ThreadPriorityToString(ThreadPriority aPriority)
913 switch (aPriority) {
914 case THREAD_PRIORITY_COMPOSITOR:
915 return "COMPOSITOR";
916 default:
917 MOZ_ASSERT(false);
918 return "???";
922 // From HalTypes.h.
923 const char*
924 ProcessPriorityToString(ProcessPriority aPriority,
925 ProcessCPUPriority aCPUPriority)
927 // Sorry this is ugly. At least it's all in one place.
929 // We intentionally fall through if aCPUPriority is invalid; we won't hit any
930 // of the if statements further down, so it's OK.
932 switch (aPriority) {
933 case PROCESS_PRIORITY_MASTER:
934 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
935 return "MASTER:CPU_NORMAL";
937 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
938 return "MASTER:CPU_LOW";
940 case PROCESS_PRIORITY_PREALLOC:
941 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
942 return "PREALLOC:CPU_NORMAL";
944 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
945 return "PREALLOC:CPU_LOW";
947 case PROCESS_PRIORITY_FOREGROUND_HIGH:
948 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
949 return "FOREGROUND_HIGH:CPU_NORMAL";
951 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
952 return "FOREGROUND_HIGH:CPU_LOW";
954 case PROCESS_PRIORITY_FOREGROUND:
955 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
956 return "FOREGROUND:CPU_NORMAL";
958 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
959 return "FOREGROUND:CPU_LOW";
961 case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
962 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
963 return "FOREGROUND_KEYBOARD:CPU_NORMAL";
965 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
966 return "FOREGROUND_KEYBOARD:CPU_LOW";
968 case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
969 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
970 return "BACKGROUND_PERCEIVABLE:CPU_NORMAL";
972 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
973 return "BACKGROUND_PERCEIVABLE:CPU_LOW";
975 case PROCESS_PRIORITY_BACKGROUND_HOMESCREEN:
976 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
977 return "BACKGROUND_HOMESCREEN:CPU_NORMAL";
979 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
980 return "BACKGROUND_HOMESCREEN:CPU_LOW";
982 case PROCESS_PRIORITY_BACKGROUND:
983 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
984 return "BACKGROUND:CPU_NORMAL";
986 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
987 return "BACKGROUND:CPU_LOW";
989 case PROCESS_PRIORITY_UNKNOWN:
990 if (aCPUPriority == PROCESS_CPU_PRIORITY_NORMAL) {
991 return "UNKNOWN:CPU_NORMAL";
993 if (aCPUPriority == PROCESS_CPU_PRIORITY_LOW) {
994 return "UNKNOWN:CPU_LOW";
996 default:
997 // Fall through. (|default| is here to silence warnings.)
998 break;
1001 MOZ_ASSERT(false);
1002 return "???";
1005 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
1007 static void
1008 InitializeFMRadioObserver()
1010 if (!sFMRadioObservers) {
1011 sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
1012 ClearOnShutdown(&sFMRadioObservers);
1016 void
1017 RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
1018 AssertMainThread();
1019 InitializeFMRadioObserver();
1020 sFMRadioObservers->AddObserver(aFMRadioObserver);
1023 void
1024 UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
1025 AssertMainThread();
1026 InitializeFMRadioObserver();
1027 sFMRadioObservers->RemoveObserver(aFMRadioObserver);
1030 void
1031 NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
1032 InitializeFMRadioObserver();
1033 sFMRadioObservers->Broadcast(aFMRadioState);
1036 void
1037 EnableFMRadio(const FMRadioSettings& aInfo) {
1038 AssertMainThread();
1039 PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
1042 void
1043 DisableFMRadio() {
1044 AssertMainThread();
1045 PROXY_IF_SANDBOXED(DisableFMRadio());
1048 void
1049 FMRadioSeek(const FMRadioSeekDirection& aDirection) {
1050 AssertMainThread();
1051 PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
1054 void
1055 GetFMRadioSettings(FMRadioSettings* aInfo) {
1056 AssertMainThread();
1057 PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
1060 void
1061 SetFMRadioFrequency(const uint32_t aFrequency) {
1062 AssertMainThread();
1063 PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
1066 uint32_t
1067 GetFMRadioFrequency() {
1068 AssertMainThread();
1069 RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency(), 0);
1072 bool
1073 IsFMRadioOn() {
1074 AssertMainThread();
1075 RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn(), false);
1078 uint32_t
1079 GetFMRadioSignalStrength() {
1080 AssertMainThread();
1081 RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength(), 0);
1084 void
1085 CancelFMRadioSeek() {
1086 AssertMainThread();
1087 PROXY_IF_SANDBOXED(CancelFMRadioSeek());
1090 FMRadioSettings
1091 GetFMBandSettings(FMRadioCountry aCountry) {
1092 FMRadioSettings settings;
1094 switch (aCountry) {
1095 case FM_RADIO_COUNTRY_US:
1096 case FM_RADIO_COUNTRY_EU:
1097 settings.upperLimit() = 108000;
1098 settings.lowerLimit() = 87800;
1099 settings.spaceType() = 200;
1100 settings.preEmphasis() = 75;
1101 break;
1102 case FM_RADIO_COUNTRY_JP_STANDARD:
1103 settings.upperLimit() = 76000;
1104 settings.lowerLimit() = 90000;
1105 settings.spaceType() = 100;
1106 settings.preEmphasis() = 50;
1107 break;
1108 case FM_RADIO_COUNTRY_CY:
1109 case FM_RADIO_COUNTRY_DE:
1110 case FM_RADIO_COUNTRY_DK:
1111 case FM_RADIO_COUNTRY_ES:
1112 case FM_RADIO_COUNTRY_FI:
1113 case FM_RADIO_COUNTRY_FR:
1114 case FM_RADIO_COUNTRY_HU:
1115 case FM_RADIO_COUNTRY_IR:
1116 case FM_RADIO_COUNTRY_IT:
1117 case FM_RADIO_COUNTRY_KW:
1118 case FM_RADIO_COUNTRY_LT:
1119 case FM_RADIO_COUNTRY_ML:
1120 case FM_RADIO_COUNTRY_NO:
1121 case FM_RADIO_COUNTRY_OM:
1122 case FM_RADIO_COUNTRY_PG:
1123 case FM_RADIO_COUNTRY_NL:
1124 case FM_RADIO_COUNTRY_CZ:
1125 case FM_RADIO_COUNTRY_UK:
1126 case FM_RADIO_COUNTRY_RW:
1127 case FM_RADIO_COUNTRY_SN:
1128 case FM_RADIO_COUNTRY_SI:
1129 case FM_RADIO_COUNTRY_ZA:
1130 case FM_RADIO_COUNTRY_SE:
1131 case FM_RADIO_COUNTRY_CH:
1132 case FM_RADIO_COUNTRY_TW:
1133 case FM_RADIO_COUNTRY_UA:
1134 settings.upperLimit() = 108000;
1135 settings.lowerLimit() = 87500;
1136 settings.spaceType() = 100;
1137 settings.preEmphasis() = 50;
1138 break;
1139 case FM_RADIO_COUNTRY_VA:
1140 case FM_RADIO_COUNTRY_MA:
1141 case FM_RADIO_COUNTRY_TR:
1142 settings.upperLimit() = 10800;
1143 settings.lowerLimit() = 87500;
1144 settings.spaceType() = 100;
1145 settings.preEmphasis() = 75;
1146 break;
1147 case FM_RADIO_COUNTRY_AU:
1148 case FM_RADIO_COUNTRY_BD:
1149 settings.upperLimit() = 108000;
1150 settings.lowerLimit() = 87500;
1151 settings.spaceType() = 200;
1152 settings.preEmphasis() = 75;
1153 break;
1154 case FM_RADIO_COUNTRY_AW:
1155 case FM_RADIO_COUNTRY_BS:
1156 case FM_RADIO_COUNTRY_CO:
1157 case FM_RADIO_COUNTRY_KR:
1158 settings.upperLimit() = 108000;
1159 settings.lowerLimit() = 88000;
1160 settings.spaceType() = 200;
1161 settings.preEmphasis() = 75;
1162 break;
1163 case FM_RADIO_COUNTRY_EC:
1164 settings.upperLimit() = 108000;
1165 settings.lowerLimit() = 88000;
1166 settings.spaceType() = 200;
1167 settings.preEmphasis() = 0;
1168 break;
1169 case FM_RADIO_COUNTRY_GM:
1170 settings.upperLimit() = 108000;
1171 settings.lowerLimit() = 88000;
1172 settings.spaceType() = 0;
1173 settings.preEmphasis() = 75;
1174 break;
1175 case FM_RADIO_COUNTRY_QA:
1176 settings.upperLimit() = 108000;
1177 settings.lowerLimit() = 88000;
1178 settings.spaceType() = 200;
1179 settings.preEmphasis() = 50;
1180 break;
1181 case FM_RADIO_COUNTRY_SG:
1182 settings.upperLimit() = 108000;
1183 settings.lowerLimit() = 88000;
1184 settings.spaceType() = 200;
1185 settings.preEmphasis() = 50;
1186 break;
1187 case FM_RADIO_COUNTRY_IN:
1188 settings.upperLimit() = 100000;
1189 settings.lowerLimit() = 108000;
1190 settings.spaceType() = 100;
1191 settings.preEmphasis() = 50;
1192 break;
1193 case FM_RADIO_COUNTRY_NZ:
1194 settings.upperLimit() = 100000;
1195 settings.lowerLimit() = 88000;
1196 settings.spaceType() = 50;
1197 settings.preEmphasis() = 50;
1198 break;
1199 case FM_RADIO_COUNTRY_USER_DEFINED:
1200 break;
1201 default:
1202 MOZ_ASSERT(0);
1203 break;
1205 return settings;
1208 void FactoryReset(mozilla::dom::FactoryResetReason& aReason)
1210 AssertMainThread();
1211 PROXY_IF_SANDBOXED(FactoryReset(aReason));
1214 void
1215 StartDiskSpaceWatcher()
1217 AssertMainProcess();
1218 AssertMainThread();
1219 PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
1222 void
1223 StopDiskSpaceWatcher()
1225 AssertMainProcess();
1226 AssertMainThread();
1227 PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
1230 uint32_t
1231 GetTotalSystemMemory()
1233 return hal_impl::GetTotalSystemMemory();
1236 uint32_t
1237 GetTotalSystemMemoryLevel()
1239 return hal_impl::GetTotalSystemMemoryLevel();
1242 bool IsHeadphoneEventFromInputDev()
1244 AssertMainThread();
1245 RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
1248 } // namespace hal
1249 } // namespace mozilla