diff options
| -rw-r--r-- | services/sensorservice/AidlSensorHalWrapper.cpp | 656 | ||||
| -rw-r--r-- | services/sensorservice/AidlSensorHalWrapper.h | 97 | ||||
| -rw-r--r-- | services/sensorservice/Android.bp | 6 | ||||
| -rw-r--r-- | services/sensorservice/HidlSensorHalWrapper.cpp | 87 | ||||
| -rw-r--r-- | services/sensorservice/HidlSensorHalWrapper.h | 14 | ||||
| -rw-r--r-- | services/sensorservice/SensorDevice.cpp | 41 | ||||
| -rw-r--r-- | services/sensorservice/SensorDevice.h | 1 |
7 files changed, 824 insertions, 78 deletions
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp new file mode 100644 index 0000000000..74c47ba5d0 --- /dev/null +++ b/services/sensorservice/AidlSensorHalWrapper.cpp @@ -0,0 +1,656 @@ +/* + * 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 "AidlSensorHalWrapper.h" +#include "ISensorsWrapper.h" +#include "SensorDeviceUtils.h" +#include "android/hardware/sensors/2.0/types.h" + +#include <aidl/android/hardware/sensors/BnSensorsCallback.h> +#include <aidlcommonsupport/NativeHandle.h> +#include <android-base/logging.h> +#include <android/binder_manager.h> + +using ::aidl::android::hardware::sensors::AdditionalInfo; +using ::aidl::android::hardware::sensors::DynamicSensorInfo; +using ::aidl::android::hardware::sensors::Event; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::SensorInfo; +using ::aidl::android::hardware::sensors::SensorStatus; +using ::aidl::android::hardware::sensors::SensorType; +using ::android::AidlMessageQueue; +using ::android::hardware::EventFlag; +using ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT; + +namespace android { + +namespace { + +status_t convertToStatus(ndk::ScopedAStatus status) { + if (status.isOk()) { + return OK; + } else { + switch (status.getExceptionCode()) { + case EX_ILLEGAL_ARGUMENT: { + return BAD_VALUE; + } + case EX_SECURITY: { + return PERMISSION_DENIED; + } + case EX_UNSUPPORTED_OPERATION: { + return INVALID_OPERATION; + } + case EX_SERVICE_SPECIFIC: { + switch (status.getServiceSpecificError()) { + case ISensors::ERROR_BAD_VALUE: { + return BAD_VALUE; + } + case ISensors::ERROR_NO_MEMORY: { + return NO_MEMORY; + } + default: { + return UNKNOWN_ERROR; + } + } + } + default: { + return UNKNOWN_ERROR; + } + } + } +} + +void convertToSensor(const SensorInfo &src, sensor_t *dst) { + dst->name = strdup(src.name.c_str()); + dst->vendor = strdup(src.vendor.c_str()); + dst->version = src.version; + dst->handle = src.sensorHandle; + dst->type = (int)src.type; + dst->maxRange = src.maxRange; + dst->resolution = src.resolution; + dst->power = src.power; + dst->minDelay = src.minDelayUs; + dst->fifoReservedEventCount = src.fifoReservedEventCount; + dst->fifoMaxEventCount = src.fifoMaxEventCount; + dst->stringType = strdup(src.typeAsString.c_str()); + dst->requiredPermission = strdup(src.requiredPermission.c_str()); + dst->maxDelay = src.maxDelayUs; + dst->flags = src.flags; + dst->reserved[0] = dst->reserved[1] = 0; +} + +void convertToSensorEvent(const Event &src, sensors_event_t *dst) { + *dst = {.version = sizeof(sensors_event_t), + .sensor = src.sensorHandle, + .type = (int32_t)src.sensorType, + .reserved0 = 0, + .timestamp = src.timestamp}; + + switch (src.sensorType) { + case SensorType::META_DATA: { + // Legacy HALs expect the handle reference in the meta data field. + // Copy it over from the handle of the event. + dst->meta_data.what = (int32_t)src.payload.get<Event::EventPayload::meta>().what; + dst->meta_data.sensor = src.sensorHandle; + // Set the sensor handle to 0 to maintain compatibility. + dst->sensor = 0; + break; + } + + case SensorType::ACCELEROMETER: + case SensorType::MAGNETIC_FIELD: + case SensorType::ORIENTATION: + case SensorType::GYROSCOPE: + case SensorType::GRAVITY: + case SensorType::LINEAR_ACCELERATION: { + dst->acceleration.x = src.payload.get<Event::EventPayload::vec3>().x; + dst->acceleration.y = src.payload.get<Event::EventPayload::vec3>().y; + dst->acceleration.z = src.payload.get<Event::EventPayload::vec3>().z; + dst->acceleration.status = (int32_t)src.payload.get<Event::EventPayload::vec3>().status; + break; + } + + case SensorType::GAME_ROTATION_VECTOR: { + dst->data[0] = src.payload.get<Event::EventPayload::vec4>().x; + dst->data[1] = src.payload.get<Event::EventPayload::vec4>().y; + dst->data[2] = src.payload.get<Event::EventPayload::vec4>().z; + dst->data[3] = src.payload.get<Event::EventPayload::vec4>().w; + break; + } + + case SensorType::ROTATION_VECTOR: + case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + dst->data[0] = src.payload.get<Event::EventPayload::data>().values[0]; + dst->data[1] = src.payload.get<Event::EventPayload::data>().values[1]; + dst->data[2] = src.payload.get<Event::EventPayload::data>().values[2]; + dst->data[3] = src.payload.get<Event::EventPayload::data>().values[3]; + dst->data[4] = src.payload.get<Event::EventPayload::data>().values[4]; + break; + } + + case SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case SensorType::GYROSCOPE_UNCALIBRATED: + case SensorType::ACCELEROMETER_UNCALIBRATED: { + dst->uncalibrated_gyro.x_uncalib = src.payload.get<Event::EventPayload::uncal>().x; + dst->uncalibrated_gyro.y_uncalib = src.payload.get<Event::EventPayload::uncal>().y; + dst->uncalibrated_gyro.z_uncalib = src.payload.get<Event::EventPayload::uncal>().z; + dst->uncalibrated_gyro.x_bias = src.payload.get<Event::EventPayload::uncal>().xBias; + dst->uncalibrated_gyro.y_bias = src.payload.get<Event::EventPayload::uncal>().yBias; + dst->uncalibrated_gyro.z_bias = src.payload.get<Event::EventPayload::uncal>().zBias; + break; + } + + case SensorType::HINGE_ANGLE: + case SensorType::DEVICE_ORIENTATION: + case SensorType::LIGHT: + case SensorType::PRESSURE: + case SensorType::PROXIMITY: + case SensorType::RELATIVE_HUMIDITY: + case SensorType::AMBIENT_TEMPERATURE: + case SensorType::SIGNIFICANT_MOTION: + case SensorType::STEP_DETECTOR: + case SensorType::TILT_DETECTOR: + case SensorType::WAKE_GESTURE: + case SensorType::GLANCE_GESTURE: + case SensorType::PICK_UP_GESTURE: + case SensorType::WRIST_TILT_GESTURE: + case SensorType::STATIONARY_DETECT: + case SensorType::MOTION_DETECT: + case SensorType::HEART_BEAT: + case SensorType::LOW_LATENCY_OFFBODY_DETECT: { + dst->data[0] = src.payload.get<Event::EventPayload::scalar>(); + break; + } + + case SensorType::STEP_COUNTER: { + dst->u64.step_counter = src.payload.get<Event::EventPayload::stepCount>(); + break; + } + + case SensorType::HEART_RATE: { + dst->heart_rate.bpm = src.payload.get<Event::EventPayload::heartRate>().bpm; + dst->heart_rate.status = + (int8_t)src.payload.get<Event::EventPayload::heartRate>().status; + break; + } + + case SensorType::POSE_6DOF: { // 15 floats + for (size_t i = 0; i < 15; ++i) { + dst->data[i] = src.payload.get<Event::EventPayload::pose6DOF>().values[i]; + } + break; + } + + case SensorType::DYNAMIC_SENSOR_META: { + dst->dynamic_sensor_meta.connected = + src.payload.get<Event::EventPayload::dynamic>().connected; + dst->dynamic_sensor_meta.handle = + src.payload.get<Event::EventPayload::dynamic>().sensorHandle; + dst->dynamic_sensor_meta.sensor = NULL; // to be filled in later + + memcpy(dst->dynamic_sensor_meta.uuid, + src.payload.get<Event::EventPayload::dynamic>().uuid.values.data(), 16); + + break; + } + + case SensorType::ADDITIONAL_INFO: { + const AdditionalInfo &srcInfo = src.payload.get<Event::EventPayload::additional>(); + + additional_info_event_t *dstInfo = &dst->additional_info; + dstInfo->type = (int32_t)srcInfo.type; + dstInfo->serial = srcInfo.serial; + + // TODO(b/195593357): Finish additional info conversion + // CHECK_EQ(sizeof(srcInfo.payload.values), sizeof(dstInfo->data_int32)); + + // memcpy(dstInfo->data_int32, + // &srcInfo.u, + // sizeof(dstInfo->data_int32)); + + break; + } + + default: { + CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + + memcpy(dst->data, src.payload.get<Event::EventPayload::data>().values.data(), + 16 * sizeof(float)); + break; + } + } +} + +void convertFromSensorEvent(const sensors_event_t &src, Event *dst) { + *dst = { + .timestamp = src.timestamp, + .sensorHandle = src.sensor, + }; + + switch (dst->sensorType) { + case SensorType::META_DATA: { + Event::EventPayload::MetaData meta; + meta.what = (Event::EventPayload::MetaData::MetaDataEventType)src.meta_data.what; + // Legacy HALs contain the handle reference in the meta data field. + // Copy that over to the handle of the event. In legacy HALs this + // field was expected to be 0. + dst->sensorHandle = src.meta_data.sensor; + dst->payload.set<Event::EventPayload::Tag::meta>(meta); + break; + } + + case SensorType::ACCELEROMETER: + case SensorType::MAGNETIC_FIELD: + case SensorType::ORIENTATION: + case SensorType::GYROSCOPE: + case SensorType::GRAVITY: + case SensorType::LINEAR_ACCELERATION: { + Event::EventPayload::Vec3 vec3; + vec3.x = src.acceleration.x; + vec3.y = src.acceleration.y; + vec3.z = src.acceleration.z; + vec3.status = (SensorStatus)src.acceleration.status; + dst->payload.set<Event::EventPayload::Tag::vec3>(vec3); + break; + } + + case SensorType::GAME_ROTATION_VECTOR: { + Event::EventPayload::Vec4 vec4; + vec4.x = src.data[0]; + vec4.y = src.data[1]; + vec4.z = src.data[2]; + vec4.w = src.data[3]; + dst->payload.set<Event::EventPayload::Tag::vec4>(vec4); + break; + } + + case SensorType::ROTATION_VECTOR: + case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + Event::EventPayload::Data data; + memcpy(data.values.data(), src.data, 5 * sizeof(float)); + dst->payload.set<Event::EventPayload::Tag::data>(data); + break; + } + + case SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case SensorType::GYROSCOPE_UNCALIBRATED: + case SensorType::ACCELEROMETER_UNCALIBRATED: { + Event::EventPayload::Uncal uncal; + uncal.x = src.uncalibrated_gyro.x_uncalib; + uncal.y = src.uncalibrated_gyro.y_uncalib; + uncal.z = src.uncalibrated_gyro.z_uncalib; + uncal.xBias = src.uncalibrated_gyro.x_bias; + uncal.yBias = src.uncalibrated_gyro.y_bias; + uncal.zBias = src.uncalibrated_gyro.z_bias; + dst->payload.set<Event::EventPayload::Tag::uncal>(uncal); + break; + } + + case SensorType::DEVICE_ORIENTATION: + case SensorType::LIGHT: + case SensorType::PRESSURE: + case SensorType::PROXIMITY: + case SensorType::RELATIVE_HUMIDITY: + case SensorType::AMBIENT_TEMPERATURE: + case SensorType::SIGNIFICANT_MOTION: + case SensorType::STEP_DETECTOR: + case SensorType::TILT_DETECTOR: + case SensorType::WAKE_GESTURE: + case SensorType::GLANCE_GESTURE: + case SensorType::PICK_UP_GESTURE: + case SensorType::WRIST_TILT_GESTURE: + case SensorType::STATIONARY_DETECT: + case SensorType::MOTION_DETECT: + case SensorType::HEART_BEAT: + case SensorType::LOW_LATENCY_OFFBODY_DETECT: + case SensorType::HINGE_ANGLE: { + dst->payload.set<Event::EventPayload::Tag::scalar>((float)src.data[0]); + break; + } + + case SensorType::STEP_COUNTER: { + dst->payload.set<Event::EventPayload::Tag::stepCount>(src.u64.step_counter); + break; + } + + case SensorType::HEART_RATE: { + Event::EventPayload::HeartRate heartRate; + heartRate.bpm = src.heart_rate.bpm; + heartRate.status = (SensorStatus)src.heart_rate.status; + dst->payload.set<Event::EventPayload::Tag::heartRate>(heartRate); + break; + } + + case SensorType::POSE_6DOF: { // 15 floats + Event::EventPayload::Pose6Dof pose6DOF; + for (size_t i = 0; i < 15; ++i) { + pose6DOF.values[i] = src.data[i]; + } + dst->payload.set<Event::EventPayload::Tag::pose6DOF>(pose6DOF); + break; + } + + case SensorType::DYNAMIC_SENSOR_META: { + DynamicSensorInfo dynamic; + dynamic.connected = src.dynamic_sensor_meta.connected; + dynamic.sensorHandle = src.dynamic_sensor_meta.handle; + + memcpy(dynamic.uuid.values.data(), src.dynamic_sensor_meta.uuid, 16); + dst->payload.set<Event::EventPayload::Tag::dynamic>(dynamic); + break; + } + + case SensorType::ADDITIONAL_INFO: { + AdditionalInfo info; + const additional_info_event_t &srcInfo = src.additional_info; + info.type = (AdditionalInfo::AdditionalInfoType)srcInfo.type; + info.serial = srcInfo.serial; + + // TODO(b/195593357): Finish additional info conversion + + dst->payload.set<Event::EventPayload::Tag::additional>(info); + break; + } + + default: { + CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + + Event::EventPayload::Data data; + memcpy(data.values.data(), src.data, 16 * sizeof(float)); + dst->payload.set<Event::EventPayload::Tag::data>(data); + break; + } + } +} + +void serviceDied(void *cookie) { + ALOGW("Sensors HAL died, attempting to reconnect."); + ((AidlSensorHalWrapper *)cookie)->prepareForReconnect(); +} + +template <typename EnumType> +constexpr typename std::underlying_type<EnumType>::type asBaseType(EnumType value) { + return static_cast<typename std::underlying_type<EnumType>::type>(value); +} + +enum EventQueueFlagBitsInternal : uint32_t { + INTERNAL_WAKE = 1 << 16, +}; + +} // anonymous namespace + +class AidlSensorsCallback : public ::aidl::android::hardware::sensors::BnSensorsCallback { +public: + AidlSensorsCallback(AidlSensorHalWrapper::SensorDeviceCallback *sensorDeviceCallback) + : mSensorDeviceCallback(sensorDeviceCallback) {} + + ::ndk::ScopedAStatus onDynamicSensorsConnected( + const std::vector<SensorInfo> &sensorInfos) override { + std::vector<sensor_t> sensors; + for (const SensorInfo &sensorInfo : sensorInfos) { + sensor_t sensor; + convertToSensor(sensorInfo, &sensor); + sensors.push_back(sensor); + } + + mSensorDeviceCallback->onDynamicSensorsConnected(sensors); + return ::ndk::ScopedAStatus::ok(); + } + + ::ndk::ScopedAStatus onDynamicSensorsDisconnected( + const std::vector<int32_t> &sensorHandles) override { + mSensorDeviceCallback->onDynamicSensorsDisconnected(sensorHandles); + return ::ndk::ScopedAStatus::ok(); + } + +private: + ISensorHalWrapper::SensorDeviceCallback *mSensorDeviceCallback; +}; + +AidlSensorHalWrapper::AidlSensorHalWrapper() + : mEventQueueFlag(nullptr), + mWakeLockQueueFlag(nullptr), + mDeathRecipient(AIBinder_DeathRecipient_new(serviceDied)) {} + +bool AidlSensorHalWrapper::supportsPolling() { + return false; +} + +bool AidlSensorHalWrapper::supportsMessageQueues() { + return true; +} + +bool AidlSensorHalWrapper::connect(SensorDeviceCallback *callback) { + mSensorDeviceCallback = callback; + mSensors = nullptr; + + auto aidlServiceName = std::string() + ISensors::descriptor + "/default"; + if (AServiceManager_isDeclared(aidlServiceName.c_str())) { + if (mSensors != nullptr) { + AIBinder_unlinkToDeath(mSensors->asBinder().get(), mDeathRecipient.get(), this); + } + + ndk::SpAIBinder binder(AServiceManager_waitForService(aidlServiceName.c_str())); + if (binder.get() != nullptr) { + + mSensors = ISensors::fromBinder(binder); + mEventQueue = std::make_unique<AidlMessageQueue< + Event, SynchronizedReadWrite>>(MAX_RECEIVE_BUFFER_EVENT_COUNT, + /*configureEventFlagWord=*/true); + + mWakeLockQueue = std::make_unique<AidlMessageQueue< + int32_t, SynchronizedReadWrite>>(MAX_RECEIVE_BUFFER_EVENT_COUNT, + /*configureEventFlagWord=*/true); + if (mEventQueueFlag != nullptr) { + EventFlag::deleteEventFlag(&mEventQueueFlag); + } + EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag); + if (mWakeLockQueueFlag != nullptr) { + EventFlag::deleteEventFlag(&mWakeLockQueueFlag); + } + EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(), &mWakeLockQueueFlag); + + CHECK(mEventQueue != nullptr && mEventQueueFlag != nullptr && + mWakeLockQueue != nullptr && mWakeLockQueueFlag != nullptr); + + mCallback = ndk::SharedRefBase::make<AidlSensorsCallback>(mSensorDeviceCallback); + mSensors->initialize(mEventQueue->dupeDesc(), mWakeLockQueue->dupeDesc(), mCallback); + + AIBinder_linkToDeath(mSensors->asBinder().get(), mDeathRecipient.get(), this); + } else { + ALOGE("Could not connect to declared sensors AIDL HAL"); + } + } + + return mSensors != nullptr; +} + +void AidlSensorHalWrapper::prepareForReconnect() { + mReconnecting = true; + if (mEventQueueFlag != nullptr) { + mEventQueueFlag->wake(asBaseType(INTERNAL_WAKE)); + } +} + +ssize_t AidlSensorHalWrapper::poll(sensors_event_t * /* buffer */, size_t /* count */) { + return 0; +} + +ssize_t AidlSensorHalWrapper::pollFmq(sensors_event_t *buffer, size_t maxNumEventsToRead) { + ssize_t eventsRead = 0; + size_t availableEvents = mEventQueue->availableToRead(); + + if (availableEvents == 0) { + uint32_t eventFlagState = 0; + + // Wait for events to become available. This is necessary so that the Event FMQ's read() is + // able to be called with the correct number of events to read. If the specified number of + // events is not available, then read() would return no events, possibly introducing + // additional latency in delivering events to applications. + if (mEventQueueFlag != nullptr) { + mEventQueueFlag->wait(asBaseType(ISensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS) | + asBaseType(INTERNAL_WAKE), + &eventFlagState); + } + availableEvents = mEventQueue->availableToRead(); + + if ((eventFlagState & asBaseType(INTERNAL_WAKE)) && mReconnecting) { + ALOGD("Event FMQ internal wake, returning from poll with no events"); + return DEAD_OBJECT; + } + } + + size_t eventsToRead = std::min({availableEvents, maxNumEventsToRead, mEventBuffer.size()}); + if (eventsToRead > 0) { + if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) { + // Notify the Sensors HAL that sensor events have been read. This is required to support + // the use of writeBlocking by the Sensors HAL. + if (mEventQueueFlag != nullptr) { + mEventQueueFlag->wake(asBaseType(ISensors::EVENT_QUEUE_FLAG_BITS_EVENTS_READ)); + } + + for (size_t i = 0; i < eventsToRead; i++) { + convertToSensorEvent(mEventBuffer[i], &buffer[i]); + } + eventsRead = eventsToRead; + } else { + ALOGW("Failed to read %zu events, currently %zu events available", eventsToRead, + availableEvents); + } + } + + return eventsRead; +} + +std::vector<sensor_t> AidlSensorHalWrapper::getSensorsList() { + std::vector<sensor_t> sensorsFound; + + if (mSensors != nullptr) { + std::vector<SensorInfo> list; + mSensors->getSensorsList(&list); + for (size_t i = 0; i < list.size(); i++) { + sensor_t sensor; + convertToSensor(list[i], &sensor); + sensorsFound.push_back(sensor); + } + } + + return sensorsFound; +} + +status_t AidlSensorHalWrapper::setOperationMode(SensorService::Mode mode) { + if (mSensors == nullptr) return NO_INIT; + return convertToStatus(mSensors->setOperationMode(static_cast<ISensors::OperationMode>(mode))); +} + +status_t AidlSensorHalWrapper::activate(int32_t sensorHandle, bool enabled) { + if (mSensors == nullptr) return NO_INIT; + return convertToStatus(mSensors->activate(sensorHandle, enabled)); +} + +status_t AidlSensorHalWrapper::batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) { + if (mSensors == nullptr) return NO_INIT; + return convertToStatus(mSensors->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs)); +} + +status_t AidlSensorHalWrapper::flush(int32_t sensorHandle) { + if (mSensors == nullptr) return NO_INIT; + return convertToStatus(mSensors->flush(sensorHandle)); +} + +status_t AidlSensorHalWrapper::injectSensorData(const sensors_event_t *event) { + if (mSensors == nullptr) return NO_INIT; + + Event ev; + convertFromSensorEvent(*event, &ev); + return convertToStatus(mSensors->injectSensorData(ev)); +} + +status_t AidlSensorHalWrapper::registerDirectChannel(const sensors_direct_mem_t *memory, + int32_t *channelHandle) { + if (mSensors == nullptr) return NO_INIT; + + ISensors::SharedMemInfo::SharedMemType type; + switch (memory->type) { + case SENSOR_DIRECT_MEM_TYPE_ASHMEM: + type = ISensors::SharedMemInfo::SharedMemType::ASHMEM; + break; + case SENSOR_DIRECT_MEM_TYPE_GRALLOC: + type = ISensors::SharedMemInfo::SharedMemType::GRALLOC; + break; + default: + return BAD_VALUE; + } + + if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { + return BAD_VALUE; + } + ISensors::SharedMemInfo::SharedMemFormat format = + ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT; + + ISensors::SharedMemInfo mem = { + .type = type, + .format = format, + .size = static_cast<int32_t>(memory->size), + .memoryHandle = makeToAidl(memory->handle), + }; + + return convertToStatus(mSensors->registerDirectChannel(mem, channelHandle)); +} + +status_t AidlSensorHalWrapper::unregisterDirectChannel(int32_t channelHandle) { + if (mSensors == nullptr) return NO_INIT; + return convertToStatus(mSensors->unregisterDirectChannel(channelHandle)); +} + +status_t AidlSensorHalWrapper::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, + const struct sensors_direct_cfg_t *config) { + if (mSensors == nullptr) return NO_INIT; + + ISensors::RateLevel rate; + switch (config->rate_level) { + case SENSOR_DIRECT_RATE_STOP: + rate = ISensors::RateLevel::STOP; + break; + case SENSOR_DIRECT_RATE_NORMAL: + rate = ISensors::RateLevel::NORMAL; + break; + case SENSOR_DIRECT_RATE_FAST: + rate = ISensors::RateLevel::FAST; + break; + case SENSOR_DIRECT_RATE_VERY_FAST: + rate = ISensors::RateLevel::VERY_FAST; + break; + default: + return BAD_VALUE; + } + + int32_t token; + mSensors->configDirectReport(sensorHandle, channelHandle, rate, &token); + return token; +} + +void AidlSensorHalWrapper::writeWakeLockHandled(uint32_t count) { + int signedCount = (int)count; + if (mWakeLockQueue->write(&signedCount)) { + mWakeLockQueueFlag->wake(asBaseType(ISensors::WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN)); + } else { + ALOGW("Failed to write wake lock handled"); + } +} + +} // namespace android diff --git a/services/sensorservice/AidlSensorHalWrapper.h b/services/sensorservice/AidlSensorHalWrapper.h new file mode 100644 index 0000000000..9f61993923 --- /dev/null +++ b/services/sensorservice/AidlSensorHalWrapper.h @@ -0,0 +1,97 @@ +/* + * 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. + */ + +#ifndef ANDROID_AIDL_SENSOR_HAL_WRAPPER_H +#define ANDROID_AIDL_SENSOR_HAL_WRAPPER_H + +#include "ISensorHalWrapper.h" + +#include <aidl/android/hardware/sensors/ISensors.h> +#include <fmq/AidlMessageQueue.h> +#include <sensor/SensorEventQueue.h> + +namespace android { + +class AidlSensorHalWrapper : public ISensorHalWrapper { +public: + AidlSensorHalWrapper(); + + ~AidlSensorHalWrapper() override { + if (mEventQueueFlag != nullptr) { + ::android::hardware::EventFlag::deleteEventFlag(&mEventQueueFlag); + mEventQueueFlag = nullptr; + } + if (mWakeLockQueueFlag != nullptr) { + ::android::hardware::EventFlag::deleteEventFlag(&mWakeLockQueueFlag); + mWakeLockQueueFlag = nullptr; + } + } + + virtual bool connect(SensorDeviceCallback *callback) override; + + virtual void prepareForReconnect() override; + + virtual bool supportsPolling() override; + + virtual bool supportsMessageQueues() override; + + virtual ssize_t poll(sensors_event_t *buffer, size_t count) override; + + virtual ssize_t pollFmq(sensors_event_t *buffer, size_t count) override; + + virtual std::vector<sensor_t> getSensorsList() override; + + virtual status_t setOperationMode(SensorService::Mode mode) override; + + virtual status_t activate(int32_t sensorHandle, bool enabled) override; + + virtual status_t batch(int32_t sensorHandle, int64_t samplingPeriodNs, + int64_t maxReportLatencyNs) override; + + virtual status_t flush(int32_t sensorHandle) override; + + virtual status_t injectSensorData(const sensors_event_t *event) override; + + virtual status_t registerDirectChannel(const sensors_direct_mem_t *memory, + int32_t *channelHandle) override; + + virtual status_t unregisterDirectChannel(int32_t channelHandle) override; + + virtual status_t configureDirectChannel(int32_t sensorHandle, int32_t channelHandle, + const struct sensors_direct_cfg_t *config) override; + + virtual void writeWakeLockHandled(uint32_t count) override; + +private: + std::shared_ptr<aidl::android::hardware::sensors::ISensors> mSensors; + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mCallback; + std::unique_ptr<::android::AidlMessageQueue<::aidl::android::hardware::sensors::Event, + SynchronizedReadWrite>> + mEventQueue; + std::unique_ptr<::android::AidlMessageQueue<int, SynchronizedReadWrite>> mWakeLockQueue; + ::android::hardware::EventFlag *mEventQueueFlag; + ::android::hardware::EventFlag *mWakeLockQueueFlag; + SensorDeviceCallback *mSensorDeviceCallback; + std::array<::aidl::android::hardware::sensors::Event, + ::android::SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT> + mEventBuffer; + + ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; +}; + +} // namespace android + +#endif // ANDROID_AIDL_SENSOR_HAL_WRAPPER_H diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp index f8d9dc2a9d..d5b629d564 100644 --- a/services/sensorservice/Android.bp +++ b/services/sensorservice/Android.bp @@ -11,6 +11,7 @@ cc_library_shared { name: "libsensorservice", srcs: [ + "AidlSensorHalWrapper.cpp", "BatteryService.cpp", "CorrectedGyroSensor.cpp", "Fusion.cpp", @@ -61,14 +62,19 @@ cc_library_shared { "libbase", "libhidlbase", "libfmq", + "libbinder_ndk", "packagemanager_aidl-cpp", "android.hardware.sensors@1.0", "android.hardware.sensors@2.0", "android.hardware.sensors@2.1", + "android.hardware.common-V2-ndk", + "android.hardware.common.fmq-V1-ndk", ], static_libs: [ + "libaidlcommonsupport", "android.hardware.sensors@1.0-convert", + "android.hardware.sensors-V1-ndk", ], generated_headers: ["framework-cppstream-protos"], diff --git a/services/sensorservice/HidlSensorHalWrapper.cpp b/services/sensorservice/HidlSensorHalWrapper.cpp index dbb3da19a6..4c64e59615 100644 --- a/services/sensorservice/HidlSensorHalWrapper.cpp +++ b/services/sensorservice/HidlSensorHalWrapper.cpp @@ -76,11 +76,11 @@ void SensorsHalDeathReceiver::serviceDied( mHidlSensorHalWrapper->prepareForReconnect(); } -struct SensorsCallback : public ISensorsCallback { +struct HidlSensorsCallback : public ISensorsCallback { using Result = ::android::hardware::sensors::V1_0::Result; using SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; - SensorsCallback(ISensorHalWrapper::SensorDeviceCallback* sensorDeviceCallback) { + HidlSensorsCallback(ISensorHalWrapper::SensorDeviceCallback* sensorDeviceCallback) { mSensorDeviceCallback = sensorDeviceCallback; } @@ -143,18 +143,19 @@ ssize_t HidlSensorHalWrapper::poll(sensors_event_t* buffer, size_t count) { bool hidlTransportError = false; do { - auto ret = mSensors->poll( - count, [&](auto result, const auto& events, const auto& dynamicSensorsAdded) { - if (result == Result::OK) { - convertToSensorEventsAndQuantize(convertToNewEvents(events), - convertToNewSensorInfos( - dynamicSensorsAdded), - buffer); - err = (ssize_t)events.size(); - } else { - err = statusFromResult(result); - } - }); + auto ret = mSensors->poll(count, + [&](auto result, const auto& events, + const auto& dynamicSensorsAdded) { + if (result == Result::OK) { + convertToSensorEvents(convertToNewEvents(events), + convertToNewSensorInfos( + dynamicSensorsAdded), + buffer); + err = (ssize_t)events.size(); + } else { + err = statusFromResult(result); + } + }); if (ret.isOk()) { hidlTransportError = false; @@ -216,9 +217,6 @@ ssize_t HidlSensorHalWrapper::pollFmq(sensors_event_t* buffer, size_t maxNumEven for (size_t i = 0; i < eventsToRead; i++) { convertToSensorEvent(mEventBuffer[i], &buffer[i]); - android::SensorDeviceUtils::quantizeSensorEventValues(&buffer[i], - getResolutionForSensor( - buffer[i].sensor)); } eventsRead = eventsToRead; } else { @@ -482,7 +480,7 @@ ISensorHalWrapper::HalConnectionStatus HidlSensorHalWrapper::initializeHidlServi CHECK(mSensors != nullptr && mWakeLockQueue != nullptr && mEventQueueFlag != nullptr && mWakeLockQueueFlag != nullptr); - mCallback = new SensorsCallback(mSensorDeviceCallback); + mCallback = sp<HidlSensorsCallback>::make(mSensorDeviceCallback); status_t status = checkReturnAndGetStatus(mSensors->initialize(*mWakeLockQueue->getDesc(), mCallback)); @@ -500,63 +498,18 @@ ISensorHalWrapper::HalConnectionStatus HidlSensorHalWrapper::initializeHidlServi void HidlSensorHalWrapper::convertToSensorEvent(const Event& src, sensors_event_t* dst) { android::hardware::sensors::V2_1::implementation::convertToSensorEvent(src, dst); - - if (src.sensorType == android::hardware::sensors::V2_1::SensorType::DYNAMIC_SENSOR_META) { - const hardware::sensors::V1_0::DynamicSensorInfo& dyn = src.u.dynamic; - - dst->dynamic_sensor_meta.connected = dyn.connected; - dst->dynamic_sensor_meta.handle = dyn.sensorHandle; - if (dyn.connected) { - std::unique_lock<std::mutex> lock(mDynamicSensorsMutex); - // Give MAX_DYN_SENSOR_WAIT_SEC for onDynamicSensorsConnected to be invoked since it - // can be received out of order from this event due to a bug in the HIDL spec that - // marks it as oneway. - auto it = mConnectedDynamicSensors.find(dyn.sensorHandle); - if (it == mConnectedDynamicSensors.end()) { - mDynamicSensorsCv.wait_for(lock, MAX_DYN_SENSOR_WAIT, [&, dyn] { - return mConnectedDynamicSensors.find(dyn.sensorHandle) != - mConnectedDynamicSensors.end(); - }); - it = mConnectedDynamicSensors.find(dyn.sensorHandle); - CHECK(it != mConnectedDynamicSensors.end()); - } - - dst->dynamic_sensor_meta.sensor = &it->second; - - memcpy(dst->dynamic_sensor_meta.uuid, dyn.uuid.data(), - sizeof(dst->dynamic_sensor_meta.uuid)); - } - } } -void HidlSensorHalWrapper::convertToSensorEventsAndQuantize( - const hidl_vec<Event>& src, const hidl_vec<SensorInfo>& dynamicSensorsAdded, - sensors_event_t* dst) { +void HidlSensorHalWrapper::convertToSensorEvents(const hidl_vec<Event>& src, + const hidl_vec<SensorInfo>& dynamicSensorsAdded, + sensors_event_t* dst) { if (dynamicSensorsAdded.size() > 0 && mCallback != nullptr) { mCallback->onDynamicSensorsConnected_2_1(dynamicSensorsAdded); } for (size_t i = 0; i < src.size(); ++i) { - android::hardware::sensors::V2_1::implementation::convertToSensorEvent(src[i], &dst[i]); - android::SensorDeviceUtils::quantizeSensorEventValues(&dst[i], - getResolutionForSensor( - dst[i].sensor)); + convertToSensorEvent(src[i], &dst[i]); } } -float HidlSensorHalWrapper::getResolutionForSensor(int sensorHandle) { - for (size_t i = 0; i < mSensorList.size(); i++) { - if (sensorHandle == mSensorList[i].handle) { - return mSensorList[i].resolution; - } - } - - auto it = mConnectedDynamicSensors.find(sensorHandle); - if (it != mConnectedDynamicSensors.end()) { - return it->second.resolution; - } - - return 0; -} - } // namespace android diff --git a/services/sensorservice/HidlSensorHalWrapper.h b/services/sensorservice/HidlSensorHalWrapper.h index 030247fc12..71c3512742 100644 --- a/services/sensorservice/HidlSensorHalWrapper.h +++ b/services/sensorservice/HidlSensorHalWrapper.h @@ -124,12 +124,6 @@ public: private: sp<::android::hardware::sensors::V2_1::implementation::ISensorsWrapperBase> mSensors; sp<::android::hardware::sensors::V2_1::ISensorsCallback> mCallback; - std::vector<sensor_t> mSensorList; - std::unordered_map<int32_t, sensor_t> mConnectedDynamicSensors; - - std::mutex mDynamicSensorsMutex; - std::condition_variable mDynamicSensorsCv; - static constexpr std::chrono::seconds MAX_DYN_SENSOR_WAIT{5}; // Keep track of any hidl transport failures SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors; @@ -153,9 +147,9 @@ private: void convertToSensorEvent(const Event& src, sensors_event_t* dst); - void convertToSensorEventsAndQuantize(const hardware::hidl_vec<Event>& src, - const hardware::hidl_vec<SensorInfo>& dynamicSensorsAdded, - sensors_event_t* dst); + void convertToSensorEvents(const hardware::hidl_vec<Event>& src, + const hardware::hidl_vec<SensorInfo>& dynamicSensorsAdded, + sensors_event_t* dst); bool connectHidlService(); @@ -167,8 +161,6 @@ private: typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue; std::unique_ptr<WakeLockQueue> mWakeLockQueue; - float getResolutionForSensor(int sensorHandle); - hardware::EventFlag* mEventQueueFlag; hardware::EventFlag* mWakeLockQueueFlag; diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp index ee621d6563..a0e30ac355 100644 --- a/services/sensorservice/SensorDevice.cpp +++ b/services/sensorservice/SensorDevice.cpp @@ -20,10 +20,15 @@ #include "android/hardware/sensors/2.1/types.h" #include "convertV2_1.h" +#include "AidlSensorHalWrapper.h" +#include "HidlSensorHalWrapper.h" + #include <android-base/logging.h> #include <android/util/ProtoOutputStream.h> #include <cutils/atomic.h> #include <frameworks/base/core/proto/android/service/sensor_service.proto.h> +#include <hardware/sensors-base.h> +#include <hardware/sensors.h> #include <sensors/convert.h> #include <utils/Errors.h> #include <utils/Singleton.h> @@ -132,11 +137,18 @@ void SensorDevice::initializeSensorList() { SensorDevice::~SensorDevice() {} bool SensorDevice::connectHalService() { + std::unique_ptr<ISensorHalWrapper> aidl_wrapper = std::make_unique<AidlSensorHalWrapper>(); + if (aidl_wrapper->connect(this)) { + mHalWrapper = std::move(aidl_wrapper); + return true; + } + std::unique_ptr<ISensorHalWrapper> hidl_wrapper = std::make_unique<HidlSensorHalWrapper>(); if (hidl_wrapper->connect(this)) { mHalWrapper = std::move(hidl_wrapper); return true; } + // TODO: check aidl connection; return false; } @@ -349,6 +361,35 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { ALOGE("Must support polling or FMQ"); eventsRead = -1; } + + if (eventsRead > 0) { + for (ssize_t i = 0; i < eventsRead; i++) { + float resolution = getResolutionForSensor(buffer[i].sensor); + android::SensorDeviceUtils::quantizeSensorEventValues(&buffer[i], resolution); + + if (buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) { + struct dynamic_sensor_meta_event& dyn = buffer[i].dynamic_sensor_meta; + if (dyn.connected) { + std::unique_lock<std::mutex> lock(mDynamicSensorsMutex); + // Give MAX_DYN_SENSOR_WAIT_SEC for onDynamicSensorsConnected to be invoked + // since it can be received out of order from this event due to a bug in the + // HIDL spec that marks it as oneway. + auto it = mConnectedDynamicSensors.find(dyn.handle); + if (it == mConnectedDynamicSensors.end()) { + mDynamicSensorsCv.wait_for(lock, MAX_DYN_SENSOR_WAIT, [&, dyn] { + return mConnectedDynamicSensors.find(dyn.handle) != + mConnectedDynamicSensors.end(); + }); + it = mConnectedDynamicSensors.find(dyn.handle); + CHECK(it != mConnectedDynamicSensors.end()); + } + + dyn.sensor = &it->second; + } + } + } + } + return eventsRead; } diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h index 80e77d96d4..747a6b0926 100644 --- a/services/sensorservice/SensorDevice.h +++ b/services/sensorservice/SensorDevice.h @@ -119,6 +119,7 @@ private: // HAL implementations. std::mutex mDynamicSensorsMutex; std::condition_variable mDynamicSensorsCv; + static constexpr std::chrono::seconds MAX_DYN_SENSOR_WAIT{5}; static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz mutable Mutex mLock; // protect mActivationCount[].batchParams |