blob: 101b983c6a714751765bdb389709431cf40051d9 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "BaseSensorObject.h"
#include "DynamicSensorsSubHal.h"
#include <convertV2_1.h>
#include <hardware/sensors-base.h>
#include <log/log.h>
#include <chrono>
#include <thread>
using ::android::hardware::sensors::V1_0::Result;
using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;
using ::android::hardware::sensors::V2_1::implementation::convertFromSensorEvent;
using ::android::hardware::sensors::V2_1::SensorInfo;
using ::android::hardware::sensors::V2_1::SensorType;
template<class T> using Return = ::android::hardware::Return<T>;
using ::android::hardware::Void;
namespace android {
namespace SensorHalExt {
static Result ResultFromStatus(status_t err) {
switch (err) {
case ::android::OK:
return Result::OK;
case ::android::PERMISSION_DENIED:
return Result::PERMISSION_DENIED;
case ::android::NO_MEMORY:
return Result::NO_MEMORY;
case ::android::BAD_VALUE:
return Result::BAD_VALUE;
default:
return Result::INVALID_OPERATION;
}
}
DynamicSensorsSubHal::DynamicSensorsSubHal() {
// initialize dynamic sensor manager
mDynamicSensorManager.reset(
DynamicSensorManager::createInstance(kDynamicHandleBase,
kMaxDynamicHandleCount,
this /* callback */));
}
// ISensors.
Return<Result> DynamicSensorsSubHal::setOperationMode(OperationMode mode) {
return (mode == static_cast<OperationMode>(SENSOR_HAL_NORMAL_MODE) ?
Result::OK : Result::BAD_VALUE);
}
Return<Result> DynamicSensorsSubHal::activate(int32_t sensor_handle,
bool enabled) {
int rc = mDynamicSensorManager->activate(sensor_handle, enabled);
return ResultFromStatus(rc);
}
Return<Result> DynamicSensorsSubHal::batch(
int32_t sensor_handle, int64_t sampling_period_ns,
int64_t max_report_latency_ns) {
int rc = mDynamicSensorManager->batch(sensor_handle, sampling_period_ns,
max_report_latency_ns);
return ResultFromStatus(rc);
}
Return<Result> DynamicSensorsSubHal::flush(int32_t sensor_handle) {
int rc = mDynamicSensorManager->flush(sensor_handle);
return ResultFromStatus(rc);
}
Return<void> DynamicSensorsSubHal::registerDirectChannel(
const SharedMemInfo& mem __unused,
registerDirectChannel_cb callback __unused) {
ALOGE("DynamicSensorsSubHal::registerDirectChannel not supported.");
return Void();
}
Return<Result> DynamicSensorsSubHal::unregisterDirectChannel(
int32_t channel_handle __unused) {
ALOGE("DynamicSensorsSubHal::unregisterDirectChannel not supported.");
return Result::INVALID_OPERATION;
}
Return<void> DynamicSensorsSubHal::configDirectReport(
int32_t sensor_handle __unused, int32_t channel_handle __unused,
RateLevel rate __unused, configDirectReport_cb callback __unused) {
ALOGE("DynamicSensorsSubHal::configDirectReport not supported.");
return Void();
}
Return<void> DynamicSensorsSubHal::getSensorsList_2_1(
getSensorsList_2_1_cb callback) {
const sensor_t& sensor_info = mDynamicSensorManager->getDynamicMetaSensor();
std::vector<SensorInfo> sensors;
ALOGD("DynamicSensorsSubHal::getSensorsList_2_1 invoked.");
// get the dynamic sensor info
sensors.resize(1);
sensors[0].sensorHandle = sensor_info.handle;
sensors[0].name = sensor_info.name;
sensors[0].vendor = sensor_info.vendor;
sensors[0].version = sensor_info.version;
sensors[0].type = static_cast<SensorType>(sensor_info.type);
sensors[0].typeAsString = sensor_info.stringType;
sensors[0].maxRange = sensor_info.maxRange;
sensors[0].resolution = sensor_info.resolution;
sensors[0].power = sensor_info.power;
sensors[0].minDelay = sensor_info.minDelay;
sensors[0].fifoReservedEventCount = sensor_info.fifoReservedEventCount;
sensors[0].fifoMaxEventCount = sensor_info.fifoMaxEventCount;
sensors[0].requiredPermission = sensor_info.requiredPermission;
sensors[0].maxDelay = sensor_info.maxDelay;
sensors[0].flags = sensor_info.flags;
callback(sensors);
return Void();
}
Return<Result> DynamicSensorsSubHal::injectSensorData_2_1(
const Event& event __unused) {
ALOGE("DynamicSensorsSubHal::injectSensorData_2_1 not supported.");
return Result::INVALID_OPERATION;
}
Return<void> DynamicSensorsSubHal::debug(
const hidl_handle& handle __unused,
const hidl_vec<hidl_string>& args __unused) {
return Void();
}
// ISensorsSubHal.
Return<Result> DynamicSensorsSubHal::initialize(
const sp<IHalProxyCallback>& hal_proxy_callback) {
ALOGD("DynamicSensorsSubHal::initialize invoked.");
mHalProxyCallback = hal_proxy_callback;
return Result::OK;
}
// SensorEventCallback.
int DynamicSensorsSubHal::submitEvent(SP(BaseSensorObject) sensor,
const sensors_event_t& e) {
std::vector<Event> events;
Event hal_event;
bool wakeup;
if (e.type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
const dynamic_sensor_meta_event_t* sensor_meta;
sensor_meta = static_cast<const dynamic_sensor_meta_event_t*>(
&(e.dynamic_sensor_meta));
if (sensor_meta->connected != 0) {
// The sensor framework must be notified of the connected sensor
// through the callback before handling the sensor added event. If
// it isn't, it will assert when looking up the sensor handle when
// processing the sensor added event.
//
// TODO (b/201529167): Fix dynamic sensors addition / removal when
// converting to AIDL.
// The sensor framework runs in a separate process from the sensor
// HAL, and it processes events in a dedicated thread, so it's
// possible the event handling can be done before the callback is
// run. Thus, a delay is added after sending notification of the
// connected sensor.
onSensorConnected(sensor_meta->handle, sensor_meta->sensor);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
convertFromSensorEvent(e, &hal_event);
events.push_back(hal_event);
if (sensor && sensor->getSensor()) {
wakeup = sensor->getSensor()->flags & SENSOR_FLAG_WAKE_UP;
} else {
wakeup = false;
}
ScopedWakelock wakelock = mHalProxyCallback->createScopedWakelock(wakeup);
mHalProxyCallback->postEvents(events, std::move(wakelock));
return 0;
}
void DynamicSensorsSubHal::onSensorConnected(
int handle, const sensor_t* sensor_info) {
hidl_vec<SensorInfo> sensor_list;
sensor_list.resize(1);
sensor_list[0].sensorHandle = handle;
sensor_list[0].name = sensor_info->name;
sensor_list[0].vendor = sensor_info->vendor;
sensor_list[0].version = sensor_info->version;
sensor_list[0].type = static_cast<SensorType>(sensor_info->type);
sensor_list[0].typeAsString = sensor_info->stringType;
sensor_list[0].maxRange = sensor_info->maxRange;
sensor_list[0].resolution = sensor_info->resolution;
sensor_list[0].power = sensor_info->power;
sensor_list[0].minDelay = sensor_info->minDelay;
sensor_list[0].fifoReservedEventCount = sensor_info->fifoReservedEventCount;
sensor_list[0].fifoMaxEventCount = sensor_info->fifoMaxEventCount;
sensor_list[0].requiredPermission = sensor_info->requiredPermission;
sensor_list[0].maxDelay = sensor_info->maxDelay;
sensor_list[0].flags = sensor_info->flags;
mHalProxyCallback->onDynamicSensorsConnected_2_1(sensor_list);
}
} // namespace SensorHalExt
} // namespace android
using ::android::hardware::sensors::V2_1::implementation::ISensorsSubHal;
ISensorsSubHal* sensorsHalGetSubHal_2_1(uint32_t* version) {
static android::SensorHalExt::DynamicSensorsSubHal subHal;
*version = SUB_HAL_2_1_VERSION;
return &subHal;
}