summaryrefslogtreecommitdiffstats
path: root/hal/gonk/GonkSensorsPollInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hal/gonk/GonkSensorsPollInterface.cpp')
-rw-r--r--hal/gonk/GonkSensorsPollInterface.cpp431
1 files changed, 431 insertions, 0 deletions
diff --git a/hal/gonk/GonkSensorsPollInterface.cpp b/hal/gonk/GonkSensorsPollInterface.cpp
new file mode 100644
index 000000000..d4edc2e7a
--- /dev/null
+++ b/hal/gonk/GonkSensorsPollInterface.cpp
@@ -0,0 +1,431 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sts=2 et sw=2 tw=80: */
+/* 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 "GonkSensorsPollInterface.h"
+#include "HalLog.h"
+#include <mozilla/UniquePtr.h>
+
+namespace mozilla {
+namespace hal {
+
+using namespace mozilla::ipc;
+
+//
+// GonkSensorsPollResultHandler
+//
+
+void
+GonkSensorsPollResultHandler::OnError(SensorsError aError)
+{
+ HAL_ERR("Received error code %d", static_cast<int>(aError));
+}
+
+void
+GonkSensorsPollResultHandler::EnableSensor()
+{ }
+
+void
+GonkSensorsPollResultHandler::DisableSensor()
+{ }
+
+void
+GonkSensorsPollResultHandler::SetPeriod()
+{ }
+
+GonkSensorsPollResultHandler::~GonkSensorsPollResultHandler()
+{ }
+
+//
+// GonkSensorsPollNotificationHandler
+//
+
+void
+GonkSensorsPollNotificationHandler::ErrorNotification(SensorsError aError)
+{
+ HAL_ERR("Received error code %d", static_cast<int>(aError));
+}
+
+void
+GonkSensorsPollNotificationHandler::SensorDetectedNotification(
+ int32_t aId,
+ SensorsType aType,
+ float aRange,
+ float aResolution,
+ float aPower,
+ int32_t aMinPeriod,
+ int32_t aMaxPeriod,
+ SensorsTriggerMode aTriggerMode,
+ SensorsDeliveryMode aDeliveryMode)
+{ }
+
+void
+GonkSensorsPollNotificationHandler::SensorLostNotification(int32_t aId)
+{ }
+
+void
+GonkSensorsPollNotificationHandler::EventNotification(int32_t aId,
+ const SensorsEvent& aEvent)
+{ }
+
+GonkSensorsPollNotificationHandler::~GonkSensorsPollNotificationHandler()
+{ }
+
+//
+// GonkSensorsPollModule
+//
+
+GonkSensorsPollModule::GonkSensorsPollModule()
+ : mProtocolVersion(0)
+{ }
+
+GonkSensorsPollModule::~GonkSensorsPollModule()
+{ }
+
+nsresult
+GonkSensorsPollModule::SetProtocolVersion(unsigned long aProtocolVersion)
+{
+ if ((aProtocolVersion < MIN_PROTOCOL_VERSION) ||
+ (aProtocolVersion > MAX_PROTOCOL_VERSION)) {
+ HAL_ERR("Sensors Poll protocol version %lu not supported",
+ aProtocolVersion);
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ mProtocolVersion = aProtocolVersion;
+ return NS_OK;
+}
+
+void
+GonkSensorsPollModule::HandleSvc(const DaemonSocketPDUHeader& aHeader,
+ DaemonSocketPDU& aPDU,
+ DaemonSocketResultHandler* aRes)
+{
+ static void (GonkSensorsPollModule::* const HandleOp[])(
+ const DaemonSocketPDUHeader&, DaemonSocketPDU&,
+ DaemonSocketResultHandler*) = {
+ [0] = &GonkSensorsPollModule::HandleRsp,
+ [1] = &GonkSensorsPollModule::HandleNtf
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
+
+ // Negate twice to map bit to 0/1
+ unsigned long isNtf = !!(aHeader.mOpcode & 0x80);
+
+ (this->*(HandleOp[isNtf]))(aHeader, aPDU, aRes);
+}
+
+// Commands
+//
+
+nsresult
+GonkSensorsPollModule::EnableSensorCmd(int32_t aId, GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ UniquePtr<DaemonSocketPDU> pdu =
+ MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_ENABLE_SENSOR, 0);
+
+ nsresult rv = PackPDU(aId, *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu.get(), aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ Unused << pdu.release();
+ return NS_OK;
+}
+
+nsresult
+GonkSensorsPollModule::DisableSensorCmd(int32_t aId, GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ UniquePtr<DaemonSocketPDU> pdu =
+ MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_DISABLE_SENSOR, 0);
+
+ nsresult rv = PackPDU(aId, *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu.get(), aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ Unused << pdu.release();
+ return NS_OK;
+}
+
+nsresult
+GonkSensorsPollModule::SetPeriodCmd(int32_t aId, uint64_t aPeriod,
+ GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ UniquePtr<DaemonSocketPDU> pdu =
+ MakeUnique<DaemonSocketPDU>(SERVICE_ID, OPCODE_SET_PERIOD, 0);
+
+ nsresult rv = PackPDU(aId, *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aPeriod, *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu.get(), aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ Unused << pdu.release();
+ return NS_OK;
+}
+
+// Responses
+//
+
+void
+GonkSensorsPollModule::ErrorRsp(
+ const DaemonSocketPDUHeader& aHeader,
+ DaemonSocketPDU& aPDU, GonkSensorsPollResultHandler* aRes)
+{
+ ErrorRunnable::Dispatch(
+ aRes, &GonkSensorsPollResultHandler::OnError, UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::EnableSensorRsp(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+ GonkSensorsPollResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &GonkSensorsPollResultHandler::EnableSensor, UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::DisableSensorRsp(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+ GonkSensorsPollResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &GonkSensorsPollResultHandler::DisableSensor, UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::SetPeriodRsp(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+ GonkSensorsPollResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &GonkSensorsPollResultHandler::SetPeriod, UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::HandleRsp(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+ DaemonSocketResultHandler* aRes)
+{
+ static void (GonkSensorsPollModule::* const sHandleRsp[])(
+ const DaemonSocketPDUHeader&, DaemonSocketPDU&,
+ GonkSensorsPollResultHandler*) = {
+ [OPCODE_ERROR] = &GonkSensorsPollModule::ErrorRsp,
+ [OPCODE_ENABLE_SENSOR] = &GonkSensorsPollModule::EnableSensorRsp,
+ [OPCODE_DISABLE_SENSOR] = &GonkSensorsPollModule::DisableSensorRsp,
+ [OPCODE_SET_PERIOD] = &GonkSensorsPollModule::SetPeriodRsp,
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
+
+ if (!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(sHandleRsp)) ||
+ !sHandleRsp[aHeader.mOpcode]) {
+ HAL_ERR("Sensors poll response opcode %d unknown", aHeader.mOpcode);
+ return;
+ }
+
+ RefPtr<GonkSensorsPollResultHandler> res =
+ static_cast<GonkSensorsPollResultHandler*>(aRes);
+
+ if (!res) {
+ return; // Return early if no result handler has been set for response
+ }
+
+ (this->*(sHandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
+}
+
+// Notifications
+//
+
+// Returns the current notification handler to a notification runnable
+class GonkSensorsPollModule::NotificationHandlerWrapper final
+{
+public:
+ typedef GonkSensorsPollNotificationHandler ObjectType;
+
+ static ObjectType* GetInstance()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return sNotificationHandler;
+ }
+
+ static GonkSensorsPollNotificationHandler* sNotificationHandler;
+};
+
+GonkSensorsPollNotificationHandler*
+ GonkSensorsPollModule::NotificationHandlerWrapper::sNotificationHandler;
+
+void
+GonkSensorsPollModule::ErrorNtf(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+ ErrorNotification::Dispatch(
+ &GonkSensorsPollNotificationHandler::ErrorNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::SensorDetectedNtf(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+ SensorDetectedNotification::Dispatch(
+ &GonkSensorsPollNotificationHandler::SensorDetectedNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::SensorLostNtf(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+ SensorLostNotification::Dispatch(
+ &GonkSensorsPollNotificationHandler::SensorLostNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::EventNtf(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU)
+{
+ EventNotification::Dispatch(
+ &GonkSensorsPollNotificationHandler::EventNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+GonkSensorsPollModule::HandleNtf(
+ const DaemonSocketPDUHeader& aHeader, DaemonSocketPDU& aPDU,
+ DaemonSocketResultHandler* aRes)
+{
+ static void (GonkSensorsPollModule::* const sHandleNtf[])(
+ const DaemonSocketPDUHeader&, DaemonSocketPDU&) = {
+ [0] = &GonkSensorsPollModule::ErrorNtf,
+ [1] = &GonkSensorsPollModule::SensorDetectedNtf,
+ [2] = &GonkSensorsPollModule::SensorLostNtf,
+ [3] = &GonkSensorsPollModule::EventNtf
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ uint8_t index = aHeader.mOpcode - 0x80;
+
+ if (!(index < MOZ_ARRAY_LENGTH(sHandleNtf)) || !sHandleNtf[index]) {
+ HAL_ERR("Sensors poll notification opcode %d unknown", aHeader.mOpcode);
+ return;
+ }
+
+ (this->*(sHandleNtf[index]))(aHeader, aPDU);
+}
+
+//
+// GonkSensorsPollInterface
+//
+
+GonkSensorsPollInterface::GonkSensorsPollInterface(
+ GonkSensorsPollModule* aModule)
+ : mModule(aModule)
+{ }
+
+GonkSensorsPollInterface::~GonkSensorsPollInterface()
+{ }
+
+void
+GonkSensorsPollInterface::SetNotificationHandler(
+ GonkSensorsPollNotificationHandler* aNotificationHandler)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ GonkSensorsPollModule::NotificationHandlerWrapper::sNotificationHandler =
+ aNotificationHandler;
+}
+
+nsresult
+GonkSensorsPollInterface::SetProtocolVersion(unsigned long aProtocolVersion)
+{
+ MOZ_ASSERT(mModule);
+
+ return mModule->SetProtocolVersion(aProtocolVersion);
+}
+
+void
+GonkSensorsPollInterface::EnableSensor(int32_t aId,
+ GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ nsresult rv = mModule->EnableSensorCmd(aId, aRes);
+ if (NS_FAILED(rv)) {
+ DispatchError(aRes, rv);
+ }
+}
+
+void
+GonkSensorsPollInterface::DisableSensor(int32_t aId,
+ GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ nsresult rv = mModule->DisableSensorCmd(aId, aRes);
+ if (NS_FAILED(rv)) {
+ DispatchError(aRes, rv);
+ }
+}
+
+void
+GonkSensorsPollInterface::SetPeriod(int32_t aId, uint64_t aPeriod,
+ GonkSensorsPollResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ nsresult rv = mModule->SetPeriodCmd(aId, aPeriod, aRes);
+ if (NS_FAILED(rv)) {
+ DispatchError(aRes, rv);
+ }
+}
+
+void
+GonkSensorsPollInterface::DispatchError(
+ GonkSensorsPollResultHandler* aRes, SensorsError aError)
+{
+ DaemonResultRunnable1<GonkSensorsPollResultHandler, void,
+ SensorsError, SensorsError>::Dispatch(
+ aRes, &GonkSensorsPollResultHandler::OnError,
+ ConstantInitOp1<SensorsError>(aError));
+}
+
+void
+GonkSensorsPollInterface::DispatchError(
+ GonkSensorsPollResultHandler* aRes, nsresult aRv)
+{
+ SensorsError error;
+
+ if (NS_FAILED(Convert(aRv, error))) {
+ error = SENSORS_ERROR_FAIL;
+ }
+ DispatchError(aRes, error);
+}
+
+} // namespace hal
+} // namespace mozilla