/hal/Hal.cpp
http://github.com/zpao/v8monkey · C++ · 424 lines · 315 code · 77 blank · 32 comment · 28 complexity · b24a3887614dc93743e7a09d56726487 MD5 · raw file
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* vim: set sw=2 ts=8 et ft=cpp : */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "Hal.h"
- #include "HalImpl.h"
- #include "HalSandbox.h"
- #include "mozilla/Util.h"
- #include "nsThreadUtils.h"
- #include "nsXULAppAPI.h"
- #include "mozilla/Observer.h"
- #include "nsIDOMDocument.h"
- #include "nsIDOMWindow.h"
- #include "mozilla/Services.h"
- #include "nsIWebNavigation.h"
- #include "nsITabChild.h"
- #include "nsIDocShell.h"
- #include "mozilla/ClearOnShutdown.h"
- #include "WindowIdentifier.h"
- using namespace mozilla::services;
- #define PROXY_IF_SANDBOXED(_call) \
- do { \
- if (InSandbox()) { \
- hal_sandbox::_call; \
- } else { \
- hal_impl::_call; \
- } \
- } while (0)
- #define RETURN_PROXY_IF_SANDBOXED(_call) \
- do { \
- if (InSandbox()) { \
- return hal_sandbox::_call; \
- } else { \
- return hal_impl::_call; \
- } \
- } while (0)
- namespace mozilla {
- namespace hal {
- PRLogModuleInfo *sHalLog = PR_LOG_DEFINE("hal");
- namespace {
- void
- AssertMainThread()
- {
- MOZ_ASSERT(NS_IsMainThread());
- }
- bool
- InSandbox()
- {
- return GeckoProcessType_Content == XRE_GetProcessType();
- }
- bool
- WindowIsActive(nsIDOMWindow *window)
- {
- NS_ENSURE_TRUE(window, false);
- nsCOMPtr<nsIDOMDocument> doc;
- window->GetDocument(getter_AddRefs(doc));
- NS_ENSURE_TRUE(doc, false);
- bool hidden = true;
- doc->GetMozHidden(&hidden);
- return !hidden;
- }
- nsAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
- void InitLastIDToVibrate()
- {
- gLastIDToVibrate = new WindowIdentifier::IDArrayType();
- ClearOnShutdown(&gLastIDToVibrate);
- }
- } // anonymous namespace
- void
- Vibrate(const nsTArray<uint32>& pattern, nsIDOMWindow* window)
- {
- Vibrate(pattern, WindowIdentifier(window));
- }
- void
- Vibrate(const nsTArray<uint32>& pattern, const WindowIdentifier &id)
- {
- AssertMainThread();
- // Only active windows may start vibrations. If |id| hasn't gone
- // through the IPC layer -- that is, if our caller is the outside
- // world, not hal_proxy -- check whether the window is active. If
- // |id| has gone through IPC, don't check the window's visibility;
- // only the window corresponding to the bottommost process has its
- // visibility state set correctly.
- if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) {
- HAL_LOG(("Vibrate: Window is inactive, dropping vibrate."));
- return;
- }
- if (InSandbox()) {
- hal_sandbox::Vibrate(pattern, id);
- }
- else {
- if (!gLastIDToVibrate)
- InitLastIDToVibrate();
- *gLastIDToVibrate = id.AsArray();
- HAL_LOG(("Vibrate: Forwarding to hal_impl."));
- // hal_impl doesn't need |id|. Send it an empty id, which will
- // assert if it's used.
- hal_impl::Vibrate(pattern, WindowIdentifier());
- }
- }
- void
- CancelVibrate(nsIDOMWindow* window)
- {
- CancelVibrate(WindowIdentifier(window));
- }
- void
- CancelVibrate(const WindowIdentifier &id)
- {
- AssertMainThread();
- // Although only active windows may start vibrations, a window may
- // cancel its own vibration even if it's no longer active.
- //
- // After a window is marked as inactive, it sends a CancelVibrate
- // request. We want this request to cancel a playing vibration
- // started by that window, so we certainly don't want to reject the
- // cancellation request because the window is now inactive.
- //
- // But it could be the case that, after this window became inactive,
- // some other window came along and started a vibration. We don't
- // want this window's cancellation request to cancel that window's
- // actively-playing vibration!
- //
- // To solve this problem, we keep track of the id of the last window
- // to start a vibration, and only accepts cancellation requests from
- // the same window. All other cancellation requests are ignored.
- if (InSandbox()) {
- hal_sandbox::CancelVibrate(id);
- }
- else if (*gLastIDToVibrate == id.AsArray()) {
- // Don't forward our ID to hal_impl. It doesn't need it, and we
- // don't want it to be tempted to read it. The empty identifier
- // will assert if it's used.
- HAL_LOG(("CancelVibrate: Forwarding to hal_impl."));
- hal_impl::CancelVibrate(WindowIdentifier());
- }
- }
- template <class InfoType>
- class ObserversManager
- {
- public:
- void AddObserver(Observer<InfoType>* aObserver) {
- if (!mObservers) {
- mObservers = new mozilla::ObserverList<InfoType>();
- }
- mObservers->AddObserver(aObserver);
- if (mObservers->Length() == 1) {
- EnableNotifications();
- }
- }
- void RemoveObserver(Observer<InfoType>* aObserver) {
- MOZ_ASSERT(mObservers);
- mObservers->RemoveObserver(aObserver);
- if (mObservers->Length() == 0) {
- DisableNotifications();
- delete mObservers;
- mObservers = 0;
- mHasValidCache = false;
- }
- }
- InfoType GetCurrentInformation() {
- if (mHasValidCache) {
- return mInfo;
- }
- mHasValidCache = true;
- GetCurrentInformationInternal(&mInfo);
- return mInfo;
- }
- void CacheInformation(const InfoType& aInfo) {
- mHasValidCache = true;
- mInfo = aInfo;
- }
- void BroadcastCachedInformation() {
- MOZ_ASSERT(mObservers);
- mObservers->Broadcast(mInfo);
- }
- protected:
- virtual void EnableNotifications() = 0;
- virtual void DisableNotifications() = 0;
- virtual void GetCurrentInformationInternal(InfoType*) = 0;
- private:
- mozilla::ObserverList<InfoType>* mObservers;
- InfoType mInfo;
- bool mHasValidCache;
- };
- class BatteryObserversManager : public ObserversManager<BatteryInformation>
- {
- protected:
- void EnableNotifications() {
- PROXY_IF_SANDBOXED(EnableBatteryNotifications());
- }
- void DisableNotifications() {
- PROXY_IF_SANDBOXED(DisableBatteryNotifications());
- }
- void GetCurrentInformationInternal(BatteryInformation* aInfo) {
- PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
- }
- };
- static BatteryObserversManager sBatteryObservers;
- class NetworkObserversManager : public ObserversManager<NetworkInformation>
- {
- protected:
- void EnableNotifications() {
- PROXY_IF_SANDBOXED(EnableNetworkNotifications());
- }
- void DisableNotifications() {
- PROXY_IF_SANDBOXED(DisableNetworkNotifications());
- }
- void GetCurrentInformationInternal(NetworkInformation* aInfo) {
- PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
- }
- };
- static NetworkObserversManager sNetworkObservers;
- void
- RegisterBatteryObserver(BatteryObserver* aObserver)
- {
- AssertMainThread();
- sBatteryObservers.AddObserver(aObserver);
- }
- void
- UnregisterBatteryObserver(BatteryObserver* aObserver)
- {
- AssertMainThread();
- sBatteryObservers.RemoveObserver(aObserver);
- }
- void
- GetCurrentBatteryInformation(BatteryInformation* aInfo)
- {
- AssertMainThread();
- *aInfo = sBatteryObservers.GetCurrentInformation();
- }
- void
- NotifyBatteryChange(const BatteryInformation& aInfo)
- {
- AssertMainThread();
- sBatteryObservers.CacheInformation(aInfo);
- sBatteryObservers.BroadcastCachedInformation();
- }
- bool GetScreenEnabled()
- {
- AssertMainThread();
- RETURN_PROXY_IF_SANDBOXED(GetScreenEnabled());
- }
- void SetScreenEnabled(bool enabled)
- {
- AssertMainThread();
- PROXY_IF_SANDBOXED(SetScreenEnabled(enabled));
- }
- double GetScreenBrightness()
- {
- AssertMainThread();
- RETURN_PROXY_IF_SANDBOXED(GetScreenBrightness());
- }
- void SetScreenBrightness(double brightness)
- {
- AssertMainThread();
- PROXY_IF_SANDBOXED(SetScreenBrightness(clamped(brightness, 0.0, 1.0)));
- }
- bool SetLight(LightType light, const hal::LightConfiguration& aConfig)
- {
- AssertMainThread();
- RETURN_PROXY_IF_SANDBOXED(SetLight(light, aConfig));
- }
- bool GetLight(LightType light, hal::LightConfiguration* aConfig)
- {
- AssertMainThread();
- RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig));
- }
- void
- EnableSensorNotifications(SensorType aSensor) {
- AssertMainThread();
- PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
- }
- void
- DisableSensorNotifications(SensorType aSensor) {
- AssertMainThread();
- PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
- }
- typedef mozilla::ObserverList<SensorData> SensorObserverList;
- static SensorObserverList *gSensorObservers = NULL;
- static SensorObserverList &
- GetSensorObservers(SensorType sensor_type) {
- MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
-
- if(gSensorObservers == NULL)
- gSensorObservers = new SensorObserverList[NUM_SENSOR_TYPE];
- return gSensorObservers[sensor_type];
- }
- void
- RegisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
- SensorObserverList &observers = GetSensorObservers(aSensor);
- AssertMainThread();
-
- observers.AddObserver(aObserver);
- if(observers.Length() == 1) {
- EnableSensorNotifications(aSensor);
- }
- }
- void
- UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
- SensorObserverList &observers = GetSensorObservers(aSensor);
- AssertMainThread();
-
- observers.RemoveObserver(aObserver);
- if(observers.Length() == 0) {
- DisableSensorNotifications(aSensor);
- }
- }
- void
- NotifySensorChange(const SensorData &aSensorData) {
- SensorObserverList &observers = GetSensorObservers(aSensorData.sensor());
- AssertMainThread();
-
- observers.Broadcast(aSensorData);
- }
- void
- RegisterNetworkObserver(NetworkObserver* aObserver)
- {
- AssertMainThread();
- sNetworkObservers.AddObserver(aObserver);
- }
- void
- UnregisterNetworkObserver(NetworkObserver* aObserver)
- {
- AssertMainThread();
- sNetworkObservers.RemoveObserver(aObserver);
- }
- void
- GetCurrentNetworkInformation(NetworkInformation* aInfo)
- {
- AssertMainThread();
- *aInfo = sNetworkObservers.GetCurrentInformation();
- }
- void
- NotifyNetworkChange(const NetworkInformation& aInfo)
- {
- sNetworkObservers.CacheInformation(aInfo);
- sNetworkObservers.BroadcastCachedInformation();
- }
- void Reboot()
- {
- AssertMainThread();
- PROXY_IF_SANDBOXED(Reboot());
- }
- void PowerOff()
- {
- AssertMainThread();
- PROXY_IF_SANDBOXED(PowerOff());
- }
- } // namespace hal
- } // namespace mozilla