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/. */
8 #include "mozilla/AppProcessChecker.h"
9 #include "mozilla/dom/ContentChild.h"
10 #include "mozilla/dom/ContentParent.h"
11 #include "mozilla/hal_sandbox/PHalChild.h"
12 #include "mozilla/hal_sandbox/PHalParent.h"
13 #include "mozilla/dom/TabParent.h"
14 #include "mozilla/dom/TabChild.h"
15 #include "mozilla/dom/battery/Types.h"
16 #include "mozilla/dom/network/Types.h"
17 #include "mozilla/dom/ScreenOrientation.h"
18 #include "mozilla/Observer.h"
19 #include "mozilla/unused.h"
20 #include "WindowIdentifier.h"
22 using namespace mozilla
;
23 using namespace mozilla::dom
;
24 using namespace mozilla::hal
;
27 namespace hal_sandbox
{
29 static bool sHalChildDestroyed
= false;
34 return sHalChildDestroyed
;
37 static PHalChild
* sHal
;
42 sHal
= ContentChild::GetSingleton()->SendPHalConstructor();
48 Vibrate(const nsTArray
<uint32_t>& pattern
, const WindowIdentifier
&id
)
50 HAL_LOG(("Vibrate: Sending to parent process."));
52 AutoInfallibleTArray
<uint32_t, 8> p(pattern
);
54 WindowIdentifier
newID(id
);
55 newID
.AppendProcessID();
56 Hal()->SendVibrate(p
, newID
.AsArray(), TabChild::GetFrom(newID
.GetWindow()));
60 CancelVibrate(const WindowIdentifier
&id
)
62 HAL_LOG(("CancelVibrate: Sending to parent process."));
64 WindowIdentifier
newID(id
);
65 newID
.AppendProcessID();
66 Hal()->SendCancelVibrate(newID
.AsArray(), TabChild::GetFrom(newID
.GetWindow()));
70 EnableBatteryNotifications()
72 Hal()->SendEnableBatteryNotifications();
76 DisableBatteryNotifications()
78 Hal()->SendDisableBatteryNotifications();
82 GetCurrentBatteryInformation(BatteryInformation
* aBatteryInfo
)
84 Hal()->SendGetCurrentBatteryInformation(aBatteryInfo
);
88 EnableNetworkNotifications()
90 Hal()->SendEnableNetworkNotifications();
94 DisableNetworkNotifications()
96 Hal()->SendDisableNetworkNotifications();
100 GetCurrentNetworkInformation(NetworkInformation
* aNetworkInfo
)
102 Hal()->SendGetCurrentNetworkInformation(aNetworkInfo
);
106 EnableScreenConfigurationNotifications()
108 Hal()->SendEnableScreenConfigurationNotifications();
112 DisableScreenConfigurationNotifications()
114 Hal()->SendDisableScreenConfigurationNotifications();
118 GetCurrentScreenConfiguration(ScreenConfiguration
* aScreenConfiguration
)
120 Hal()->SendGetCurrentScreenConfiguration(aScreenConfiguration
);
124 LockScreenOrientation(const dom::ScreenOrientation
& aOrientation
)
127 Hal()->SendLockScreenOrientation(aOrientation
, &allowed
);
132 UnlockScreenOrientation()
134 Hal()->SendUnlockScreenOrientation();
140 bool enabled
= false;
141 Hal()->SendGetScreenEnabled(&enabled
);
146 SetScreenEnabled(bool aEnabled
)
148 Hal()->SendSetScreenEnabled(aEnabled
);
154 bool enabled
= false;
155 Hal()->SendGetKeyLightEnabled(&enabled
);
160 SetKeyLightEnabled(bool aEnabled
)
162 Hal()->SendSetKeyLightEnabled(aEnabled
);
169 Hal()->SendGetCpuSleepAllowed(&allowed
);
174 SetCpuSleepAllowed(bool aAllowed
)
176 Hal()->SendSetCpuSleepAllowed(aAllowed
);
180 GetScreenBrightness()
182 double brightness
= 0;
183 Hal()->SendGetScreenBrightness(&brightness
);
188 SetScreenBrightness(double aBrightness
)
190 Hal()->SendSetScreenBrightness(aBrightness
);
194 AdjustSystemClock(int64_t aDeltaMilliseconds
)
196 Hal()->SendAdjustSystemClock(aDeltaMilliseconds
);
200 SetTimezone(const nsCString
& aTimezoneSpec
)
202 Hal()->SendSetTimezone(nsCString(aTimezoneSpec
));
209 Hal()->SendGetTimezone(&timezone
);
216 int32_t timezoneOffset
;
217 Hal()->SendGetTimezoneOffset(&timezoneOffset
);
218 return timezoneOffset
;
222 EnableSystemClockChangeNotifications()
224 Hal()->SendEnableSystemClockChangeNotifications();
228 DisableSystemClockChangeNotifications()
230 Hal()->SendDisableSystemClockChangeNotifications();
234 EnableSystemTimezoneChangeNotifications()
236 Hal()->SendEnableSystemTimezoneChangeNotifications();
240 DisableSystemTimezoneChangeNotifications()
242 Hal()->SendDisableSystemTimezoneChangeNotifications();
248 NS_RUNTIMEABORT("Reboot() can't be called from sandboxed contexts.");
254 NS_RUNTIMEABORT("PowerOff() can't be called from sandboxed contexts.");
258 StartForceQuitWatchdog(ShutdownMode aMode
, int32_t aTimeoutSecs
)
260 NS_RUNTIMEABORT("StartForceQuitWatchdog() can't be called from sandboxed contexts.");
264 EnableSensorNotifications(SensorType aSensor
) {
265 Hal()->SendEnableSensorNotifications(aSensor
);
269 DisableSensorNotifications(SensorType aSensor
) {
270 Hal()->SendDisableSensorNotifications(aSensor
);
273 //TODO: bug 852944 - IPC implementations of these
274 void StartMonitoringGamepadStatus()
277 void StopMonitoringGamepadStatus()
281 EnableWakeLockNotifications()
283 Hal()->SendEnableWakeLockNotifications();
287 DisableWakeLockNotifications()
289 Hal()->SendDisableWakeLockNotifications();
293 ModifyWakeLock(const nsAString
&aTopic
,
294 WakeLockControl aLockAdjust
,
295 WakeLockControl aHiddenAdjust
,
298 MOZ_ASSERT(aProcessID
!= CONTENT_PROCESS_ID_UNKNOWN
);
299 Hal()->SendModifyWakeLock(nsString(aTopic
), aLockAdjust
, aHiddenAdjust
, aProcessID
);
303 GetWakeLockInfo(const nsAString
&aTopic
, WakeLockInformation
*aWakeLockInfo
)
305 Hal()->SendGetWakeLockInfo(nsString(aTopic
), aWakeLockInfo
);
309 EnableSwitchNotifications(SwitchDevice aDevice
)
311 Hal()->SendEnableSwitchNotifications(aDevice
);
315 DisableSwitchNotifications(SwitchDevice aDevice
)
317 Hal()->SendDisableSwitchNotifications(aDevice
);
321 GetCurrentSwitchState(SwitchDevice aDevice
)
324 Hal()->SendGetCurrentSwitchState(aDevice
, &state
);
329 NotifySwitchStateFromInputDevice(SwitchDevice aDevice
, SwitchState aState
)
333 NS_RUNTIMEABORT("Only the main process may notify switch state change.");
339 NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts. Yet.");
346 NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts. Yet.");
350 SetAlarm(int32_t aSeconds
, int32_t aNanoseconds
)
352 NS_RUNTIMEABORT("Alarms can't be programmed from sandboxed contexts. Yet.");
357 SetProcessPriority(int aPid
,
358 ProcessPriority aPriority
,
359 ProcessCPUPriority aCPUPriority
,
360 uint32_t aBackgroundLRU
)
362 NS_RUNTIMEABORT("Only the main process may set processes' priorities.");
366 SetCurrentThreadPriority(ThreadPriority aThreadPriority
)
368 NS_RUNTIMEABORT("Setting thread priority cannot be called from sandboxed contexts.");
372 EnableFMRadio(const hal::FMRadioSettings
& aSettings
)
374 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
380 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
384 FMRadioSeek(const hal::FMRadioSeekDirection
& aDirection
)
386 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
390 GetFMRadioSettings(FMRadioSettings
* aSettings
)
392 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
396 SetFMRadioFrequency(const uint32_t aFrequency
)
398 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
402 GetFMRadioFrequency()
404 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
411 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
416 GetFMRadioSignalStrength()
418 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
425 NS_RUNTIMEABORT("FM radio cannot be called from sandboxed contexts.");
429 FactoryReset(FactoryResetReason
& aReason
)
431 if (aReason
== FactoryResetReason::Normal
) {
432 Hal()->SendFactoryReset(NS_LITERAL_STRING("normal"));
433 } else if (aReason
== FactoryResetReason::Wipe
) {
434 Hal()->SendFactoryReset(NS_LITERAL_STRING("wipe"));
439 StartDiskSpaceWatcher()
441 NS_RUNTIMEABORT("StartDiskSpaceWatcher() can't be called from sandboxed contexts.");
445 StopDiskSpaceWatcher()
447 NS_RUNTIMEABORT("StopDiskSpaceWatcher() can't be called from sandboxed contexts.");
450 bool IsHeadphoneEventFromInputDev()
452 NS_RUNTIMEABORT("IsHeadphoneEventFromInputDev() cannot be called from sandboxed contexts.");
456 class HalParent
: public PHalParent
457 , public BatteryObserver
458 , public NetworkObserver
459 , public ISensorObserver
460 , public WakeLockObserver
461 , public ScreenConfigurationObserver
462 , public SwitchObserver
463 , public SystemClockChangeObserver
464 , public SystemTimezoneChangeObserver
468 ActorDestroy(ActorDestroyReason aWhy
) MOZ_OVERRIDE
470 // NB: you *must* unconditionally unregister your observer here,
471 // if it *may* be registered below.
472 hal::UnregisterBatteryObserver(this);
473 hal::UnregisterNetworkObserver(this);
474 hal::UnregisterScreenConfigurationObserver(this);
475 for (int32_t sensor
= SENSOR_UNKNOWN
+ 1;
476 sensor
< NUM_SENSOR_TYPE
; ++sensor
) {
477 hal::UnregisterSensorObserver(SensorType(sensor
), this);
479 hal::UnregisterWakeLockObserver(this);
480 hal::UnregisterSystemClockChangeObserver(this);
481 hal::UnregisterSystemTimezoneChangeObserver(this);
482 for (int32_t switchDevice
= SWITCH_DEVICE_UNKNOWN
+ 1;
483 switchDevice
< NUM_SWITCH_DEVICE
; ++switchDevice
) {
484 hal::UnregisterSwitchObserver(SwitchDevice(switchDevice
), this);
489 RecvVibrate(const InfallibleTArray
<unsigned int>& pattern
,
490 const InfallibleTArray
<uint64_t> &id
,
491 PBrowserParent
*browserParent
) MOZ_OVERRIDE
493 // We give all content vibration permission.
494 TabParent
*tabParent
= static_cast<TabParent
*>(browserParent
);
495 nsCOMPtr
<nsIDOMWindow
> window
=
496 do_QueryInterface(tabParent
->GetBrowserDOMWindow());
497 WindowIdentifier
newID(id
, window
);
498 hal::Vibrate(pattern
, newID
);
503 RecvCancelVibrate(const InfallibleTArray
<uint64_t> &id
,
504 PBrowserParent
*browserParent
) MOZ_OVERRIDE
506 TabParent
*tabParent
= static_cast<TabParent
*>(browserParent
);
507 nsCOMPtr
<nsIDOMWindow
> window
=
508 do_QueryInterface(tabParent
->GetBrowserDOMWindow());
509 WindowIdentifier
newID(id
, window
);
510 hal::CancelVibrate(newID
);
515 RecvEnableBatteryNotifications() MOZ_OVERRIDE
{
516 // We give all content battery-status permission.
517 hal::RegisterBatteryObserver(this);
522 RecvDisableBatteryNotifications() MOZ_OVERRIDE
{
523 hal::UnregisterBatteryObserver(this);
528 RecvGetCurrentBatteryInformation(BatteryInformation
* aBatteryInfo
) MOZ_OVERRIDE
{
529 // We give all content battery-status permission.
530 hal::GetCurrentBatteryInformation(aBatteryInfo
);
534 void Notify(const BatteryInformation
& aBatteryInfo
) MOZ_OVERRIDE
{
535 unused
<< SendNotifyBatteryChange(aBatteryInfo
);
539 RecvEnableNetworkNotifications() MOZ_OVERRIDE
{
540 // We give all content access to this network-status information.
541 hal::RegisterNetworkObserver(this);
546 RecvDisableNetworkNotifications() MOZ_OVERRIDE
{
547 hal::UnregisterNetworkObserver(this);
552 RecvGetCurrentNetworkInformation(NetworkInformation
* aNetworkInfo
) MOZ_OVERRIDE
{
553 hal::GetCurrentNetworkInformation(aNetworkInfo
);
557 void Notify(const NetworkInformation
& aNetworkInfo
) {
558 unused
<< SendNotifyNetworkChange(aNetworkInfo
);
562 RecvEnableScreenConfigurationNotifications() MOZ_OVERRIDE
{
563 // Screen configuration is used to implement CSS and DOM
564 // properties, so all content already has access to this.
565 hal::RegisterScreenConfigurationObserver(this);
570 RecvDisableScreenConfigurationNotifications() MOZ_OVERRIDE
{
571 hal::UnregisterScreenConfigurationObserver(this);
576 RecvGetCurrentScreenConfiguration(ScreenConfiguration
* aScreenConfiguration
) MOZ_OVERRIDE
{
577 hal::GetCurrentScreenConfiguration(aScreenConfiguration
);
582 RecvLockScreenOrientation(const dom::ScreenOrientation
& aOrientation
, bool* aAllowed
) MOZ_OVERRIDE
584 // FIXME/bug 777980: unprivileged content may only lock
585 // orientation while fullscreen. We should check whether the
586 // request comes from an actor in a process that might be
587 // fullscreen. We don't have that information currently.
588 *aAllowed
= hal::LockScreenOrientation(aOrientation
);
593 RecvUnlockScreenOrientation() MOZ_OVERRIDE
595 hal::UnlockScreenOrientation();
599 void Notify(const ScreenConfiguration
& aScreenConfiguration
) {
600 unused
<< SendNotifyScreenConfigurationChange(aScreenConfiguration
);
604 RecvGetScreenEnabled(bool* aEnabled
) MOZ_OVERRIDE
606 if (!AssertAppProcessPermission(this, "power")) {
609 *aEnabled
= hal::GetScreenEnabled();
614 RecvSetScreenEnabled(const bool& aEnabled
) MOZ_OVERRIDE
616 if (!AssertAppProcessPermission(this, "power")) {
619 hal::SetScreenEnabled(aEnabled
);
624 RecvGetKeyLightEnabled(bool* aEnabled
) MOZ_OVERRIDE
626 if (!AssertAppProcessPermission(this, "power")) {
629 *aEnabled
= hal::GetKeyLightEnabled();
634 RecvSetKeyLightEnabled(const bool& aEnabled
) MOZ_OVERRIDE
636 if (!AssertAppProcessPermission(this, "power")) {
639 hal::SetKeyLightEnabled(aEnabled
);
644 RecvGetCpuSleepAllowed(bool* aAllowed
) MOZ_OVERRIDE
646 if (!AssertAppProcessPermission(this, "power")) {
649 *aAllowed
= hal::GetCpuSleepAllowed();
654 RecvSetCpuSleepAllowed(const bool& aAllowed
) MOZ_OVERRIDE
656 if (!AssertAppProcessPermission(this, "power")) {
659 hal::SetCpuSleepAllowed(aAllowed
);
664 RecvGetScreenBrightness(double* aBrightness
) MOZ_OVERRIDE
666 if (!AssertAppProcessPermission(this, "power")) {
669 *aBrightness
= hal::GetScreenBrightness();
674 RecvSetScreenBrightness(const double& aBrightness
) MOZ_OVERRIDE
676 if (!AssertAppProcessPermission(this, "power")) {
679 hal::SetScreenBrightness(aBrightness
);
684 RecvAdjustSystemClock(const int64_t &aDeltaMilliseconds
) MOZ_OVERRIDE
686 if (!AssertAppProcessPermission(this, "time")) {
689 hal::AdjustSystemClock(aDeltaMilliseconds
);
694 RecvSetTimezone(const nsCString
& aTimezoneSpec
) MOZ_OVERRIDE
696 if (!AssertAppProcessPermission(this, "time")) {
699 hal::SetTimezone(aTimezoneSpec
);
704 RecvGetTimezone(nsCString
*aTimezoneSpec
) MOZ_OVERRIDE
706 if (!AssertAppProcessPermission(this, "time")) {
709 *aTimezoneSpec
= hal::GetTimezone();
714 RecvGetTimezoneOffset(int32_t *aTimezoneOffset
) MOZ_OVERRIDE
716 if (!AssertAppProcessPermission(this, "time")) {
719 *aTimezoneOffset
= hal::GetTimezoneOffset();
724 RecvEnableSystemClockChangeNotifications() MOZ_OVERRIDE
726 hal::RegisterSystemClockChangeObserver(this);
731 RecvDisableSystemClockChangeNotifications() MOZ_OVERRIDE
733 hal::UnregisterSystemClockChangeObserver(this);
738 RecvEnableSystemTimezoneChangeNotifications() MOZ_OVERRIDE
740 hal::RegisterSystemTimezoneChangeObserver(this);
745 RecvDisableSystemTimezoneChangeNotifications() MOZ_OVERRIDE
747 hal::UnregisterSystemTimezoneChangeObserver(this);
752 RecvEnableSensorNotifications(const SensorType
&aSensor
) MOZ_OVERRIDE
{
753 // We currently allow any content to register device-sensor
755 hal::RegisterSensorObserver(aSensor
, this);
760 RecvDisableSensorNotifications(const SensorType
&aSensor
) MOZ_OVERRIDE
{
761 hal::UnregisterSensorObserver(aSensor
, this);
765 void Notify(const SensorData
& aSensorData
) {
766 unused
<< SendNotifySensorChange(aSensorData
);
770 RecvModifyWakeLock(const nsString
& aTopic
,
771 const WakeLockControl
& aLockAdjust
,
772 const WakeLockControl
& aHiddenAdjust
,
773 const uint64_t& aProcessID
) MOZ_OVERRIDE
775 MOZ_ASSERT(aProcessID
!= CONTENT_PROCESS_ID_UNKNOWN
);
777 // We allow arbitrary content to use wake locks.
778 hal::ModifyWakeLock(aTopic
, aLockAdjust
, aHiddenAdjust
, aProcessID
);
783 RecvEnableWakeLockNotifications() MOZ_OVERRIDE
785 // We allow arbitrary content to use wake locks.
786 hal::RegisterWakeLockObserver(this);
791 RecvDisableWakeLockNotifications() MOZ_OVERRIDE
793 hal::UnregisterWakeLockObserver(this);
798 RecvGetWakeLockInfo(const nsString
&aTopic
, WakeLockInformation
*aWakeLockInfo
) MOZ_OVERRIDE
800 hal::GetWakeLockInfo(aTopic
, aWakeLockInfo
);
804 void Notify(const WakeLockInformation
& aWakeLockInfo
)
806 unused
<< SendNotifyWakeLockChange(aWakeLockInfo
);
810 RecvEnableSwitchNotifications(const SwitchDevice
& aDevice
) MOZ_OVERRIDE
812 // Content has no reason to listen to switch events currently.
813 hal::RegisterSwitchObserver(aDevice
, this);
818 RecvDisableSwitchNotifications(const SwitchDevice
& aDevice
) MOZ_OVERRIDE
820 hal::UnregisterSwitchObserver(aDevice
, this);
824 void Notify(const SwitchEvent
& aSwitchEvent
)
826 unused
<< SendNotifySwitchChange(aSwitchEvent
);
830 RecvGetCurrentSwitchState(const SwitchDevice
& aDevice
, hal::SwitchState
*aState
) MOZ_OVERRIDE
832 // Content has no reason to listen to switch events currently.
833 *aState
= hal::GetCurrentSwitchState(aDevice
);
837 void Notify(const int64_t& aClockDeltaMS
)
839 unused
<< SendNotifySystemClockChange(aClockDeltaMS
);
842 void Notify(const SystemTimezoneChangeInformation
& aSystemTimezoneChangeInfo
)
844 unused
<< SendNotifySystemTimezoneChange(aSystemTimezoneChangeInfo
);
848 RecvFactoryReset(const nsString
& aReason
) MOZ_OVERRIDE
850 if (!AssertAppProcessPermission(this, "power")) {
854 FactoryResetReason reason
= FactoryResetReason::Normal
;
855 if (aReason
.EqualsLiteral("normal")) {
856 reason
= FactoryResetReason::Normal
;
857 } else if (aReason
.EqualsLiteral("wipe")) {
858 reason
= FactoryResetReason::Wipe
;
860 // Invalid factory reset reason. That should never happen.
864 hal::FactoryReset(reason
);
868 virtual mozilla::ipc::IProtocol
*
869 CloneProtocol(Channel
* aChannel
,
870 mozilla::ipc::ProtocolCloneContext
* aCtx
) MOZ_OVERRIDE
872 ContentParent
* contentParent
= aCtx
->GetContentParent();
873 nsAutoPtr
<PHalParent
> actor(contentParent
->AllocPHalParent());
874 if (!actor
|| !contentParent
->RecvPHalConstructor(actor
)) {
877 return actor
.forget();
881 class HalChild
: public PHalChild
{
884 ActorDestroy(ActorDestroyReason aWhy
) MOZ_OVERRIDE
886 sHalChildDestroyed
= true;
890 RecvNotifyBatteryChange(const BatteryInformation
& aBatteryInfo
) MOZ_OVERRIDE
{
891 hal::NotifyBatteryChange(aBatteryInfo
);
896 RecvNotifySensorChange(const hal::SensorData
&aSensorData
) MOZ_OVERRIDE
;
899 RecvNotifyNetworkChange(const NetworkInformation
& aNetworkInfo
) MOZ_OVERRIDE
{
900 hal::NotifyNetworkChange(aNetworkInfo
);
905 RecvNotifyWakeLockChange(const WakeLockInformation
& aWakeLockInfo
) MOZ_OVERRIDE
{
906 hal::NotifyWakeLockChange(aWakeLockInfo
);
911 RecvNotifyScreenConfigurationChange(const ScreenConfiguration
& aScreenConfiguration
) MOZ_OVERRIDE
{
912 hal::NotifyScreenConfigurationChange(aScreenConfiguration
);
917 RecvNotifySwitchChange(const mozilla::hal::SwitchEvent
& aEvent
) MOZ_OVERRIDE
{
918 hal::NotifySwitchChange(aEvent
);
923 RecvNotifySystemClockChange(const int64_t& aClockDeltaMS
) {
924 hal::NotifySystemClockChange(aClockDeltaMS
);
929 RecvNotifySystemTimezoneChange(
930 const SystemTimezoneChangeInformation
& aSystemTimezoneChangeInfo
) {
931 hal::NotifySystemTimezoneChange(aSystemTimezoneChangeInfo
);
937 HalChild::RecvNotifySensorChange(const hal::SensorData
&aSensorData
) {
938 hal::NotifySensorChange(aSensorData
);
943 PHalChild
* CreateHalChild() {
944 return new HalChild();
947 PHalParent
* CreateHalParent() {
948 return new HalParent();
951 } // namespace hal_sandbox
952 } // namespace mozilla