summaryrefslogtreecommitdiff
path: root/modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp')
-rw-r--r--modules/sensors/dynamic_sensor/DynamicSensorsSubHal.cpp239
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;
+}
+