SandboxHal.cpp (11570B)
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/. */ 6 7 #include "Hal.h" 8 #include "HalLog.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/BrowserParent.h" 14 #include "mozilla/dom/BrowserChild.h" 15 #include "mozilla/EnumeratedRange.h" 16 #include "mozilla/HalWakeLock.h" 17 #include "mozilla/Observer.h" 18 #include "WindowIdentifier.h" 19 20 using namespace mozilla; 21 using namespace mozilla::dom; 22 using namespace mozilla::hal; 23 24 namespace mozilla { 25 namespace hal_sandbox { 26 27 static bool sHalChildDestroyed = false; 28 29 bool HalChildDestroyed() { return sHalChildDestroyed; } 30 31 static PHalChild* sHal; 32 static PHalChild* Hal() { 33 if (!sHal) { 34 sHal = ContentChild::GetSingleton()->SendPHalConstructor(); 35 } 36 return sHal; 37 } 38 39 void Vibrate(const nsTArray<uint32_t>& pattern, WindowIdentifier&& id) { 40 HAL_LOG("Vibrate: Sending to parent process."); 41 42 WindowIdentifier newID(std::move(id)); 43 newID.AppendProcessID(); 44 if (BrowserChild* bc = BrowserChild::GetFrom(newID.GetWindow())) { 45 Hal()->SendVibrate(pattern, newID.AsArray(), WrapNotNull(bc)); 46 } 47 } 48 49 void CancelVibrate(WindowIdentifier&& id) { 50 HAL_LOG("CancelVibrate: Sending to parent process."); 51 52 WindowIdentifier newID(std::move(id)); 53 newID.AppendProcessID(); 54 if (BrowserChild* bc = BrowserChild::GetFrom(newID.GetWindow())) { 55 Hal()->SendCancelVibrate(newID.AsArray(), WrapNotNull(bc)); 56 } 57 } 58 59 void EnableBatteryNotifications() { Hal()->SendEnableBatteryNotifications(); } 60 61 void DisableBatteryNotifications() { Hal()->SendDisableBatteryNotifications(); } 62 63 void GetCurrentBatteryInformation(BatteryInformation* aBatteryInfo) { 64 Hal()->SendGetCurrentBatteryInformation(aBatteryInfo); 65 } 66 67 void EnableNetworkNotifications() { Hal()->SendEnableNetworkNotifications(); } 68 69 void DisableNetworkNotifications() { Hal()->SendDisableNetworkNotifications(); } 70 71 void GetCurrentNetworkInformation(NetworkInformation* aNetworkInfo) { 72 Hal()->SendGetCurrentNetworkInformation(aNetworkInfo); 73 } 74 75 RefPtr<GenericNonExclusivePromise> LockScreenOrientation( 76 const hal::ScreenOrientation& aOrientation) { 77 return Hal() 78 ->SendLockScreenOrientation(aOrientation) 79 ->Then(GetCurrentSerialEventTarget(), __func__, 80 [](const mozilla::MozPromise<nsresult, ipc::ResponseRejectReason, 81 true>::ResolveOrRejectValue& aValue) { 82 if (aValue.IsResolve()) { 83 if (NS_SUCCEEDED(aValue.ResolveValue())) { 84 return GenericNonExclusivePromise::CreateAndResolve( 85 true, __func__); 86 } 87 return GenericNonExclusivePromise::CreateAndReject( 88 aValue.ResolveValue(), __func__); 89 } 90 return GenericNonExclusivePromise::CreateAndReject( 91 NS_ERROR_FAILURE, __func__); 92 }); 93 } 94 95 void UnlockScreenOrientation() { Hal()->SendUnlockScreenOrientation(); } 96 97 void EnableSensorNotifications(SensorType aSensor) { 98 Hal()->SendEnableSensorNotifications(aSensor); 99 } 100 101 void DisableSensorNotifications(SensorType aSensor) { 102 Hal()->SendDisableSensorNotifications(aSensor); 103 } 104 105 void EnableWakeLockNotifications() { Hal()->SendEnableWakeLockNotifications(); } 106 107 void DisableWakeLockNotifications() { 108 Hal()->SendDisableWakeLockNotifications(); 109 } 110 111 void ModifyWakeLock(const nsAString& aTopic, WakeLockControl aLockAdjust, 112 WakeLockControl aHiddenAdjust) { 113 Hal()->SendModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust); 114 } 115 116 void GetWakeLockInfo(const nsAString& aTopic, 117 WakeLockInformation* aWakeLockInfo) { 118 Hal()->SendGetWakeLockInfo(aTopic, aWakeLockInfo); 119 } 120 121 bool EnableAlarm() { 122 MOZ_CRASH("Alarms can't be programmed from sandboxed contexts. Yet."); 123 } 124 125 void DisableAlarm() { 126 MOZ_CRASH("Alarms can't be programmed from sandboxed contexts. Yet."); 127 } 128 129 bool SetAlarm(int32_t aSeconds, int32_t aNanoseconds) { 130 MOZ_CRASH("Alarms can't be programmed from sandboxed contexts. Yet."); 131 } 132 133 void SetProcessPriority(int aPid, ProcessPriority aPriority) { 134 MOZ_CRASH("Only the main process may set processes' priorities."); 135 } 136 137 void PerformHapticFeedback(int32_t aType) { 138 Hal()->SendPerformHapticFeedback(aType); 139 } 140 141 class HalParent : public PHalParent, 142 public BatteryObserver, 143 public NetworkObserver, 144 public ISensorObserver, 145 public WakeLockObserver { 146 public: 147 virtual void ActorDestroy(ActorDestroyReason aWhy) override { 148 // NB: you *must* unconditionally unregister your observer here, 149 // if it *may* be registered below. 150 hal::UnregisterBatteryObserver(this); 151 hal::UnregisterNetworkObserver(this); 152 for (auto sensor : MakeEnumeratedRange(NUM_SENSOR_TYPE)) { 153 hal::UnregisterSensorObserver(sensor, this); 154 } 155 hal::UnregisterWakeLockObserver(this); 156 } 157 158 virtual mozilla::ipc::IPCResult RecvVibrate( 159 nsTArray<unsigned int>&& pattern, nsTArray<uint64_t>&& id, 160 NotNull<PBrowserParent*> browserParent) override { 161 // We give all content vibration permission. 162 // BrowserParent *browserParent = BrowserParent::GetFrom(browserParent); 163 /* xxxkhuey wtf 164 nsCOMPtr<nsIDOMWindow> window = 165 do_QueryInterface(browserParent->GetBrowserDOMWindow()); 166 */ 167 hal::Vibrate(pattern, WindowIdentifier(std::move(id), nullptr)); 168 return IPC_OK(); 169 } 170 171 virtual mozilla::ipc::IPCResult RecvCancelVibrate( 172 nsTArray<uint64_t>&& id, 173 NotNull<PBrowserParent*> browserParent) override { 174 // BrowserParent *browserParent = BrowserParent::GetFrom(browserParent); 175 /* XXXkhuey wtf 176 nsCOMPtr<nsIDOMWindow> window = 177 browserParent->GetBrowserDOMWindow(); 178 */ 179 hal::CancelVibrate(WindowIdentifier(std::move(id), nullptr)); 180 return IPC_OK(); 181 } 182 183 virtual mozilla::ipc::IPCResult RecvEnableBatteryNotifications() override { 184 // We give all content battery-status permission. 185 hal::RegisterBatteryObserver(this); 186 return IPC_OK(); 187 } 188 189 virtual mozilla::ipc::IPCResult RecvDisableBatteryNotifications() override { 190 hal::UnregisterBatteryObserver(this); 191 return IPC_OK(); 192 } 193 194 virtual mozilla::ipc::IPCResult RecvGetCurrentBatteryInformation( 195 BatteryInformation* aBatteryInfo) override { 196 // We give all content battery-status permission. 197 hal::GetCurrentBatteryInformation(aBatteryInfo); 198 return IPC_OK(); 199 } 200 201 void Notify(const BatteryInformation& aBatteryInfo) override { 202 (void)SendNotifyBatteryChange(aBatteryInfo); 203 } 204 205 virtual mozilla::ipc::IPCResult RecvEnableNetworkNotifications() override { 206 // We give all content access to this network-status information. 207 hal::RegisterNetworkObserver(this); 208 return IPC_OK(); 209 } 210 211 virtual mozilla::ipc::IPCResult RecvDisableNetworkNotifications() override { 212 hal::UnregisterNetworkObserver(this); 213 return IPC_OK(); 214 } 215 216 virtual mozilla::ipc::IPCResult RecvGetCurrentNetworkInformation( 217 NetworkInformation* aNetworkInfo) override { 218 hal::GetCurrentNetworkInformation(aNetworkInfo); 219 return IPC_OK(); 220 } 221 222 void Notify(const NetworkInformation& aNetworkInfo) override { 223 (void)SendNotifyNetworkChange(aNetworkInfo); 224 } 225 226 virtual mozilla::ipc::IPCResult RecvLockScreenOrientation( 227 const ScreenOrientation& aOrientation, 228 LockScreenOrientationResolver&& aResolve) override { 229 // FIXME/bug 777980: unprivileged content may only lock 230 // orientation while fullscreen. We should check whether the 231 // request comes from an actor in a process that might be 232 // fullscreen. We don't have that information currently. 233 234 hal::LockScreenOrientation(aOrientation) 235 ->Then( 236 GetMainThreadSerialEventTarget(), __func__, 237 [aResolve](const GenericNonExclusivePromise::ResolveOrRejectValue& 238 aValue) { 239 if (aValue.IsResolve()) { 240 MOZ_ASSERT(aValue.ResolveValue()); 241 aResolve(NS_OK); 242 return; 243 } 244 aResolve(aValue.RejectValue()); 245 }); 246 return IPC_OK(); 247 } 248 249 virtual mozilla::ipc::IPCResult RecvUnlockScreenOrientation() override { 250 hal::UnlockScreenOrientation(); 251 return IPC_OK(); 252 } 253 254 virtual mozilla::ipc::IPCResult RecvEnableSensorNotifications( 255 const SensorType& aSensor) override { 256 // We currently allow any content to register device-sensor 257 // listeners. 258 hal::RegisterSensorObserver(aSensor, this); 259 return IPC_OK(); 260 } 261 262 virtual mozilla::ipc::IPCResult RecvDisableSensorNotifications( 263 const SensorType& aSensor) override { 264 hal::UnregisterSensorObserver(aSensor, this); 265 return IPC_OK(); 266 } 267 268 void Notify(const SensorData& aSensorData) override { 269 (void)SendNotifySensorChange(aSensorData); 270 } 271 272 virtual mozilla::ipc::IPCResult RecvModifyWakeLock( 273 const nsAString& aTopic, const WakeLockControl& aLockAdjust, 274 const WakeLockControl& aHiddenAdjust) override { 275 // We allow arbitrary content to use wake locks. 276 uint64_t id = static_cast<ContentParent*>(Manager())->ChildID(); 277 hal_impl::ModifyWakeLockWithChildID(aTopic, aLockAdjust, aHiddenAdjust, id); 278 return IPC_OK(); 279 } 280 281 virtual mozilla::ipc::IPCResult RecvEnableWakeLockNotifications() override { 282 // We allow arbitrary content to use wake locks. 283 hal::RegisterWakeLockObserver(this); 284 return IPC_OK(); 285 } 286 287 virtual mozilla::ipc::IPCResult RecvDisableWakeLockNotifications() override { 288 hal::UnregisterWakeLockObserver(this); 289 return IPC_OK(); 290 } 291 292 virtual mozilla::ipc::IPCResult RecvGetWakeLockInfo( 293 const nsAString& aTopic, WakeLockInformation* aWakeLockInfo) override { 294 hal::GetWakeLockInfo(aTopic, aWakeLockInfo); 295 return IPC_OK(); 296 } 297 298 void Notify(const WakeLockInformation& aWakeLockInfo) override { 299 (void)SendNotifyWakeLockChange(aWakeLockInfo); 300 } 301 302 virtual mozilla::ipc::IPCResult RecvPerformHapticFeedback( 303 const int32_t& aType) override { 304 hal::PerformHapticFeedback(aType); 305 return IPC_OK(); 306 } 307 }; 308 309 class HalChild : public PHalChild { 310 public: 311 virtual void ActorDestroy(ActorDestroyReason aWhy) override { 312 sHalChildDestroyed = true; 313 } 314 315 virtual mozilla::ipc::IPCResult RecvNotifyBatteryChange( 316 const BatteryInformation& aBatteryInfo) override { 317 hal::NotifyBatteryChange(aBatteryInfo); 318 return IPC_OK(); 319 } 320 321 virtual mozilla::ipc::IPCResult RecvNotifySensorChange( 322 const hal::SensorData& aSensorData) override; 323 324 virtual mozilla::ipc::IPCResult RecvNotifyNetworkChange( 325 const NetworkInformation& aNetworkInfo) override { 326 hal::NotifyNetworkChange(aNetworkInfo); 327 return IPC_OK(); 328 } 329 330 virtual mozilla::ipc::IPCResult RecvNotifyWakeLockChange( 331 const WakeLockInformation& aWakeLockInfo) override { 332 hal::NotifyWakeLockChange(aWakeLockInfo); 333 return IPC_OK(); 334 } 335 }; 336 337 mozilla::ipc::IPCResult HalChild::RecvNotifySensorChange( 338 const hal::SensorData& aSensorData) { 339 hal::NotifySensorChange(aSensorData); 340 341 return IPC_OK(); 342 } 343 344 PHalChild* CreateHalChild() { return new HalChild(); } 345 346 PHalParent* CreateHalParent() { return new HalParent(); } 347 348 } // namespace hal_sandbox 349 } // namespace mozilla