2011-10-05 22:15:45 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2011-09-30 07:00:48 +00:00
|
|
|
/* vim: set sw=2 ts=8 et ft=cpp : */
|
2012-02-10 10:04:44 +00:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
2012-02-02 06:09:00 +00:00
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
2012-02-10 10:04:44 +00:00
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2011-10-05 22:15:45 +00:00
|
|
|
|
|
|
|
#include "Hal.h"
|
2016-02-15 06:33:00 +00:00
|
|
|
|
2011-12-17 21:04:51 +00:00
|
|
|
#include "HalImpl.h"
|
2014-09-24 13:23:18 +00:00
|
|
|
#include "HalLog.h"
|
2011-12-17 21:04:51 +00:00
|
|
|
#include "HalSandbox.h"
|
2018-08-31 20:29:30 +00:00
|
|
|
#include "HalWakeLockInternal.h"
|
2019-01-02 13:05:23 +00:00
|
|
|
#include "mozilla/dom/Document.h"
|
2011-10-05 22:15:45 +00:00
|
|
|
#include "nsThreadUtils.h"
|
|
|
|
#include "nsXULAppAPI.h"
|
2013-05-17 20:17:53 +00:00
|
|
|
#include "nsPIDOMWindow.h"
|
2016-02-15 06:33:00 +00:00
|
|
|
#include "nsJSUtils.h"
|
|
|
|
#include "mozilla/ClearOnShutdown.h"
|
|
|
|
#include "mozilla/Observer.h"
|
2012-11-17 15:05:18 +00:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2016-02-15 06:33:00 +00:00
|
|
|
#include "WindowIdentifier.h"
|
2011-09-30 07:00:48 +00:00
|
|
|
|
2012-08-05 05:09:39 +00:00
|
|
|
#ifdef XP_WIN
|
|
|
|
# include <process.h>
|
|
|
|
# define getpid _getpid
|
|
|
|
#endif
|
|
|
|
|
2011-09-30 07:00:48 +00:00
|
|
|
using namespace mozilla::services;
|
2013-02-14 20:41:30 +00:00
|
|
|
using namespace mozilla::dom;
|
2011-10-05 22:15:45 +00:00
|
|
|
|
|
|
|
#define PROXY_IF_SANDBOXED(_call) \
|
|
|
|
do { \
|
|
|
|
if (InSandbox()) { \
|
2013-02-12 04:09:25 +00:00
|
|
|
if (!hal_sandbox::HalChildDestroyed()) { \
|
2012-10-07 01:53:22 +00:00
|
|
|
hal_sandbox::_call; \
|
|
|
|
} \
|
2011-10-05 22:15:45 +00:00
|
|
|
} else { \
|
|
|
|
hal_impl::_call; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2012-10-07 01:53:22 +00:00
|
|
|
#define RETURN_PROXY_IF_SANDBOXED(_call, defValue) \
|
2011-12-04 17:07:00 +00:00
|
|
|
do { \
|
|
|
|
if (InSandbox()) { \
|
2013-02-12 04:09:25 +00:00
|
|
|
if (hal_sandbox::HalChildDestroyed()) { \
|
2012-10-07 01:53:22 +00:00
|
|
|
return defValue; \
|
|
|
|
} \
|
2011-12-04 17:07:00 +00:00
|
|
|
return hal_sandbox::_call; \
|
|
|
|
} else { \
|
|
|
|
return hal_impl::_call; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2020-01-18 13:48:34 +00:00
|
|
|
namespace mozilla::hal {
|
2011-10-05 22:15:45 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
static bool sInitialized = false;
|
|
|
|
|
2016-01-28 18:35:00 +00:00
|
|
|
mozilla::LogModule* GetHalLog() {
|
|
|
|
static mozilla::LazyLogModule sHalLog("hal");
|
2012-10-29 23:32:10 +00:00
|
|
|
return sHalLog;
|
|
|
|
}
|
2011-09-30 07:00:48 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2011-10-05 22:15:45 +00:00
|
|
|
void AssertMainThread() { MOZ_ASSERT(NS_IsMainThread()); }
|
|
|
|
|
|
|
|
bool InSandbox() { return GeckoProcessType_Content == XRE_GetProcessType(); }
|
|
|
|
|
2016-01-30 17:05:36 +00:00
|
|
|
bool WindowIsActive(nsPIDOMWindowInner* aWindow) {
|
2019-01-02 13:05:23 +00:00
|
|
|
dom::Document* document = aWindow->GetDoc();
|
2013-05-05 07:03:15 +00:00
|
|
|
NS_ENSURE_TRUE(document, false);
|
|
|
|
return !document->Hidden();
|
2011-09-30 07:00:48 +00:00
|
|
|
}
|
|
|
|
|
2012-07-26 19:33:45 +00:00
|
|
|
StaticAutoPtr<WindowIdentifier::IDArrayType> gLastIDToVibrate;
|
2011-09-30 07:00:48 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
static void RecordLastIDToVibrate(const WindowIdentifier& aId) {
|
|
|
|
if (!InSandbox()) {
|
2020-05-05 10:14:24 +00:00
|
|
|
*gLastIDToVibrate = aId.AsArray().Clone();
|
2018-08-31 20:29:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool MayCancelVibration(const WindowIdentifier& aId) {
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
return InSandbox() || (*gLastIDToVibrate == aId.AsArray());
|
2011-09-30 07:00:48 +00:00
|
|
|
}
|
|
|
|
|
2015-07-13 15:25:42 +00:00
|
|
|
} // namespace
|
2011-09-30 07:00:48 +00:00
|
|
|
|
2016-01-30 17:05:36 +00:00
|
|
|
void Vibrate(const nsTArray<uint32_t>& pattern, nsPIDOMWindowInner* window) {
|
2011-12-17 21:04:26 +00:00
|
|
|
Vibrate(pattern, WindowIdentifier(window));
|
2011-09-30 07:00:48 +00:00
|
|
|
}
|
|
|
|
|
2020-05-05 10:14:24 +00:00
|
|
|
void Vibrate(const nsTArray<uint32_t>& pattern, WindowIdentifier&& id) {
|
2011-10-05 22:15:45 +00:00
|
|
|
AssertMainThread();
|
2011-09-30 07:00:48 +00:00
|
|
|
|
|
|
|
// 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())) {
|
2014-09-24 13:23:18 +00:00
|
|
|
HAL_LOG("Vibrate: Window is inactive, dropping vibrate.");
|
2011-09-30 07:00:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
RecordLastIDToVibrate(id);
|
2012-11-08 19:35:03 +00:00
|
|
|
|
2016-01-04 15:08:21 +00:00
|
|
|
// Don't forward our ID if we are not in the sandbox, because hal_impl
|
2012-11-08 19:35:03 +00:00
|
|
|
// 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.
|
2020-05-05 10:14:24 +00:00
|
|
|
PROXY_IF_SANDBOXED(
|
|
|
|
Vibrate(pattern, InSandbox() ? std::move(id) : WindowIdentifier()));
|
2011-10-05 22:15:45 +00:00
|
|
|
}
|
|
|
|
|
2016-01-30 17:05:36 +00:00
|
|
|
void CancelVibrate(nsPIDOMWindowInner* window) {
|
2011-12-17 21:04:26 +00:00
|
|
|
CancelVibrate(WindowIdentifier(window));
|
|
|
|
}
|
|
|
|
|
2020-05-05 10:14:24 +00:00
|
|
|
void CancelVibrate(WindowIdentifier&& id) {
|
2011-09-30 07:00:48 +00:00
|
|
|
AssertMainThread();
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
if (MayCancelVibration(id)) {
|
2016-01-04 15:08:21 +00:00
|
|
|
// Don't forward our ID if we are not in the sandbox, because hal_impl
|
2012-11-08 19:35:03 +00:00
|
|
|
// 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.
|
2020-05-05 10:14:24 +00:00
|
|
|
PROXY_IF_SANDBOXED(
|
|
|
|
CancelVibrate(InSandbox() ? std::move(id) : WindowIdentifier()));
|
2011-09-30 07:00:48 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-04 17:07:00 +00:00
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
template <class InfoType>
|
|
|
|
class ObserversManager {
|
2011-11-02 15:14:01 +00:00
|
|
|
public:
|
2011-12-17 21:51:44 +00:00
|
|
|
void AddObserver(Observer<InfoType>* aObserver) {
|
2018-08-31 20:29:30 +00:00
|
|
|
mObservers.AddObserver(aObserver);
|
2018-07-02 10:14:18 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
if (mObservers.Length() == 1) {
|
2011-12-17 21:51:44 +00:00
|
|
|
EnableNotifications();
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
void RemoveObserver(Observer<InfoType>* aObserver) {
|
2018-08-31 20:29:30 +00:00
|
|
|
bool removed = mObservers.RemoveObserver(aObserver);
|
2012-09-06 21:58:36 +00:00
|
|
|
if (!removed) {
|
2012-03-14 18:18:26 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-11-02 15:14:01 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
if (mObservers.Length() == 0) {
|
2011-12-17 21:51:44 +00:00
|
|
|
DisableNotifications();
|
2012-03-07 11:03:25 +00:00
|
|
|
OnNotificationsDisabled();
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-07 11:03:25 +00:00
|
|
|
void BroadcastInformation(const InfoType& aInfo) {
|
2018-08-31 20:29:30 +00:00
|
|
|
mObservers.Broadcast(aInfo);
|
2012-03-07 11:03:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2018-08-31 20:29:30 +00:00
|
|
|
~ObserversManager() { MOZ_ASSERT(mObservers.Length() == 0); }
|
|
|
|
|
2012-03-07 11:03:25 +00:00
|
|
|
virtual void EnableNotifications() = 0;
|
|
|
|
virtual void DisableNotifications() = 0;
|
|
|
|
virtual void OnNotificationsDisabled() {}
|
|
|
|
|
|
|
|
private:
|
2018-08-31 20:29:30 +00:00
|
|
|
mozilla::ObserverList<InfoType> mObservers;
|
2012-03-07 11:03:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class InfoType>
|
|
|
|
class CachingObserversManager : public ObserversManager<InfoType> {
|
|
|
|
public:
|
2011-12-17 21:51:44 +00:00
|
|
|
InfoType GetCurrentInformation() {
|
|
|
|
if (mHasValidCache) {
|
|
|
|
return mInfo;
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
GetCurrentInformationInternal(&mInfo);
|
2012-07-27 18:39:44 +00:00
|
|
|
mHasValidCache = true;
|
2011-12-17 21:51:44 +00:00
|
|
|
return mInfo;
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
void CacheInformation(const InfoType& aInfo) {
|
|
|
|
mHasValidCache = true;
|
|
|
|
mInfo = aInfo;
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
void BroadcastCachedInformation() { this->BroadcastInformation(mInfo); }
|
2011-11-02 15:14:01 +00:00
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
protected:
|
|
|
|
virtual void GetCurrentInformationInternal(InfoType*) = 0;
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void OnNotificationsDisabled() override { mHasValidCache = false; }
|
2012-03-07 11:03:25 +00:00
|
|
|
|
2011-11-02 15:14:01 +00:00
|
|
|
private:
|
2011-12-17 21:51:44 +00:00
|
|
|
InfoType mInfo;
|
|
|
|
bool mHasValidCache;
|
|
|
|
};
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
class BatteryObserversManager final
|
|
|
|
: public CachingObserversManager<BatteryInformation> {
|
2011-12-17 21:51:44 +00:00
|
|
|
protected:
|
2016-11-23 11:21:06 +00:00
|
|
|
void EnableNotifications() override {
|
2011-12-17 21:51:44 +00:00
|
|
|
PROXY_IF_SANDBOXED(EnableBatteryNotifications());
|
|
|
|
}
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void DisableNotifications() override {
|
2011-12-17 21:51:44 +00:00
|
|
|
PROXY_IF_SANDBOXED(DisableBatteryNotifications());
|
|
|
|
}
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void GetCurrentInformationInternal(BatteryInformation* aInfo) override {
|
2011-12-17 21:51:44 +00:00
|
|
|
PROXY_IF_SANDBOXED(GetCurrentBatteryInformation(aInfo));
|
|
|
|
}
|
2011-11-02 15:14:01 +00:00
|
|
|
};
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
class NetworkObserversManager final
|
|
|
|
: public CachingObserversManager<NetworkInformation> {
|
2012-01-16 13:39:57 +00:00
|
|
|
protected:
|
2016-11-23 11:21:06 +00:00
|
|
|
void EnableNotifications() override {
|
2012-01-16 13:39:57 +00:00
|
|
|
PROXY_IF_SANDBOXED(EnableNetworkNotifications());
|
|
|
|
}
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void DisableNotifications() override {
|
2012-01-16 13:39:57 +00:00
|
|
|
PROXY_IF_SANDBOXED(DisableNetworkNotifications());
|
|
|
|
}
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void GetCurrentInformationInternal(NetworkInformation* aInfo) override {
|
2012-01-16 13:39:57 +00:00
|
|
|
PROXY_IF_SANDBOXED(GetCurrentNetworkInformation(aInfo));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
class WakeLockObserversManager final
|
|
|
|
: public ObserversManager<WakeLockInformation> {
|
2012-03-07 11:03:25 +00:00
|
|
|
protected:
|
2016-11-23 11:21:06 +00:00
|
|
|
void EnableNotifications() override {
|
2012-03-07 11:03:25 +00:00
|
|
|
PROXY_IF_SANDBOXED(EnableWakeLockNotifications());
|
|
|
|
}
|
|
|
|
|
2016-11-23 11:21:06 +00:00
|
|
|
void DisableNotifications() override {
|
2012-03-07 11:03:25 +00:00
|
|
|
PROXY_IF_SANDBOXED(DisableWakeLockNotifications());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
typedef mozilla::ObserverList<SensorData> SensorObserverList;
|
|
|
|
StaticAutoPtr<SensorObserverList> sSensorObservers[NUM_SENSOR_TYPE];
|
|
|
|
|
|
|
|
static SensorObserverList* GetSensorObservers(SensorType sensor_type) {
|
2016-02-19 16:31:43 +00:00
|
|
|
AssertMainThread();
|
2018-08-31 20:29:30 +00:00
|
|
|
MOZ_ASSERT(sensor_type < NUM_SENSOR_TYPE);
|
2012-03-13 16:42:46 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
if (!sSensorObservers[sensor_type]) {
|
|
|
|
sSensorObservers[sensor_type] = new SensorObserverList();
|
|
|
|
}
|
|
|
|
|
|
|
|
return sSensorObservers[sensor_type];
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MOZ_IMPL_HAL_OBSERVER(name_) \
|
|
|
|
StaticAutoPtr<name_##ObserversManager> s##name_##Observers; \
|
|
|
|
\
|
|
|
|
static name_##ObserversManager* name_##Observers() { \
|
|
|
|
AssertMainThread(); \
|
|
|
|
\
|
|
|
|
if (!s##name_##Observers) { \
|
|
|
|
MOZ_ASSERT(sInitialized); \
|
|
|
|
s##name_##Observers = new name_##ObserversManager(); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
return s##name_##Observers; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void Register##name_##Observer(name_##Observer* aObserver) { \
|
|
|
|
AssertMainThread(); \
|
|
|
|
name_##Observers()->AddObserver(aObserver); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void Unregister##name_##Observer(name_##Observer* aObserver) { \
|
|
|
|
AssertMainThread(); \
|
|
|
|
name_##Observers()->RemoveObserver(aObserver); \
|
2018-08-13 01:57:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_IMPL_HAL_OBSERVER(Battery)
|
2011-11-02 15:14:01 +00:00
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
void GetCurrentBatteryInformation(BatteryInformation* aInfo) {
|
2018-08-31 20:29:30 +00:00
|
|
|
*aInfo = BatteryObservers()->GetCurrentInformation();
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
|
2011-12-17 21:51:44 +00:00
|
|
|
void NotifyBatteryChange(const BatteryInformation& aInfo) {
|
2018-08-31 20:29:30 +00:00
|
|
|
BatteryObservers()->CacheInformation(aInfo);
|
|
|
|
BatteryObservers()->BroadcastCachedInformation();
|
2011-11-02 15:14:01 +00:00
|
|
|
}
|
|
|
|
|
2012-02-05 19:51:06 +00:00
|
|
|
void EnableSensorNotifications(SensorType aSensor) {
|
|
|
|
AssertMainThread();
|
|
|
|
PROXY_IF_SANDBOXED(EnableSensorNotifications(aSensor));
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisableSensorNotifications(SensorType aSensor) {
|
|
|
|
AssertMainThread();
|
|
|
|
PROXY_IF_SANDBOXED(DisableSensorNotifications(aSensor));
|
|
|
|
}
|
|
|
|
|
|
|
|
void RegisterSensorObserver(SensorType aSensor, ISensorObserver* aObserver) {
|
2018-08-31 20:29:30 +00:00
|
|
|
SensorObserverList* observers = GetSensorObservers(aSensor);
|
2016-01-04 15:08:21 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
observers->AddObserver(aObserver);
|
|
|
|
if (observers->Length() == 1) {
|
2012-02-05 19:51:06 +00:00
|
|
|
EnableSensorNotifications(aSensor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UnregisterSensorObserver(SensorType aSensor, ISensorObserver* aObserver) {
|
2018-08-31 20:29:30 +00:00
|
|
|
SensorObserverList* observers = GetSensorObservers(aSensor);
|
|
|
|
if (!observers->RemoveObserver(aObserver) || observers->Length() > 0) {
|
2012-05-21 10:12:03 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
DisableSensorNotifications(aSensor);
|
2012-02-05 19:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void NotifySensorChange(const SensorData& aSensorData) {
|
2018-08-31 20:29:30 +00:00
|
|
|
SensorObserverList* observers = GetSensorObservers(aSensorData.sensor());
|
2012-02-05 19:51:06 +00:00
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
observers->Broadcast(aSensorData);
|
2012-02-05 19:51:06 +00:00
|
|
|
}
|
|
|
|
|
2018-08-13 01:57:50 +00:00
|
|
|
MOZ_IMPL_HAL_OBSERVER(Network)
|
2012-01-16 13:39:57 +00:00
|
|
|
|
|
|
|
void GetCurrentNetworkInformation(NetworkInformation* aInfo) {
|
2018-08-31 20:29:30 +00:00
|
|
|
*aInfo = NetworkObservers()->GetCurrentInformation();
|
2012-01-16 13:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void NotifyNetworkChange(const NetworkInformation& aInfo) {
|
2018-08-31 20:29:30 +00:00
|
|
|
NetworkObservers()->CacheInformation(aInfo);
|
|
|
|
NetworkObservers()->BroadcastCachedInformation();
|
2012-01-16 13:39:57 +00:00
|
|
|
}
|
|
|
|
|
2018-08-13 01:57:50 +00:00
|
|
|
MOZ_IMPL_HAL_OBSERVER(WakeLock)
|
2012-03-07 11:03:25 +00:00
|
|
|
|
2012-11-17 15:05:18 +00:00
|
|
|
void ModifyWakeLock(const nsAString& aTopic, WakeLockControl aLockAdjust,
|
2013-02-14 20:41:30 +00:00
|
|
|
WakeLockControl aHiddenAdjust,
|
|
|
|
uint64_t aProcessID /* = CONTENT_PROCESS_ID_UNKNOWN */) {
|
2012-03-07 11:03:25 +00:00
|
|
|
AssertMainThread();
|
|
|
|
|
2013-02-14 20:41:30 +00:00
|
|
|
if (aProcessID == CONTENT_PROCESS_ID_UNKNOWN) {
|
|
|
|
aProcessID = InSandbox() ? ContentChild::GetSingleton()->GetID()
|
|
|
|
: CONTENT_PROCESS_ID_MAIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
PROXY_IF_SANDBOXED(
|
|
|
|
ModifyWakeLock(aTopic, aLockAdjust, aHiddenAdjust, aProcessID));
|
2012-11-17 15:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GetWakeLockInfo(const nsAString& aTopic,
|
|
|
|
WakeLockInformation* aWakeLockInfo) {
|
2012-03-07 11:03:25 +00:00
|
|
|
AssertMainThread();
|
|
|
|
PROXY_IF_SANDBOXED(GetWakeLockInfo(aTopic, aWakeLockInfo));
|
|
|
|
}
|
|
|
|
|
|
|
|
void NotifyWakeLockChange(const WakeLockInformation& aInfo) {
|
|
|
|
AssertMainThread();
|
2018-08-31 20:29:30 +00:00
|
|
|
WakeLockObservers()->BroadcastInformation(aInfo);
|
2012-03-07 11:03:25 +00:00
|
|
|
}
|
|
|
|
|
2022-03-02 03:48:14 +00:00
|
|
|
RefPtr<GenericNonExclusivePromise> LockScreenOrientation(
|
Bug 1697647 - Add screen orientation lock api r=ipc-reviewers,mccr8,agi,smaug,jonalmeida
Previously, the screenOrientation.lock API was for Fennec and not supported for Fenix and multi-process use. The overall idea is to now allow apps to use the API through a delegate and make asynchronous calls to LockDeviceOrientation. This required replacing the existing code that returned a default false bool to calls that perform the requested orientation change and instead return a promise that contained either an allow or deny value.
Returning a promise instead of a bool involved changing the API calls from the C++ side to Java. The new general control flow of screenOrientation lock follows: an app calls C++ ScreenOrientation.lock() which eventually dispatches LockOrientationTask to resolve the pending orientation promise. Hal.cpp sends an IPC call to the content process and RecvLockScreenOrientation retrieves the current instance of geckoRuntime and calls the java side LockScreenOrientation. Apps must create a delegate and override onOrientationLock to set the requested orientation. In geckoview's testing, this is done with the android API setRequestedOrientation. Once a device orientation change has been triggered, native OnOrientationChange calls to NotifyScreenConfigurationChange, which notifies all observers and dispatches a change event to resolve the pending orientation promise.
Testing:
I used a demo on the GeckoView Example (https://usefulangle.com/demos/105/screen.html) to test locking to landscape orientation. This required a change to the GVE to show the app from recreating the whole thing on orientation change. In the example AndroidManifest xml file, `orientation` prevents restart when orientation changes.
The Junit/Kotlin tests were to verify that the expected orientation delegate was called with the expected new orientation value, in an orientation change, if the new orientation was the same as the current, and if the pre-lock conditions such as being fullscreen were not met.
A static preference `dom.screenorientation.allow-lock` was added to the dom group, since it affects the ui dom) and is currently turned off. C++ can access it through its mirrored variable dom_screenorientation_allow_lock (same name but with underscores). The junit tests turn the preference on and test the lock feature.
Reference:
Orientation constant values:
C++
1 ScreenOrientation_PortraitPrimary); - vertical with button at bottom
2 ScreenOrientation_PortraitSecondary); - vertical with button at top
4 ScreenOrientation_LandscapePrimary); - horizational w button right
8 ScreenOrientation_LandscapeSecondary); - horization button left
16 ScreenOrientation_Default);
Java
1 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_PRIMARY.value
2 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_SECONDARY.value
4 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_PRIMARY.value
8 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_SECONDARY.value
Java public API
0 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
1 Activitynfo.SCREEN_ORIENTATION_PORTRAIT
Android
1 ORIENTATION_PORTRAIT
2 ORIENTATION_LANDSCAPE
Differential Revision: https://phabricator.services.mozilla.com/D129427
2021-12-06 13:58:37 +00:00
|
|
|
const ScreenOrientation& aOrientation) {
|
2012-03-29 19:43:16 +00:00
|
|
|
AssertMainThread();
|
Bug 1697647 - Add screen orientation lock api r=ipc-reviewers,mccr8,agi,smaug,jonalmeida
Previously, the screenOrientation.lock API was for Fennec and not supported for Fenix and multi-process use. The overall idea is to now allow apps to use the API through a delegate and make asynchronous calls to LockDeviceOrientation. This required replacing the existing code that returned a default false bool to calls that perform the requested orientation change and instead return a promise that contained either an allow or deny value.
Returning a promise instead of a bool involved changing the API calls from the C++ side to Java. The new general control flow of screenOrientation lock follows: an app calls C++ ScreenOrientation.lock() which eventually dispatches LockOrientationTask to resolve the pending orientation promise. Hal.cpp sends an IPC call to the content process and RecvLockScreenOrientation retrieves the current instance of geckoRuntime and calls the java side LockScreenOrientation. Apps must create a delegate and override onOrientationLock to set the requested orientation. In geckoview's testing, this is done with the android API setRequestedOrientation. Once a device orientation change has been triggered, native OnOrientationChange calls to NotifyScreenConfigurationChange, which notifies all observers and dispatches a change event to resolve the pending orientation promise.
Testing:
I used a demo on the GeckoView Example (https://usefulangle.com/demos/105/screen.html) to test locking to landscape orientation. This required a change to the GVE to show the app from recreating the whole thing on orientation change. In the example AndroidManifest xml file, `orientation` prevents restart when orientation changes.
The Junit/Kotlin tests were to verify that the expected orientation delegate was called with the expected new orientation value, in an orientation change, if the new orientation was the same as the current, and if the pre-lock conditions such as being fullscreen were not met.
A static preference `dom.screenorientation.allow-lock` was added to the dom group, since it affects the ui dom) and is currently turned off. C++ can access it through its mirrored variable dom_screenorientation_allow_lock (same name but with underscores). The junit tests turn the preference on and test the lock feature.
Reference:
Orientation constant values:
C++
1 ScreenOrientation_PortraitPrimary); - vertical with button at bottom
2 ScreenOrientation_PortraitSecondary); - vertical with button at top
4 ScreenOrientation_LandscapePrimary); - horizational w button right
8 ScreenOrientation_LandscapeSecondary); - horization button left
16 ScreenOrientation_Default);
Java
1 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_PRIMARY.value
2 GeckoScreenOrientation.ScreenOrientation.PORTRAIT_SECONDARY.value
4 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_PRIMARY.value
8 GeckoScreenOrientation.ScreenOrientation.LANDSCAPE_SECONDARY.value
Java public API
0 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
1 Activitynfo.SCREEN_ORIENTATION_PORTRAIT
Android
1 ORIENTATION_PORTRAIT
2 ORIENTATION_LANDSCAPE
Differential Revision: https://phabricator.services.mozilla.com/D129427
2021-12-06 13:58:37 +00:00
|
|
|
RETURN_PROXY_IF_SANDBOXED(LockScreenOrientation(aOrientation), nullptr);
|
2012-03-29 19:43:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void UnlockScreenOrientation() {
|
|
|
|
AssertMainThread();
|
|
|
|
PROXY_IF_SANDBOXED(UnlockScreenOrientation());
|
|
|
|
}
|
|
|
|
|
2017-05-26 15:50:17 +00:00
|
|
|
void SetProcessPriority(int aPid, ProcessPriority aPriority) {
|
2013-05-09 20:27:06 +00:00
|
|
|
// n.b. The sandboxed implementation crashes; SetProcessPriority works only
|
|
|
|
// from the main process.
|
2017-05-26 15:50:17 +00:00
|
|
|
PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
|
2012-08-05 05:09:39 +00:00
|
|
|
}
|
|
|
|
|
2013-02-08 14:32:23 +00:00
|
|
|
// From HalTypes.h.
|
|
|
|
const char* ProcessPriorityToString(ProcessPriority aPriority) {
|
|
|
|
switch (aPriority) {
|
2020-06-23 17:34:51 +00:00
|
|
|
case PROCESS_PRIORITY_PARENT_PROCESS:
|
|
|
|
return "PARENT_PROCESS";
|
2017-02-01 12:34:24 +00:00
|
|
|
case PROCESS_PRIORITY_PREALLOC:
|
|
|
|
return "PREALLOC";
|
2013-02-14 20:41:30 +00:00
|
|
|
case PROCESS_PRIORITY_FOREGROUND_HIGH:
|
|
|
|
return "FOREGROUND_HIGH";
|
2013-02-08 14:32:23 +00:00
|
|
|
case PROCESS_PRIORITY_FOREGROUND:
|
|
|
|
return "FOREGROUND";
|
2013-09-24 08:10:20 +00:00
|
|
|
case PROCESS_PRIORITY_FOREGROUND_KEYBOARD:
|
|
|
|
return "FOREGROUND_KEYBOARD";
|
2013-02-08 14:32:23 +00:00
|
|
|
case PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE:
|
|
|
|
return "BACKGROUND_PERCEIVABLE";
|
|
|
|
case PROCESS_PRIORITY_BACKGROUND:
|
|
|
|
return "BACKGROUND";
|
2013-02-23 04:24:28 +00:00
|
|
|
case PROCESS_PRIORITY_UNKNOWN:
|
|
|
|
return "UNKNOWN";
|
2013-02-08 14:32:23 +00:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT(false);
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-31 20:29:30 +00:00
|
|
|
void Init() {
|
|
|
|
MOZ_ASSERT(!sInitialized);
|
|
|
|
|
|
|
|
if (!InSandbox()) {
|
|
|
|
gLastIDToVibrate = new WindowIdentifier::IDArrayType();
|
|
|
|
}
|
|
|
|
|
|
|
|
WakeLockInit();
|
|
|
|
|
|
|
|
sInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shutdown() {
|
|
|
|
MOZ_ASSERT(sInitialized);
|
|
|
|
|
|
|
|
gLastIDToVibrate = nullptr;
|
|
|
|
|
|
|
|
sBatteryObservers = nullptr;
|
|
|
|
sNetworkObservers = nullptr;
|
|
|
|
sWakeLockObservers = nullptr;
|
|
|
|
|
|
|
|
for (auto& sensorObserver : sSensorObservers) {
|
|
|
|
sensorObserver = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
sInitialized = false;
|
|
|
|
}
|
|
|
|
|
2020-01-18 13:48:34 +00:00
|
|
|
} // namespace mozilla::hal
|