gecko-dev/hal/gonk/GonkSensorsPollInterface.cpp
2016-03-30 13:18:00 +02:00

432 lines
10 KiB
C++

/* -*- 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