Line data Source code
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 :
9 : #include "HalImpl.h"
10 : #include "HalLog.h"
11 : #include "HalSandbox.h"
12 : #include "nsIDOMDocument.h"
13 : #include "nsIDOMWindow.h"
14 : #include "nsIDocument.h"
15 : #include "nsIDocShell.h"
16 : #include "nsITabChild.h"
17 : #include "nsIWebNavigation.h"
18 : #include "nsThreadUtils.h"
19 : #include "nsXULAppAPI.h"
20 : #include "nsPIDOMWindow.h"
21 : #include "nsJSUtils.h"
22 : #include "mozilla/ClearOnShutdown.h"
23 : #include "mozilla/Observer.h"
24 : #include "mozilla/Services.h"
25 : #include "mozilla/StaticPtr.h"
26 : #include "mozilla/dom/ContentChild.h"
27 : #include "mozilla/dom/ContentParent.h"
28 : #include "mozilla/dom/ScreenOrientation.h"
29 : #include "WindowIdentifier.h"
30 :
31 : #ifdef XP_WIN
32 : #include <process.h>
33 : #define getpid _getpid
34 : #endif
35 :
36 : using namespace mozilla::services;
37 : using namespace mozilla::dom;
38 :
39 : #define PROXY_IF_SANDBOXED(_call) \
40 : do { \
41 : if (InSandbox()) { \
42 : if (!hal_sandbox::HalChildDestroyed()) { \
43 : hal_sandbox::_call; \
44 : } \
45 : } else { \
46 : hal_impl::_call; \
47 : } \
48 : } while (0)
49 :
50 : #define RETURN_PROXY_IF_SANDBOXED(_call, defValue)\
51 : do { \
52 : if (InSandbox()) { \
53 : if (hal_sandbox::HalChildDestroyed()) { \
54 : return defValue; \
55 : } \
56 : return hal_sandbox::_call; \
57 : } else { \
58 : return hal_impl::_call; \
59 : } \
60 : } while (0)
61 :
62 : namespace mozilla {
63 : namespace hal {
64 :
65 : mozilla::LogModule *
66 1 : GetHalLog()
67 : {
68 : static mozilla::LazyLogModule sHalLog("hal");
69 1 : return sHalLog;
70 : }
71 :
72 : namespace {
73 :
74 : void
75 76 : AssertMainThread()
76 : {
77 76 : MOZ_ASSERT(NS_IsMainThread());
78 76 : }
79 :
80 : bool
81 7 : InSandbox()
82 : {
83 7 : return GeckoProcessType_Content == XRE_GetProcessType();
84 : }
85 :
86 : void
87 0 : AssertMainProcess()
88 : {
89 0 : MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
90 0 : }
91 :
92 : #if !defined(MOZ_WIDGET_GONK)
93 :
94 : bool
95 0 : WindowIsActive(nsPIDOMWindowInner* aWindow)
96 : {
97 0 : nsIDocument* document = aWindow->GetDoc();
98 0 : NS_ENSURE_TRUE(document, false);
99 :
100 0 : return !document->Hidden();
101 : }
102 :
103 : #endif // !defined(MOZ_WIDGET_GONK)
104 :
105 3 : StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
106 :
107 0 : void InitLastIDToVibrate()
108 : {
109 0 : gLastIDToVibrate = new WindowIdentifier::IDArrayType();
110 0 : ClearOnShutdown(&gLastIDToVibrate);
111 0 : }
112 :
113 : } // namespace
114 :
115 : void
116 0 : Vibrate(const nsTArray<uint32_t>& pattern, nsPIDOMWindowInner* window)
117 : {
118 0 : Vibrate(pattern, WindowIdentifier(window));
119 0 : }
120 :
121 : void
122 0 : Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id)
123 : {
124 0 : AssertMainThread();
125 :
126 : #if !defined(MOZ_WIDGET_GONK)
127 : // Only active windows may start vibrations. If |id| hasn't gone
128 : // through the IPC layer -- that is, if our caller is the outside
129 : // world, not hal_proxy -- check whether the window is active. If
130 : // |id| has gone through IPC, don't check the window's visibility;
131 : // only the window corresponding to the bottommost process has its
132 : // visibility state set correctly.
133 0 : if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
134 0 : HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
135 0 : return;
136 : }
137 : #endif // !defined(MOZ_WIDGET_GONK)
138 :
139 0 : if (!InSandbox()) {
140 0 : if (!gLastIDToVibrate) {
141 0 : InitLastIDToVibrate();
142 : }
143 0 : *gLastIDToVibrate = id.AsArray();
144 : }
145 :
146 : // Don't forward our ID if we are not in the sandbox, because hal_impl
147 : // doesn't need it, and we don't want it to be tempted to read it. The
148 : // empty identifier will assert if it's used.
149 0 : PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier()));
150 : }
151 :
152 : void
153 0 : CancelVibrate(nsPIDOMWindowInner* window)
154 : {
155 0 : CancelVibrate(WindowIdentifier(window));
156 0 : }
157 :
158 : void
159 0 : CancelVibrate(const WindowIdentifier &id)
160 : {
161 0 : AssertMainThread();
162 :
163 : // Although only active windows may start vibrations, a window may
164 : // cancel its own vibration even if it's no longer active.
165 : //
166 : // After a window is marked as inactive, it sends a CancelVibrate
167 : // request. We want this request to cancel a playing vibration
168 : // started by that window, so we certainly don't want to reject the
169 : // cancellation request because the window is now inactive.
170 : //
171 : // But it could be the case that, after this window became inactive,
172 : // some other window came along and started a vibration. We don't
173 : // want this window's cancellation request to cancel that window's
174 : // actively-playing vibration!
175 : //
176 : // To solve this problem, we keep track of the id of the last window
177 : // to start a vibration, and only accepts cancellation requests from
178 : // the same window. All other cancellation requests are ignored.
179 :
180 0 : if (InSandbox() || (gLastIDToVibrate && *gLastIDToVibrate == id.AsArray())) {
181 : // Don't forward our ID if we are not in the sandbox, because hal_impl
182 : // doesn't need it, and we don't want it to be tempted to read it. The
183 : // empty identifier will assert if it's used.
184 0 : PROXY_IF_SANDBOXED(CancelVibrate(InSandbox() ? id : WindowIdentifier()));
185 : }
186 0 : }
187 :
188 : template <class InfoType>
189 5 : class ObserversManager
190 : {
191 : public:
192 6 : void AddObserver(Observer<InfoType>* aObserver) {
193 6 : if (!mObservers) {
194 5 : mObservers = new mozilla::ObserverList<InfoType>();
195 : }
196 :
197 6 : mObservers->AddObserver(aObserver);
198 :
199 6 : if (mObservers->Length() == 1) {
200 5 : EnableNotifications();
201 : }
202 6 : }
203 :
204 0 : void RemoveObserver(Observer<InfoType>* aObserver) {
205 0 : bool removed = mObservers && mObservers->RemoveObserver(aObserver);
206 0 : if (!removed) {
207 0 : return;
208 : }
209 :
210 0 : if (mObservers->Length() == 0) {
211 0 : DisableNotifications();
212 :
213 0 : OnNotificationsDisabled();
214 :
215 0 : delete mObservers;
216 0 : mObservers = nullptr;
217 : }
218 : }
219 :
220 0 : void BroadcastInformation(const InfoType& aInfo) {
221 : // It is possible for mObservers to be nullptr here on some platforms,
222 : // because a call to BroadcastInformation gets queued up asynchronously
223 : // while RemoveObserver is running (and before the notifications are
224 : // disabled). The queued call can then get run after mObservers has
225 : // been nulled out. See bug 757025.
226 0 : if (!mObservers) {
227 0 : return;
228 : }
229 0 : mObservers->Broadcast(aInfo);
230 : }
231 :
232 : protected:
233 : virtual void EnableNotifications() = 0;
234 : virtual void DisableNotifications() = 0;
235 0 : virtual void OnNotificationsDisabled() {}
236 :
237 : private:
238 : mozilla::ObserverList<InfoType>* mObservers;
239 : };
240 :
241 : template <class InfoType>
242 1 : class CachingObserversManager : public ObserversManager<InfoType>
243 : {
244 : public:
245 34 : InfoType GetCurrentInformation() {
246 34 : if (mHasValidCache) {
247 33 : return mInfo;
248 : }
249 :
250 1 : GetCurrentInformationInternal(&mInfo);
251 1 : mHasValidCache = true;
252 1 : return mInfo;
253 : }
254 :
255 0 : void CacheInformation(const InfoType& aInfo) {
256 0 : mHasValidCache = true;
257 0 : mInfo = aInfo;
258 0 : }
259 :
260 0 : void BroadcastCachedInformation() {
261 0 : this->BroadcastInformation(mInfo);
262 0 : }
263 :
264 : protected:
265 : virtual void GetCurrentInformationInternal(InfoType*) = 0;
266 :
267 0 : void OnNotificationsDisabled() override {
268 0 : mHasValidCache = false;
269 0 : }
270 :
271 : private:
272 : InfoType mInfo;
273 : bool mHasValidCache;
274 : };
275 :
276 0 : class BatteryObserversManager : public CachingObserversManager<BatteryInformation>
277 : {
278 : protected:
279 0 : void EnableNotifications() override {
280 0 : PROXY_IF_SANDBOXED(EnableBatteryNotifications());
281 0 : }
282 :
283 0 : void DisableNotifications() override {
284 0 : PROXY_IF_SANDBOXED(DisableBatteryNotifications());
285 0 : }
286 :
287 0 : void GetCurrentInformationInternal(BatteryInformation* aInfo) override {
288 0 : PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
289 0 : }
290 : };
291 :
292 : static BatteryObserversManager&
293 0 : BatteryObservers()
294 : {
295 0 : static BatteryObserversManager sBatteryObservers;
296 0 : AssertMainThread();
297 0 : return sBatteryObservers;
298 : }
299 :
300 0 : class NetworkObserversManager : public CachingObserversManager<NetworkInformation>
301 : {
302 : protected:
303 0 : void EnableNotifications() override {
304 0 : PROXY_IF_SANDBOXED(EnableNetworkNotifications());
305 0 : }
306 :
307 0 : void DisableNotifications() override {
308 0 : PROXY_IF_SANDBOXED(DisableNetworkNotifications());
309 0 : }
310 :
311 0 : void GetCurrentInformationInternal(NetworkInformation* aInfo) override {
312 0 : PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
313 0 : }
314 : };
315 :
316 : static NetworkObserversManager&
317 0 : NetworkObservers()
318 : {
319 0 : static NetworkObserversManager sNetworkObservers;
320 0 : AssertMainThread();
321 0 : return sNetworkObservers;
322 : }
323 :
324 1 : class WakeLockObserversManager : public ObserversManager<WakeLockInformation>
325 : {
326 : protected:
327 1 : void EnableNotifications() override {
328 1 : PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
329 1 : }
330 :
331 0 : void DisableNotifications() override {
332 0 : PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
333 0 : }
334 : };
335 :
336 : static WakeLockObserversManager&
337 1 : WakeLockObservers()
338 : {
339 1 : static WakeLockObserversManager sWakeLockObservers;
340 1 : AssertMainThread();
341 1 : return sWakeLockObservers;
342 : }
343 :
344 1 : class ScreenConfigurationObserversManager : public CachingObserversManager<ScreenConfiguration>
345 : {
346 : protected:
347 1 : void EnableNotifications() override {
348 1 : PROXY_IF_SANDBOXED(EnableScreenConfigurationNotifications());
349 1 : }
350 :
351 0 : void DisableNotifications() override {
352 0 : PROXY_IF_SANDBOXED(DisableScreenConfigurationNotifications());
353 0 : }
354 :
355 1 : void GetCurrentInformationInternal(ScreenConfiguration* aInfo) override {
356 1 : PROXY_IF_SANDBOXED(GetCurrentScreenConfiguration(aInfo));
357 1 : }
358 : };
359 :
360 : static ScreenConfigurationObserversManager&
361 35 : ScreenConfigurationObservers()
362 : {
363 35 : AssertMainThread();
364 35 : static ScreenConfigurationObserversManager sScreenConfigurationObservers;
365 35 : return sScreenConfigurationObservers;
366 : }
367 :
368 : void
369 0 : RegisterBatteryObserver(BatteryObserver* aObserver)
370 : {
371 0 : AssertMainThread();
372 0 : BatteryObservers().AddObserver(aObserver);
373 0 : }
374 :
375 : void
376 0 : UnregisterBatteryObserver(BatteryObserver* aObserver)
377 : {
378 0 : AssertMainThread();
379 0 : BatteryObservers().RemoveObserver(aObserver);
380 0 : }
381 :
382 : void
383 0 : GetCurrentBatteryInformation(BatteryInformation* aInfo)
384 : {
385 0 : AssertMainThread();
386 0 : *aInfo = BatteryObservers().GetCurrentInformation();
387 0 : }
388 :
389 : void
390 0 : NotifyBatteryChange(const BatteryInformation& aInfo)
391 : {
392 0 : AssertMainThread();
393 0 : BatteryObservers().CacheInformation(aInfo);
394 0 : BatteryObservers().BroadcastCachedInformation();
395 0 : }
396 :
397 0 : bool GetScreenEnabled()
398 : {
399 0 : AssertMainThread();
400 0 : RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled(), false);
401 : }
402 :
403 0 : void SetScreenEnabled(bool aEnabled)
404 : {
405 0 : AssertMainThread();
406 0 : PROXY_IF_SANDBOXED(SetScreenEnabled(aEnabled));
407 0 : }
408 :
409 0 : bool GetKeyLightEnabled()
410 : {
411 0 : AssertMainThread();
412 0 : RETURN_PROXY_IF_SANDBOXED(GetKeyLightEnabled(), false);
413 : }
414 :
415 0 : void SetKeyLightEnabled(bool aEnabled)
416 : {
417 0 : AssertMainThread();
418 0 : PROXY_IF_SANDBOXED(SetKeyLightEnabled(aEnabled));
419 0 : }
420 :
421 0 : bool GetCpuSleepAllowed()
422 : {
423 : // Generally for interfaces that are accessible by normal web content
424 : // we should cache the result and be notified on state changes, like
425 : // what the battery API does. But since this is only used by
426 : // privileged interface, the synchronous getter is OK here.
427 0 : AssertMainThread();
428 0 : RETURN_PROXY_IF_SANDBOXED(GetCpuSleepAllowed(), true);
429 : }
430 :
431 0 : void SetCpuSleepAllowed(bool aAllowed)
432 : {
433 0 : AssertMainThread();
434 0 : PROXY_IF_SANDBOXED(SetCpuSleepAllowed(aAllowed));
435 0 : }
436 :
437 0 : double GetScreenBrightness()
438 : {
439 0 : AssertMainThread();
440 0 : RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness(), 0);
441 : }
442 :
443 0 : void SetScreenBrightness(double aBrightness)
444 : {
445 0 : AssertMainThread();
446 0 : PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(aBrightness, 0.0, 1.0)));
447 0 : }
448 :
449 0 : class SystemClockChangeObserversManager : public ObserversManager<int64_t>
450 : {
451 : protected:
452 0 : void EnableNotifications() override {
453 0 : PROXY_IF_SANDBOXED(EnableSystemClockChangeNotifications());
454 0 : }
455 :
456 0 : void DisableNotifications() override {
457 0 : PROXY_IF_SANDBOXED(DisableSystemClockChangeNotifications());
458 0 : }
459 : };
460 :
461 : static SystemClockChangeObserversManager&
462 0 : SystemClockChangeObservers()
463 : {
464 0 : static SystemClockChangeObserversManager sSystemClockChangeObservers;
465 0 : AssertMainThread();
466 0 : return sSystemClockChangeObservers;
467 : }
468 :
469 : void
470 0 : RegisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
471 : {
472 0 : AssertMainThread();
473 0 : SystemClockChangeObservers().AddObserver(aObserver);
474 0 : }
475 :
476 : void
477 0 : UnregisterSystemClockChangeObserver(SystemClockChangeObserver* aObserver)
478 : {
479 0 : AssertMainThread();
480 0 : SystemClockChangeObservers().RemoveObserver(aObserver);
481 0 : }
482 :
483 : void
484 0 : NotifySystemClockChange(const int64_t& aClockDeltaMS)
485 : {
486 0 : SystemClockChangeObservers().BroadcastInformation(aClockDeltaMS);
487 0 : }
488 :
489 3 : class SystemTimezoneChangeObserversManager : public ObserversManager<SystemTimezoneChangeInformation>
490 : {
491 : protected:
492 3 : void EnableNotifications() override {
493 3 : PROXY_IF_SANDBOXED(EnableSystemTimezoneChangeNotifications());
494 3 : }
495 :
496 0 : void DisableNotifications() override {
497 0 : PROXY_IF_SANDBOXED(DisableSystemTimezoneChangeNotifications());
498 0 : }
499 : };
500 :
501 : static SystemTimezoneChangeObserversManager&
502 4 : SystemTimezoneChangeObservers()
503 : {
504 4 : static SystemTimezoneChangeObserversManager sSystemTimezoneChangeObservers;
505 4 : return sSystemTimezoneChangeObservers;
506 : }
507 :
508 : void
509 4 : RegisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
510 : {
511 4 : AssertMainThread();
512 4 : SystemTimezoneChangeObservers().AddObserver(aObserver);
513 4 : }
514 :
515 : void
516 0 : UnregisterSystemTimezoneChangeObserver(SystemTimezoneChangeObserver* aObserver)
517 : {
518 0 : AssertMainThread();
519 0 : SystemTimezoneChangeObservers().RemoveObserver(aObserver);
520 0 : }
521 :
522 : void
523 0 : NotifySystemTimezoneChange(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
524 : {
525 0 : nsJSUtils::ResetTimeZone();
526 0 : SystemTimezoneChangeObservers().BroadcastInformation(aSystemTimezoneChangeInfo);
527 0 : }
528 :
529 : void
530 0 : AdjustSystemClock(int64_t aDeltaMilliseconds)
531 : {
532 0 : AssertMainThread();
533 0 : PROXY_IF_SANDBOXED(AdjustSystemClock(aDeltaMilliseconds));
534 0 : }
535 :
536 : void
537 0 : SetTimezone(const nsCString& aTimezoneSpec)
538 : {
539 0 : AssertMainThread();
540 0 : PROXY_IF_SANDBOXED(SetTimezone(aTimezoneSpec));
541 0 : }
542 :
543 : int32_t
544 0 : GetTimezoneOffset()
545 : {
546 0 : AssertMainThread();
547 0 : RETURN_PROXY_IF_SANDBOXED(GetTimezoneOffset(), 0);
548 : }
549 :
550 : nsCString
551 0 : GetTimezone()
552 : {
553 0 : AssertMainThread();
554 0 : RETURN_PROXY_IF_SANDBOXED(GetTimezone(), nsCString(""));
555 : }
556 :
557 : void
558 0 : EnableSensorNotifications(SensorType aSensor) {
559 0 : AssertMainThread();
560 0 : PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
561 0 : }
562 :
563 : void
564 0 : DisableSensorNotifications(SensorType aSensor) {
565 0 : AssertMainThread();
566 0 : PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
567 0 : }
568 :
569 : typedef mozilla::ObserverList<SensorData> SensorObserverList;
570 : static SensorObserverList* gSensorObservers = nullptr;
571 :
572 : static SensorObserverList &
573 0 : GetSensorObservers(SensorType sensor_type) {
574 0 : MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
575 :
576 0 : if(!gSensorObservers) {
577 0 : gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
578 : }
579 0 : return gSensorObservers[sensor_type];
580 : }
581 :
582 : void
583 0 : RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
584 0 : SensorObserverList &observers = GetSensorObservers(aSensor);
585 :
586 0 : AssertMainThread();
587 :
588 0 : observers.AddObserver(aObserver);
589 0 : if(observers.Length() == 1) {
590 0 : EnableSensorNotifications(aSensor);
591 : }
592 0 : }
593 :
594 : void
595 0 : UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
596 0 : AssertMainThread();
597 :
598 0 : if (!gSensorObservers) {
599 0 : return;
600 : }
601 :
602 0 : SensorObserverList &observers = GetSensorObservers(aSensor);
603 0 : if (!observers.RemoveObserver(aObserver) || observers.Length() > 0) {
604 0 : return;
605 : }
606 0 : DisableSensorNotifications(aSensor);
607 :
608 : // Destroy sSensorObservers only if all observer lists are empty.
609 0 : for (int i = 0; i < NUM_SENSOR_TYPE; i++) {
610 0 : if (gSensorObservers[i].Length() > 0) {
611 0 : return;
612 : }
613 : }
614 0 : delete [] gSensorObservers;
615 0 : gSensorObservers = nullptr;
616 : }
617 :
618 : void
619 0 : NotifySensorChange(const SensorData &aSensorData) {
620 0 : SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
621 :
622 0 : AssertMainThread();
623 :
624 0 : observers.Broadcast(aSensorData);
625 0 : }
626 :
627 : void
628 0 : RegisterNetworkObserver(NetworkObserver* aObserver)
629 : {
630 0 : AssertMainThread();
631 0 : NetworkObservers().AddObserver(aObserver);
632 0 : }
633 :
634 : void
635 0 : UnregisterNetworkObserver(NetworkObserver* aObserver)
636 : {
637 0 : AssertMainThread();
638 0 : NetworkObservers().RemoveObserver(aObserver);
639 0 : }
640 :
641 : void
642 0 : GetCurrentNetworkInformation(NetworkInformation* aInfo)
643 : {
644 0 : AssertMainThread();
645 0 : *aInfo = NetworkObservers().GetCurrentInformation();
646 0 : }
647 :
648 : void
649 0 : NotifyNetworkChange(const NetworkInformation& aInfo)
650 : {
651 0 : NetworkObservers().CacheInformation(aInfo);
652 0 : NetworkObservers().BroadcastCachedInformation();
653 0 : }
654 :
655 0 : void Reboot()
656 : {
657 0 : AssertMainProcess();
658 0 : AssertMainThread();
659 0 : PROXY_IF_SANDBOXED(Reboot());
660 0 : }
661 :
662 0 : void PowerOff()
663 : {
664 0 : AssertMainProcess();
665 0 : AssertMainThread();
666 0 : PROXY_IF_SANDBOXED(PowerOff());
667 0 : }
668 :
669 0 : void StartForceQuitWatchdog(ShutdownMode aMode, int32_t aTimeoutSecs)
670 : {
671 0 : AssertMainProcess();
672 0 : AssertMainThread();
673 0 : PROXY_IF_SANDBOXED(StartForceQuitWatchdog(aMode, aTimeoutSecs));
674 0 : }
675 :
676 : void
677 1 : RegisterWakeLockObserver(WakeLockObserver* aObserver)
678 : {
679 1 : AssertMainThread();
680 1 : WakeLockObservers().AddObserver(aObserver);
681 1 : }
682 :
683 : void
684 0 : UnregisterWakeLockObserver(WakeLockObserver* aObserver)
685 : {
686 0 : AssertMainThread();
687 0 : WakeLockObservers().RemoveObserver(aObserver);
688 0 : }
689 :
690 : void
691 0 : ModifyWakeLock(const nsAString& aTopic,
692 : WakeLockControl aLockAdjust,
693 : WakeLockControl aHiddenAdjust,
694 : uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */)
695 : {
696 0 : AssertMainThread();
697 :
698 0 : if (aProcessID == CONTENT_PROCESS_ID_UNKNOWN) {
699 0 : aProcessID = InSandbox() ? ContentChild::GetSingleton()->GetID() :
700 0 : CONTENT_PROCESS_ID_MAIN;
701 : }
702 :
703 0 : PROXY_IF_SANDBOXED(ModifyWakeLock(aTopic, aLockAdjust,
704 : aHiddenAdjust, aProcessID));
705 0 : }
706 :
707 : void
708 0 : GetWakeLockInfo(const nsAString& aTopic, WakeLockInformation* aWakeLockInfo)
709 : {
710 0 : AssertMainThread();
711 0 : PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
712 0 : }
713 :
714 : void
715 0 : NotifyWakeLockChange(const WakeLockInformation& aInfo)
716 : {
717 0 : AssertMainThread();
718 0 : WakeLockObservers().BroadcastInformation(aInfo);
719 0 : }
720 :
721 : void
722 1 : RegisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
723 : {
724 1 : AssertMainThread();
725 1 : ScreenConfigurationObservers().AddObserver(aObserver);
726 1 : }
727 :
728 : void
729 0 : UnregisterScreenConfigurationObserver(ScreenConfigurationObserver* aObserver)
730 : {
731 0 : AssertMainThread();
732 0 : ScreenConfigurationObservers().RemoveObserver(aObserver);
733 0 : }
734 :
735 : void
736 34 : GetCurrentScreenConfiguration(ScreenConfiguration* aScreenConfiguration)
737 : {
738 34 : AssertMainThread();
739 34 : *aScreenConfiguration = ScreenConfigurationObservers().GetCurrentInformation();
740 34 : }
741 :
742 : void
743 0 : NotifyScreenConfigurationChange(const ScreenConfiguration& aScreenConfiguration)
744 : {
745 0 : ScreenConfigurationObservers().CacheInformation(aScreenConfiguration);
746 0 : ScreenConfigurationObservers().BroadcastCachedInformation();
747 0 : }
748 :
749 : bool
750 0 : LockScreenOrientation(const dom::ScreenOrientationInternal& aOrientation)
751 : {
752 0 : AssertMainThread();
753 0 : RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), false);
754 : }
755 :
756 : void
757 0 : UnlockScreenOrientation()
758 : {
759 0 : AssertMainThread();
760 0 : PROXY_IF_SANDBOXED(UnlockScreenOrientation());
761 0 : }
762 :
763 : void
764 0 : EnableSwitchNotifications(SwitchDevice aDevice) {
765 0 : AssertMainThread();
766 0 : PROXY_IF_SANDBOXED(EnableSwitchNotifications(aDevice));
767 0 : }
768 :
769 : void
770 0 : DisableSwitchNotifications(SwitchDevice aDevice) {
771 0 : AssertMainThread();
772 0 : PROXY_IF_SANDBOXED(DisableSwitchNotifications(aDevice));
773 0 : }
774 :
775 0 : SwitchState GetCurrentSwitchState(SwitchDevice aDevice)
776 : {
777 0 : AssertMainThread();
778 0 : RETURN_PROXY_IF_SANDBOXED(GetCurrentSwitchState(aDevice), SWITCH_STATE_UNKNOWN);
779 : }
780 :
781 0 : void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState)
782 : {
783 0 : AssertMainThread();
784 0 : PROXY_IF_SANDBOXED(NotifySwitchStateFromInputDevice(aDevice, aState));
785 0 : }
786 :
787 : typedef mozilla::ObserverList<SwitchEvent> SwitchObserverList;
788 :
789 : static SwitchObserverList *sSwitchObserverLists = nullptr;
790 :
791 : static SwitchObserverList&
792 0 : GetSwitchObserverList(SwitchDevice aDevice) {
793 0 : MOZ_ASSERT(0 <= aDevice && aDevice < NUM_SWITCH_DEVICE);
794 0 : if (sSwitchObserverLists == nullptr) {
795 0 : sSwitchObserverLists = new SwitchObserverList[NUM_SWITCH_DEVICE];
796 : }
797 0 : return sSwitchObserverLists[aDevice];
798 : }
799 :
800 : static void
801 0 : ReleaseObserversIfNeeded() {
802 0 : for (int i = 0; i < NUM_SWITCH_DEVICE; i++) {
803 0 : if (sSwitchObserverLists[i].Length() != 0)
804 0 : return;
805 : }
806 :
807 : //The length of every list is 0, no observer in the list.
808 0 : delete [] sSwitchObserverLists;
809 0 : sSwitchObserverLists = nullptr;
810 : }
811 :
812 : void
813 0 : RegisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
814 : {
815 0 : AssertMainThread();
816 0 : SwitchObserverList& observer = GetSwitchObserverList(aDevice);
817 0 : observer.AddObserver(aObserver);
818 0 : if (observer.Length() == 1) {
819 0 : EnableSwitchNotifications(aDevice);
820 : }
821 0 : }
822 :
823 : void
824 0 : UnregisterSwitchObserver(SwitchDevice aDevice, SwitchObserver *aObserver)
825 : {
826 0 : AssertMainThread();
827 :
828 0 : if (!sSwitchObserverLists) {
829 0 : return;
830 : }
831 :
832 0 : SwitchObserverList& observer = GetSwitchObserverList(aDevice);
833 0 : if (!observer.RemoveObserver(aObserver) || observer.Length() > 0) {
834 0 : return;
835 : }
836 :
837 0 : DisableSwitchNotifications(aDevice);
838 0 : ReleaseObserversIfNeeded();
839 : }
840 :
841 : void
842 0 : NotifySwitchChange(const SwitchEvent& aEvent)
843 : {
844 : // When callback this notification, main thread may call unregister function
845 : // first. We should check if this pointer is valid.
846 0 : if (!sSwitchObserverLists)
847 0 : return;
848 :
849 0 : SwitchObserverList& observer = GetSwitchObserverList(aEvent.device());
850 0 : observer.Broadcast(aEvent);
851 : }
852 :
853 : bool
854 0 : SetProcessPrioritySupported()
855 : {
856 0 : RETURN_PROXY_IF_SANDBOXED(SetProcessPrioritySupported(), false);
857 : }
858 :
859 : void
860 0 : SetProcessPriority(int aPid, ProcessPriority aPriority)
861 : {
862 : // n.b. The sandboxed implementation crashes; SetProcessPriority works only
863 : // from the main process.
864 0 : PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
865 0 : }
866 :
867 : void
868 1 : SetCurrentThreadPriority(hal::ThreadPriority aThreadPriority)
869 : {
870 1 : PROXY_IF_SANDBOXED(SetCurrentThreadPriority(aThreadPriority));
871 1 : }
872 :
873 : void
874 0 : SetThreadPriority(PlatformThreadId aThreadId,
875 : hal::ThreadPriority aThreadPriority)
876 : {
877 0 : PROXY_IF_SANDBOXED(SetThreadPriority(aThreadId, aThreadPriority));
878 0 : }
879 :
880 : // From HalTypes.h.
881 : const char*
882 0 : ProcessPriorityToString(ProcessPriority aPriority)
883 : {
884 0 : switch (aPriority) {
885 : case PROCESS_PRIORITY_MASTER:
886 0 : return "MASTER";
887 : case PROCESS_PRIORITY_PREALLOC:
888 0 : return "PREALLOC";
889 : case PROCESS_PRIORITY_FOREGROUND_HIGH:
890 0 : return "FOREGROUND_HIGH";
891 : case PROCESS_PRIORITY_FOREGROUND:
892 0 : return "FOREGROUND";
893 : case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
894 0 : return "FOREGROUND_KEYBOARD";
895 : case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
896 0 : return "BACKGROUND_PERCEIVABLE";
897 : case PROCESS_PRIORITY_BACKGROUND:
898 0 : return "BACKGROUND";
899 : case PROCESS_PRIORITY_UNKNOWN:
900 0 : return "UNKNOWN";
901 : default:
902 0 : MOZ_ASSERT(false);
903 : return "???";
904 : }
905 : }
906 :
907 : const char *
908 0 : ThreadPriorityToString(ThreadPriority aPriority)
909 : {
910 0 : switch (aPriority) {
911 : case THREAD_PRIORITY_COMPOSITOR:
912 0 : return "COMPOSITOR";
913 : default:
914 0 : MOZ_ASSERT(false);
915 : return "???";
916 : }
917 : }
918 :
919 0 : void FactoryReset(mozilla::dom::FactoryResetReason& aReason)
920 : {
921 0 : AssertMainThread();
922 0 : PROXY_IF_SANDBOXED(FactoryReset(aReason));
923 0 : }
924 :
925 : void
926 0 : StartDiskSpaceWatcher()
927 : {
928 0 : AssertMainProcess();
929 0 : AssertMainThread();
930 0 : PROXY_IF_SANDBOXED(StartDiskSpaceWatcher());
931 0 : }
932 :
933 : void
934 0 : StopDiskSpaceWatcher()
935 : {
936 0 : AssertMainProcess();
937 0 : AssertMainThread();
938 0 : PROXY_IF_SANDBOXED(StopDiskSpaceWatcher());
939 0 : }
940 :
941 : uint32_t
942 0 : GetTotalSystemMemory()
943 : {
944 0 : return hal_impl::GetTotalSystemMemory();
945 : }
946 :
947 0 : bool IsHeadphoneEventFromInputDev()
948 : {
949 0 : AssertMainThread();
950 0 : RETURN_PROXY_IF_SANDBOXED(IsHeadphoneEventFromInputDev(), false);
951 : }
952 :
953 0 : nsresult StartSystemService(const char* aSvcName, const char* aArgs)
954 : {
955 0 : AssertMainThread();
956 0 : RETURN_PROXY_IF_SANDBOXED(StartSystemService(aSvcName, aArgs), NS_ERROR_FAILURE);
957 : }
958 :
959 0 : void StopSystemService(const char* aSvcName)
960 : {
961 0 : AssertMainThread();
962 0 : PROXY_IF_SANDBOXED(StopSystemService(aSvcName));
963 0 : }
964 :
965 0 : bool SystemServiceIsRunning(const char* aSvcName)
966 : {
967 0 : AssertMainThread();
968 0 : RETURN_PROXY_IF_SANDBOXED(SystemServiceIsRunning(aSvcName), false);
969 : }
970 :
971 : } // namespace hal
972 9 : } // namespace mozilla
|