diff options
Diffstat (limited to 'modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp')
-rw-r--r-- | modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp new file mode 100644 index 00000000..d5a9b3c0 --- /dev/null +++ b/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp @@ -0,0 +1,239 @@ +/* + * 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 = 1; + 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 = 1; + 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; +} + |