diff options
author | Haamed Gheibi <haamed@google.com> | 2022-02-04 13:47:26 -0800 |
---|---|---|
committer | Haamed Gheibi <haamed@google.com> | 2022-02-04 13:55:47 -0800 |
commit | f99b35c293439db0b7436b47b939eb8c7bf21b51 (patch) | |
tree | 6cd9b0719554809447c845616317cca5409b93ae /sensors/aidl | |
parent | a028272dee9220e6810cbdcfb2328c34f8afe4c2 (diff) | |
parent | 332dead340bb196c6ba3f6978e8fb53966c74bf7 (diff) |
Merge TP1A.220120.003
Change-Id: Ie5eba313ee102e452f5f96942ed2f3a7bb4e8f01
Diffstat (limited to 'sensors/aidl')
21 files changed, 1575 insertions, 3 deletions
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp index fd1ac441e2..92b7ad03d8 100644 --- a/sensors/aidl/Android.bp +++ b/sensors/aidl/Android.bp @@ -1,4 +1,11 @@ -// This is the expected build file, but it may not be right in all cases +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} aidl_interface { name: "android.hardware.sensors", diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl index 186b2be8b3..c92ab1ab0c 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl @@ -51,6 +51,7 @@ parcelable Event { android.hardware.sensors.DynamicSensorInfo dynamic; android.hardware.sensors.AdditionalInfo additional; android.hardware.sensors.Event.EventPayload.Data data; + android.hardware.sensors.Event.EventPayload.HeadTracker headTracker; @FixedSize @VintfStability parcelable Vec4 { float x; @@ -75,6 +76,16 @@ parcelable Event { float zBias; } @FixedSize @VintfStability + parcelable HeadTracker { + float rx; + float ry; + float rz; + float vx; + float vy; + float vz; + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { float bpm; android.hardware.sensors.SensorStatus status; diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl index 4f3b5b2e79..3d7ab45cd8 100644 --- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl @@ -70,5 +70,6 @@ enum SensorType { LOW_LATENCY_OFFBODY_DETECT = 34, ACCELEROMETER_UNCALIBRATED = 35, HINGE_ANGLE = 36, + HEAD_TRACKER = 37, DEVICE_PRIVATE_BASE = 65536, } diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl index 6ef9acbbda..fd6a8cc4ba 100644 --- a/sensors/aidl/android/hardware/sensors/Event.aidl +++ b/sensors/aidl/android/hardware/sensors/Event.aidl @@ -127,6 +127,11 @@ parcelable Event { */ Data data; + /** + * SensorType::HEAD_TRACKER + */ + HeadTracker headTracker; + @FixedSize @VintfStability parcelable Vec4 { @@ -156,6 +161,46 @@ parcelable Event { float zBias; } + /** + * Payload of the HEAD_TRACKER sensor type. Note that the axis + * definition of this sensor type differs from the rest of Android. See + * SensorType::HEAD_TRACKER for more information. + */ + @FixedSize + @VintfStability + parcelable HeadTracker { + /** + * An Euler vector (rotation vector, i.e. a vector whose direction + * indicates the axis of rotation and magnitude indicates the angle + * to rotate around that axis) representing the transform from + * the (arbitrary, possibly slowly drifting) reference frame to the + * head frame. Expressed in radians. Magnitude of the vector must be + * in the range [0, pi], while the value of individual axes are + * in the range [-pi, pi]. + */ + float rx; + float ry; + float rz; + + /** + * An Euler vector (rotation vector) representing the angular + * velocity of the head (relative to itself), in radians per second. + * The direction of this vector indicates the axis of rotation, and + * the magnitude indicates the rate of rotation. + */ + float vx; + float vy; + float vz; + + /** + * This value increments (or wraps around to 0) each time the + * reference frame is suddenly and significantly changed, for + * example if an orientation filter algorithm used for determining + * the orientation has had its state reset. + */ + int discontinuityCount; + } + @FixedSize @VintfStability parcelable HeartRate { diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl index 95c7a6a2ad..01e6bee1d5 100644 --- a/sensors/aidl/android/hardware/sensors/SensorType.aidl +++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl @@ -142,6 +142,10 @@ enum SensorType { * The rotation vector symbolizes the orientation of the device relative to * the East-North-Up coordinates frame. * + * Note that despite the name, SensorType::ROTATION_VECTOR uses + * quaternion representation, rather than the rotation vector representation + * (aka Euler vector) seen in SensorType::HEAD_TRACKER. + * * Implement the non-wake-up version of this sensor and implement the * wake-up version if the system possesses a wake up fifo. */ @@ -634,6 +638,35 @@ enum SensorType { HINGE_ANGLE = 36, /** + * HEAD_TRACKER + * reporting-mode: continuous + * + * A sensor of this type measures the orientation of a user's head relative + * to an arbitrary reference frame, and the rate of rotation. + * + * Events produced by this sensor follow a special head-centric coordinate + * frame, where: + * - The X axis crosses through the user's ears, with the positive X + * direction extending out of the user's right ear + * - The Y axis crosses from the back of the user's head through their + * nose, with the positive direction extending out of the nose, and the + * X/Y plane being nominally parallel to the ground when the user is + * upright and looking straight ahead + * - The Z axis crosses from the neck through the top of the user's head, + * with the positive direction extending out from the top of the head + * + * When this sensor type is exposed as a dynamic sensor through a + * communications channel that uses HID, such as Bluetooth or USB, as part + * of a device with audio output capability (e.g. headphones), then the + * DynamicSensorInfo::uuid field shall be set to contents of the HID + * Persistent Unique ID to permit association between the sensor and audio + * device. Accordingly, the HID Persistent Unique ID (Sensors Page 0x20, + * Usage ID 0x302) must be populated as a UUID in binary representation, + * following RFC 4122 byte order. + */ + HEAD_TRACKER = 37, + + /** * Base for device manufacturers private sensor types. * These sensor types can't be exposed in the SDK. */ diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp new file mode 100644 index 0000000000..eee10625bb --- /dev/null +++ b/sensors/aidl/default/multihal/Android.bp @@ -0,0 +1,58 @@ +// +// 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. +// + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_library_static { + name: "android.hardware.sensors@aidl-multihal", + vendor: true, + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + shared_libs: [ + "libfmq", + "libpower", + "libbase", + "libbinder_ndk", + "android.hardware.sensors@1.0", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + ], + export_include_dirs: ["include"], + srcs: [ + "HalProxyAidl.cpp", + "ConvertUtils.cpp", + ], + visibility: [ + ":__subpackages__", + "//hardware/interfaces/sensors/aidl/multihal:__subpackages__", + "//hardware/interfaces/tests/extension/sensors:__subpackages__", + ], + static_libs: [ + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "libaidlcommonsupport", + ], +} diff --git a/sensors/aidl/default/multihal/ConvertUtils.cpp b/sensors/aidl/default/multihal/ConvertUtils.cpp new file mode 100644 index 0000000000..509bbb0e7b --- /dev/null +++ b/sensors/aidl/default/multihal/ConvertUtils.cpp @@ -0,0 +1,321 @@ +/* + * 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 "ConvertUtils.h" +#include <android-base/logging.h> +#include <log/log.h> + +using AidlSensorInfo = ::aidl::android::hardware::sensors::SensorInfo; +using AidlSensorType = ::aidl::android::hardware::sensors::SensorType; +using AidlEvent = ::aidl::android::hardware::sensors::Event; +using AidlSensorStatus = ::aidl::android::hardware::sensors::SensorStatus; +using ::aidl::android::hardware::sensors::AdditionalInfo; +using ::aidl::android::hardware::sensors::DynamicSensorInfo; +using ::android::hardware::sensors::V1_0::MetaDataEventType; +using V1_0SensorStatus = ::android::hardware::sensors::V1_0::SensorStatus; +using ::android::hardware::sensors::V1_0::AdditionalInfoType; +using V2_1SensorInfo = ::android::hardware::sensors::V2_1::SensorInfo; +using V2_1Event = ::android::hardware::sensors::V2_1::Event; +using V2_1SensorType = ::android::hardware::sensors::V2_1::SensorType; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +AidlSensorInfo convertSensorInfo(const V2_1SensorInfo& sensorInfo) { + AidlSensorInfo aidlSensorInfo; + aidlSensorInfo.sensorHandle = sensorInfo.sensorHandle; + aidlSensorInfo.name = sensorInfo.name; + aidlSensorInfo.vendor = sensorInfo.vendor; + aidlSensorInfo.version = sensorInfo.version; + aidlSensorInfo.type = (AidlSensorType)sensorInfo.type; + aidlSensorInfo.typeAsString = sensorInfo.typeAsString; + aidlSensorInfo.maxRange = sensorInfo.maxRange; + aidlSensorInfo.resolution = sensorInfo.resolution; + aidlSensorInfo.power = sensorInfo.power; + aidlSensorInfo.minDelayUs = sensorInfo.minDelay; + aidlSensorInfo.fifoReservedEventCount = sensorInfo.fifoReservedEventCount; + aidlSensorInfo.fifoMaxEventCount = sensorInfo.fifoMaxEventCount; + aidlSensorInfo.requiredPermission = sensorInfo.requiredPermission; + aidlSensorInfo.maxDelayUs = sensorInfo.maxDelay; + aidlSensorInfo.flags = sensorInfo.flags; + return aidlSensorInfo; +} + +void convertToHidlEvent(const AidlEvent& aidlEvent, V2_1Event* hidlEvent) { + hidlEvent->timestamp = aidlEvent.timestamp; + hidlEvent->sensorHandle = aidlEvent.sensorHandle; + hidlEvent->sensorType = (V2_1SensorType)aidlEvent.sensorType; + + switch (aidlEvent.sensorType) { + case AidlSensorType::META_DATA: + hidlEvent->u.meta.what = + (MetaDataEventType)aidlEvent.payload.get<Event::EventPayload::meta>().what; + break; + case AidlSensorType::ACCELEROMETER: + case AidlSensorType::MAGNETIC_FIELD: + case AidlSensorType::ORIENTATION: + case AidlSensorType::GYROSCOPE: + case AidlSensorType::GRAVITY: + case AidlSensorType::LINEAR_ACCELERATION: + hidlEvent->u.vec3.x = aidlEvent.payload.get<Event::EventPayload::vec3>().x; + hidlEvent->u.vec3.y = aidlEvent.payload.get<Event::EventPayload::vec3>().y; + hidlEvent->u.vec3.z = aidlEvent.payload.get<Event::EventPayload::vec3>().z; + break; + case AidlSensorType::GAME_ROTATION_VECTOR: + hidlEvent->u.vec4.x = aidlEvent.payload.get<Event::EventPayload::vec4>().x; + hidlEvent->u.vec4.y = aidlEvent.payload.get<Event::EventPayload::vec4>().y; + hidlEvent->u.vec4.z = aidlEvent.payload.get<Event::EventPayload::vec4>().z; + hidlEvent->u.vec4.w = aidlEvent.payload.get<Event::EventPayload::vec4>().w; + break; + case AidlSensorType::ROTATION_VECTOR: + case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR: + std::copy(aidlEvent.payload.get<Event::EventPayload::data>().values.data(), + aidlEvent.payload.get<Event::EventPayload::data>().values.data() + 5, + hidlEvent->u.data.data()); + break; + case AidlSensorType::ACCELEROMETER_UNCALIBRATED: + case AidlSensorType::MAGNETIC_FIELD_UNCALIBRATED: + case AidlSensorType::GYROSCOPE_UNCALIBRATED: + hidlEvent->u.uncal.x = aidlEvent.payload.get<Event::EventPayload::uncal>().x; + hidlEvent->u.uncal.y = aidlEvent.payload.get<Event::EventPayload::uncal>().y; + hidlEvent->u.uncal.z = aidlEvent.payload.get<Event::EventPayload::uncal>().z; + hidlEvent->u.uncal.x_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().xBias; + hidlEvent->u.uncal.y_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().yBias; + hidlEvent->u.uncal.z_bias = aidlEvent.payload.get<Event::EventPayload::uncal>().zBias; + break; + case AidlSensorType::DEVICE_ORIENTATION: + case AidlSensorType::LIGHT: + case AidlSensorType::PRESSURE: + case AidlSensorType::PROXIMITY: + case AidlSensorType::RELATIVE_HUMIDITY: + case AidlSensorType::AMBIENT_TEMPERATURE: + case AidlSensorType::SIGNIFICANT_MOTION: + case AidlSensorType::STEP_DETECTOR: + case AidlSensorType::TILT_DETECTOR: + case AidlSensorType::WAKE_GESTURE: + case AidlSensorType::GLANCE_GESTURE: + case AidlSensorType::PICK_UP_GESTURE: + case AidlSensorType::WRIST_TILT_GESTURE: + case AidlSensorType::STATIONARY_DETECT: + case AidlSensorType::MOTION_DETECT: + case AidlSensorType::HEART_BEAT: + case AidlSensorType::LOW_LATENCY_OFFBODY_DETECT: + case AidlSensorType::HINGE_ANGLE: + hidlEvent->u.scalar = aidlEvent.payload.get<Event::EventPayload::scalar>(); + break; + case AidlSensorType::STEP_COUNTER: + hidlEvent->u.stepCount = aidlEvent.payload.get<AidlEvent::EventPayload::stepCount>(); + break; + case AidlSensorType::HEART_RATE: + hidlEvent->u.heartRate.bpm = + aidlEvent.payload.get<AidlEvent::EventPayload::heartRate>().bpm; + hidlEvent->u.heartRate.status = + (V1_0SensorStatus)aidlEvent.payload.get<Event::EventPayload::heartRate>() + .status; + break; + case AidlSensorType::POSE_6DOF: + std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::pose6DOF>().values), + hidlEvent->u.pose6DOF.data()); + break; + case AidlSensorType::DYNAMIC_SENSOR_META: + hidlEvent->u.dynamic.connected = + aidlEvent.payload.get<Event::EventPayload::dynamic>().connected; + hidlEvent->u.dynamic.sensorHandle = + aidlEvent.payload.get<Event::EventPayload::dynamic>().sensorHandle; + std::copy( + std::begin( + aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::dynamic>().uuid.values), + hidlEvent->u.dynamic.uuid.data()); + break; + case AidlSensorType::ADDITIONAL_INFO: { + const AdditionalInfo& additionalInfo = + aidlEvent.payload.get<AidlEvent::EventPayload::additional>(); + hidlEvent->u.additional.type = (AdditionalInfoType)additionalInfo.type; + hidlEvent->u.additional.serial = additionalInfo.serial; + + switch (additionalInfo.payload.getTag()) { + case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: { + const auto& aidlData = + additionalInfo.payload + .get<AdditionalInfo::AdditionalInfoPayload::dataInt32>() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_int32.data()); + break; + } + case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: { + const auto& aidlData = + additionalInfo.payload + .get<AdditionalInfo::AdditionalInfoPayload::dataFloat>() + .values; + std::copy(std::begin(aidlData), std::end(aidlData), + hidlEvent->u.additional.u.data_float.data()); + break; + } + default: + ALOGE("Invalid sensor additioanl info tag: %d", + additionalInfo.payload.getTag()); + break; + } + break; + } + default: + CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + std::copy(std::begin(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), + std::end(aidlEvent.payload.get<AidlEvent::EventPayload::data>().values), + hidlEvent->u.data.data()); + break; + } +} + +void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { + aidlEvent->timestamp = hidlEvent.timestamp; + aidlEvent->sensorHandle = hidlEvent.sensorHandle; + aidlEvent->sensorType = (AidlSensorType)hidlEvent.sensorType; + switch (hidlEvent.sensorType) { + case V2_1SensorType::META_DATA: { + AidlEvent::EventPayload::MetaData meta; + meta.what = (Event::EventPayload::MetaData::MetaDataEventType)hidlEvent.u.meta.what; + aidlEvent->payload.set<Event::EventPayload::meta>(meta); + break; + } + case V2_1SensorType::ACCELEROMETER: + case V2_1SensorType::MAGNETIC_FIELD: + case V2_1SensorType::ORIENTATION: + case V2_1SensorType::GYROSCOPE: + case V2_1SensorType::GRAVITY: + case V2_1SensorType::LINEAR_ACCELERATION: { + AidlEvent::EventPayload::Vec3 vec3; + vec3.x = hidlEvent.u.vec3.x; + vec3.y = hidlEvent.u.vec3.y; + vec3.z = hidlEvent.u.vec3.z; + aidlEvent->payload.set<Event::EventPayload::vec3>(vec3); + break; + } + case V2_1SensorType::GAME_ROTATION_VECTOR: { + AidlEvent::EventPayload::Vec4 vec4; + vec4.x = hidlEvent.u.vec4.x; + vec4.y = hidlEvent.u.vec4.y; + vec4.z = hidlEvent.u.vec4.z; + vec4.w = hidlEvent.u.vec4.w; + aidlEvent->payload.set<Event::EventPayload::vec4>(vec4); + break; + } + case V2_1SensorType::ROTATION_VECTOR: + case V2_1SensorType::GEOMAGNETIC_ROTATION_VECTOR: { + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + 5, + std::begin(data.values)); + aidlEvent->payload.set<Event::EventPayload::data>(data); + break; + } + case V2_1SensorType::MAGNETIC_FIELD_UNCALIBRATED: + case V2_1SensorType::GYROSCOPE_UNCALIBRATED: + case V2_1SensorType::ACCELEROMETER_UNCALIBRATED: { + AidlEvent::EventPayload::Uncal uncal; + uncal.x = hidlEvent.u.uncal.x; + uncal.y = hidlEvent.u.uncal.y; + uncal.z = hidlEvent.u.uncal.z; + uncal.xBias = hidlEvent.u.uncal.x_bias; + uncal.yBias = hidlEvent.u.uncal.y_bias; + uncal.zBias = hidlEvent.u.uncal.z_bias; + aidlEvent->payload.set<Event::EventPayload::uncal>(uncal); + break; + } + case V2_1SensorType::DEVICE_ORIENTATION: + case V2_1SensorType::LIGHT: + case V2_1SensorType::PRESSURE: + case V2_1SensorType::PROXIMITY: + case V2_1SensorType::RELATIVE_HUMIDITY: + case V2_1SensorType::AMBIENT_TEMPERATURE: + case V2_1SensorType::SIGNIFICANT_MOTION: + case V2_1SensorType::STEP_DETECTOR: + case V2_1SensorType::TILT_DETECTOR: + case V2_1SensorType::WAKE_GESTURE: + case V2_1SensorType::GLANCE_GESTURE: + case V2_1SensorType::PICK_UP_GESTURE: + case V2_1SensorType::WRIST_TILT_GESTURE: + case V2_1SensorType::STATIONARY_DETECT: + case V2_1SensorType::MOTION_DETECT: + case V2_1SensorType::HEART_BEAT: + case V2_1SensorType::LOW_LATENCY_OFFBODY_DETECT: + case V2_1SensorType::HINGE_ANGLE: + aidlEvent->payload.set<Event::EventPayload::scalar>(hidlEvent.u.scalar); + break; + case V2_1SensorType::STEP_COUNTER: + aidlEvent->payload.set<Event::EventPayload::stepCount>(hidlEvent.u.stepCount); + break; + case V2_1SensorType::HEART_RATE: { + AidlEvent::EventPayload::HeartRate heartRate; + heartRate.bpm = hidlEvent.u.heartRate.bpm; + heartRate.status = (SensorStatus)hidlEvent.u.heartRate.status; + aidlEvent->payload.set<Event::EventPayload::heartRate>(heartRate); + break; + } + case V2_1SensorType::POSE_6DOF: { + AidlEvent::EventPayload::Pose6Dof pose6Dof; + std::copy(hidlEvent.u.pose6DOF.data(), + hidlEvent.u.pose6DOF.data() + hidlEvent.u.pose6DOF.size(), + std::begin(pose6Dof.values)); + aidlEvent->payload.set<Event::EventPayload::pose6DOF>(pose6Dof); + break; + } + case V2_1SensorType::DYNAMIC_SENSOR_META: { + DynamicSensorInfo dynamicSensorInfo; + dynamicSensorInfo.connected = hidlEvent.u.dynamic.connected; + dynamicSensorInfo.sensorHandle = hidlEvent.u.dynamic.sensorHandle; + std::copy(hidlEvent.u.dynamic.uuid.data(), + hidlEvent.u.dynamic.uuid.data() + hidlEvent.u.dynamic.uuid.size(), + std::begin(dynamicSensorInfo.uuid.values)); + aidlEvent->payload.set<Event::EventPayload::dynamic>(dynamicSensorInfo); + break; + } + case V2_1SensorType::ADDITIONAL_INFO: { + AdditionalInfo additionalInfo; + additionalInfo.type = (AdditionalInfo::AdditionalInfoType)hidlEvent.u.additional.type; + additionalInfo.serial = hidlEvent.u.additional.serial; + + AdditionalInfo::AdditionalInfoPayload::Int32Values int32Values; + std::copy(hidlEvent.u.additional.u.data_int32.data(), + hidlEvent.u.additional.u.data_int32.data() + + hidlEvent.u.additional.u.data_int32.size(), + std::begin(int32Values.values)); + additionalInfo.payload.set<AdditionalInfo::AdditionalInfoPayload::dataInt32>( + int32Values); + aidlEvent->payload.set<Event::EventPayload::additional>(additionalInfo); + break; + } + default: { + CHECK_GE((int32_t)hidlEvent.sensorType, (int32_t)V2_1SensorType::DEVICE_PRIVATE_BASE); + AidlEvent::EventPayload::Data data; + std::copy(hidlEvent.u.data.data(), hidlEvent.u.data.data() + hidlEvent.u.data.size(), + std::begin(data.values)); + aidlEvent->payload.set<Event::EventPayload::data>(data); + break; + } + } +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/HalProxyAidl.cpp b/sensors/aidl/default/multihal/HalProxyAidl.cpp new file mode 100644 index 0000000000..64805e6638 --- /dev/null +++ b/sensors/aidl/default/multihal/HalProxyAidl.cpp @@ -0,0 +1,213 @@ +/* + * 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 "HalProxyAidl.h" +#include <aidlcommonsupport/NativeHandle.h> +#include <fmq/AidlMessageQueue.h> +#include <hidl/Status.h> +#include "ConvertUtils.h" +#include "EventMessageQueueWrapperAidl.h" +#include "ISensorsCallbackWrapperAidl.h" +#include "WakeLockMessageQueueWrapperAidl.h" +#include "convertV2_1.h" + +using ::aidl::android::hardware::common::fmq::MQDescriptor; +using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::ISensorsCallback; +using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static binder_status_t resultToBinderStatus(::android::hardware::sensors::V1_0::Result result) { + switch (result) { + case ::android::hardware::sensors::V1_0::Result::OK: + return STATUS_OK; + case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED: + return STATUS_PERMISSION_DENIED; + case ::android::hardware::sensors::V1_0::Result::NO_MEMORY: + return STATUS_NO_MEMORY; + case ::android::hardware::sensors::V1_0::Result::BAD_VALUE: + return STATUS_BAD_VALUE; + case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION: + return STATUS_INVALID_OPERATION; + } +} + +static ::android::hardware::sensors::V1_0::RateLevel convertRateLevel( + ISensors::RateLevel rateLevel) { + switch (rateLevel) { + case ISensors::RateLevel::STOP: + return ::android::hardware::sensors::V1_0::RateLevel::STOP; + case ISensors::RateLevel::NORMAL: + return ::android::hardware::sensors::V1_0::RateLevel::NORMAL; + case ISensors::RateLevel::FAST: + return ::android::hardware::sensors::V1_0::RateLevel::FAST; + case ISensors::RateLevel::VERY_FAST: + return ::android::hardware::sensors::V1_0::RateLevel::VERY_FAST; + } +} + +static ::android::hardware::sensors::V1_0::OperationMode convertOperationMode( + ISensors::OperationMode operationMode) { + switch (operationMode) { + case ISensors::OperationMode::NORMAL: + return ::android::hardware::sensors::V1_0::OperationMode::NORMAL; + case ISensors::OperationMode::DATA_INJECTION: + return ::android::hardware::sensors::V1_0::OperationMode::DATA_INJECTION; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemType convertSharedMemType( + ISensors::SharedMemInfo::SharedMemType sharedMemType) { + switch (sharedMemType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return ::android::hardware::sensors::V1_0::SharedMemType::ASHMEM; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return ::android::hardware::sensors::V1_0::SharedMemType::GRALLOC; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemFormat convertSharedMemFormat( + ISensors::SharedMemInfo::SharedMemFormat sharedMemFormat) { + switch (sharedMemFormat) { + case ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT: + return ::android::hardware::sensors::V1_0::SharedMemFormat::SENSORS_EVENT; + } +} + +static ::android::hardware::sensors::V1_0::SharedMemInfo convertSharedMemInfo( + const ISensors::SharedMemInfo& sharedMemInfo) { + ::android::hardware::sensors::V1_0::SharedMemInfo v1SharedMemInfo; + v1SharedMemInfo.type = convertSharedMemType(sharedMemInfo.type); + v1SharedMemInfo.format = convertSharedMemFormat(sharedMemInfo.format); + v1SharedMemInfo.size = sharedMemInfo.size; + v1SharedMemInfo.memoryHandle = + ::android::hardware::hidl_handle(::android::makeFromAidl(sharedMemInfo.memoryHandle)); + return v1SharedMemInfo; +} + +::ndk::ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::activate(in_sensorHandle, in_enabled))); +} + +::ndk::ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus( + HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, in_maxReportLatencyNs))); +} + +::ndk::ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle, + int32_t in_channelHandle, + ISensors::RateLevel in_rate, + int32_t* _aidl_return) { + binder_status_t binderStatus; + HalProxy::configDirectReport( + in_sensorHandle, in_channelHandle, convertRateLevel(in_rate), + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) { + return ndk::ScopedAStatus::fromStatus(resultToBinderStatus(HalProxy::flush(in_sensorHandle))); +} + +::ndk::ScopedAStatus HalProxyAidl::getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) { + for (const auto& sensor : HalProxy::getSensors()) { + _aidl_return->push_back(convertSensorInfo(sensor.second)); + } + return ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus HalProxyAidl::initialize( + const MQDescriptor<::aidl::android::hardware::sensors::Event, SynchronizedReadWrite>& + in_eventQueueDescriptor, + const MQDescriptor<int32_t, SynchronizedReadWrite>& in_wakeLockDescriptor, + const std::shared_ptr<ISensorsCallback>& in_sensorsCallback) { + ::android::sp<::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase> + dynamicCallback = new ISensorsCallbackWrapperAidl(in_sensorsCallback); + + auto aidlEventQueue = + std::make_unique<::android::AidlMessageQueue<::aidl::android::hardware::sensors::Event, + SynchronizedReadWrite>>( + in_eventQueueDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase> + eventQueue = std::make_unique<EventMessageQueueWrapperAidl>(aidlEventQueue); + + auto aidlWakeLockQueue = + std::make_unique<::android::AidlMessageQueue<int32_t, SynchronizedReadWrite>>( + in_wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr< + ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase> + wakeLockQueue = std::make_unique<WakeLockMessageQueueWrapperAidl>(aidlWakeLockQueue); + + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(initializeCommon(eventQueue, wakeLockQueue, dynamicCallback))); +} + +::ndk::ScopedAStatus HalProxyAidl::injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) { + ::android::hardware::sensors::V2_1::Event hidlEvent; + convertToHidlEvent(in_event, &hidlEvent); + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::injectSensorData(convertToOldEvent(hidlEvent)))); +} + +::ndk::ScopedAStatus HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) { + binder_status_t binderStatus; + ::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = convertSharedMemInfo(in_mem); + + HalProxy::registerDirectChannel( + sharedMemInfo, + [&binderStatus, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + binderStatus = resultToBinderStatus(result); + *_aidl_return = reportToken; + }); + + native_handle_delete( + const_cast<native_handle_t*>(sharedMemInfo.memoryHandle.getNativeHandle())); + return ndk::ScopedAStatus::fromStatus(binderStatus); +} + +::ndk::ScopedAStatus HalProxyAidl::setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::setOperationMode(convertOperationMode(in_mode)))); +} + +::ndk::ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) { + return ndk::ScopedAStatus::fromStatus( + resultToBinderStatus(HalProxy::unregisterDirectChannel(in_channelHandle))); +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/ConvertUtils.h b/sensors/aidl/default/multihal/include/ConvertUtils.h new file mode 100644 index 0000000000..91dfabde3a --- /dev/null +++ b/sensors/aidl/default/multihal/include/ConvertUtils.h @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#pragma once + +#include <aidl/android/hardware/sensors/BnSensors.h> +#include <android/hardware/sensors/2.1/types.h> + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +/** + * Generates an AIDL SensorInfo instance from the passed HIDL V2.1 SensorInfo instance. + */ +::aidl::android::hardware::sensors::SensorInfo convertSensorInfo( + const ::android::hardware::sensors::V2_1::SensorInfo& sensorInfo); + +/** + * Populates a HIDL V2.1 Event instance based on an AIDL Event instance. + */ +void convertToHidlEvent(const ::aidl::android::hardware::sensors::Event& aidlEvent, + ::android::hardware::sensors::V2_1::Event* hidlEvent); + +/** + * Populates an AIDL Event instance based on a HIDL V2.1 Event instance. + */ +void convertToAidlEvent(const ::android::hardware::sensors::V2_1::Event& hidlEvent, + ::aidl::android::hardware::sensors::Event* aidlEvent); + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..3eaa1d4335 --- /dev/null +++ b/sensors/aidl/default/multihal/include/EventMessageQueueWrapperAidl.h @@ -0,0 +1,99 @@ +/* + * 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. + */ + +#pragma once + +#include <android/hardware/sensors/2.1/types.h> +#include <fmq/AidlMessageQueue.h> +#include "ConvertUtils.h" +#include "EventMessageQueueWrapper.h" +#include "ISensorsWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class EventMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::EventMessageQueueWrapperBase { + public: + EventMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic<uint32_t>* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + virtual size_t availableToRead() override { return mQueue->availableToRead(); } + + size_t availableToWrite() override { return mQueue->availableToWrite(); } + + virtual bool read(::android::hardware::sensors::V2_1::Event* events, + size_t numToRead) override { + bool success = mQueue->read(mIntermediateEventBuffer.data(), numToRead); + for (int i = 0; i < numToRead; ++i) { + convertToHidlEvent(mIntermediateEventBuffer[i], &events[i]); + } + return success; + } + + bool write(const ::android::hardware::sensors::V2_1::Event* events, + size_t numToWrite) override { + for (int i = 0; i < numToWrite; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), numToWrite); + } + + virtual bool write( + const std::vector<::android::hardware::sensors::V2_1::Event>& events) override { + for (int i = 0; i < events.size(); ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->write(mIntermediateEventBuffer.data(), events.size()); + } + + bool writeBlocking(const ::android::hardware::sensors::V2_1::Event* events, size_t count, + uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + for (int i = 0; i < count; ++i) { + convertToAidlEvent(events[i], &mIntermediateEventBuffer[i]); + } + return mQueue->writeBlocking(mIntermediateEventBuffer.data(), count, readNotification, + writeNotification, timeOutNanos, evFlag); + } + + size_t getQuantumCount() override { return mQueue->getQuantumCount(); } + + private: + std::unique_ptr<::android::AidlMessageQueue< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; + std::array<::aidl::android::hardware::sensors::Event, + ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT> + mIntermediateEventBuffer; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/HalProxyAidl.h b/sensors/aidl/default/multihal/include/HalProxyAidl.h new file mode 100644 index 0000000000..7401726cf9 --- /dev/null +++ b/sensors/aidl/default/multihal/include/HalProxyAidl.h @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#pragma once + +#include <aidl/android/hardware/sensors/BnSensors.h> +#include "HalProxy.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class HalProxyAidl : public ::android::hardware::sensors::V2_1::implementation::HalProxy, + public ::aidl::android::hardware::sensors::BnSensors { + ::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override; + ::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) override; + ::ndk::ScopedAStatus configDirectReport( + int32_t in_sensorHandle, int32_t in_channelHandle, + ::aidl::android::hardware::sensors::ISensors::RateLevel in_rate, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override; + ::ndk::ScopedAStatus getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override; + ::ndk::ScopedAStatus initialize( + const ::aidl::android::hardware::common::fmq::MQDescriptor< + ::aidl::android::hardware::sensors::Event, + ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_eventQueueDescriptor, + const ::aidl::android::hardware::common::fmq::MQDescriptor< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>& + in_wakeLockDescriptor, + const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>& + in_sensorsCallback) override; + ::ndk::ScopedAStatus injectSensorData( + const ::aidl::android::hardware::sensors::Event& in_event) override; + ::ndk::ScopedAStatus registerDirectChannel( + const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem, + int32_t* _aidl_return) override; + ::ndk::ScopedAStatus setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override; + ::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h new file mode 100644 index 0000000000..6ef6c6398d --- /dev/null +++ b/sensors/aidl/default/multihal/include/ISensorsCallbackWrapperAidl.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#pragma once + +#include "ConvertUtils.h" +#include "ISensorsCallbackWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static std::vector<::aidl::android::hardware::sensors::SensorInfo> convertToAidlSensorInfos( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) { + std::vector<::aidl::android::hardware::sensors::SensorInfo> aidlSensorInfos; + for (const auto& sensorInfo : sensorInfos) { + aidlSensorInfos.push_back(convertSensorInfo(sensorInfo)); + } + return aidlSensorInfos; +} + +class ISensorsCallbackWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::ISensorsCallbackWrapperBase { + public: + ISensorsCallbackWrapperAidl( + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> sensorsCallback) + : mSensorsCallback(sensorsCallback) {} + + ::android::hardware::Return<void> onDynamicSensorsConnected( + const ::android::hardware::hidl_vec<::android::hardware::sensors::V2_1::SensorInfo>& + sensorInfos) override { + mSensorsCallback->onDynamicSensorsConnected(convertToAidlSensorInfos(sensorInfos)); + return ::android::hardware::Void(); + } + + ::android::hardware::Return<void> onDynamicSensorsDisconnected( + const ::android::hardware::hidl_vec<int32_t>& sensorHandles) override { + mSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); + return ::android::hardware::Void(); + } + + private: + std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mSensorsCallback; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl
\ No newline at end of file diff --git a/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h new file mode 100644 index 0000000000..6be0b69aa3 --- /dev/null +++ b/sensors/aidl/default/multihal/include/WakeLockMessageQueueWrapperAidl.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#pragma once + +#include <android/hardware/sensors/2.1/types.h> +#include <fmq/AidlMessageQueue.h> +#include "WakeLockMessageQueueWrapper.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +class WakeLockMessageQueueWrapperAidl + : public ::android::hardware::sensors::V2_1::implementation::WakeLockMessageQueueWrapperBase { + public: + WakeLockMessageQueueWrapperAidl( + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>>& queue) + : mQueue(std::move(queue)) {} + + virtual std::atomic<uint32_t>* getEventFlagWord() override { + return mQueue->getEventFlagWord(); + } + + bool readBlocking(uint32_t* wakeLocks, size_t numToRead, uint32_t readNotification, + uint32_t writeNotification, int64_t timeOutNanos, + ::android::hardware::EventFlag* evFlag) override { + return mQueue->readBlocking(reinterpret_cast<int32_t*>(wakeLocks), numToRead, + readNotification, writeNotification, timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { + return mQueue->write(reinterpret_cast<const int32_t*>(wakeLock)); + } + + private: + std::unique_ptr<::android::AidlMessageQueue< + int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>> + mQueue; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp new file mode 100644 index 0000000000..6d35dafd6d --- /dev/null +++ b/sensors/aidl/multihal/Android.bp @@ -0,0 +1,59 @@ +// +// 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. +// + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_binary { + name: "android.hardware.sensors-service.multihal", + vendor: true, + relative_install_path: "hw", + srcs: [ + "service.cpp", + ], + header_libs: [ + "android.hardware.sensors@2.X-multihal.header", + "android.hardware.sensors@2.X-shared-utils", + ], + init_rc: ["android.hardware.sensors-service-multihal.rc"], + vintf_fragments: ["android.hardware.sensors-multihal.xml"], + shared_libs: [ + "android.hardware.sensors@2.0-ScopedWakelock", + "android.hardware.sensors@2.0", + "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", + "libbase", + "libcutils", + "libfmq", + "liblog", + "libpower", + "libutils", + "libbinder_ndk", + "libhidlbase", + ], + static_libs: [ + "libaidlcommonsupport", + "android.hardware.sensors@1.0-convert", + "android.hardware.sensors@2.X-multihal", + "android.hardware.sensors@aidl-multihal", + ], +} diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS new file mode 100644 index 0000000000..e9556700d6 --- /dev/null +++ b/sensors/aidl/multihal/OWNERS @@ -0,0 +1,3 @@ +arthuri@google.com +bduddie@google.com +stange@google.com
\ No newline at end of file diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml new file mode 100644 index 0000000000..d78edffaf9 --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml @@ -0,0 +1,23 @@ +<!-- + ~ 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. + --> + +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.sensors</name> + <version>1</version> + <fqname>ISensors/default</fqname> + </hal> +</manifest> diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc new file mode 100644 index 0000000000..3f91a0a04a --- /dev/null +++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal + class hal + user system + group system wakelock context_hub + task_profiles ServiceCapacityLow + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10
\ No newline at end of file diff --git a/sensors/aidl/multihal/service.cpp b/sensors/aidl/multihal/service.cpp new file mode 100644 index 0000000000..11c108a395 --- /dev/null +++ b/sensors/aidl/multihal/service.cpp @@ -0,0 +1,36 @@ +/* + * 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 <android-base/logging.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> +#include "HalProxyAidl.h" + +using ::aidl::android::hardware::sensors::implementation::HalProxyAidl; + +int main() { + ABinderProcess_setThreadPoolMaxThreadCount(0); + + // Make a default multihal sensors service + auto halProxy = ndk::SharedRefBase::make<HalProxyAidl>(); + const std::string halProxyName = std::string() + HalProxyAidl::descriptor + "/default"; + binder_status_t status = + AServiceManager_addService(halProxy->asBinder().get(), halProxyName.c_str()); + CHECK_EQ(status, STATUS_OK); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp index 5a519a5a1e..b5a5f15691 100644 --- a/sensors/aidl/vts/Android.bp +++ b/sensors/aidl/vts/Android.bp @@ -34,6 +34,7 @@ cc_test { shared_libs: [ "libbinder", "libbinder_ndk", + "libvndksupport", "libfmq", "android.hardware.common-V2-ndk", "android.hardware.common.fmq-V1-ndk", @@ -41,6 +42,7 @@ cc_test { static_libs: [ "android.hardware.sensors-V1-ndk", "VtsHalSensorsTargetTestUtils", + "libaidlcommonsupport", ], test_suites: [ "general-tests", diff --git a/sensors/aidl/vts/SensorsAidlTestSharedMemory.h b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h new file mode 100644 index 0000000000..4b5916a0d7 --- /dev/null +++ b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2022 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_SENSORS_AIDL_TEST_SHARED_MEMORY_H +#define ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H + +#include "sensors-vts-utils/GrallocWrapper.h" + +#include <aidlcommonsupport/NativeHandle.h> +#include <android-base/macros.h> +#include <log/log.h> + +#include <sys/mman.h> +#include <cinttypes> + +#include <cutils/ashmem.h> + +using ::aidl::android::hardware::sensors::BnSensors; +using ::aidl::android::hardware::sensors::Event; +using ::aidl::android::hardware::sensors::ISensors; +using ::aidl::android::hardware::sensors::SensorType; + +template <class SensorType, class Event> +class SensorsAidlTestSharedMemory { + public: + static SensorsAidlTestSharedMemory* create(ISensors::SharedMemInfo::SharedMemType type, + size_t size) { + constexpr size_t kMaxSize = + 128 * 1024 * 1024; // sensor test should not need more than 128M + if (size == 0 || size >= kMaxSize) { + return nullptr; + } + + auto m = new SensorsAidlTestSharedMemory<SensorType, Event>(type, size); + if (m->mSize != size || m->mBuffer == nullptr) { + delete m; + m = nullptr; + } + return m; + } + + ISensors::SharedMemInfo getSharedMemInfo() const { + ISensors::SharedMemInfo mem = { + .type = mType, + .format = ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT, + .size = static_cast<int32_t>(mSize), + .memoryHandle = android::dupToAidl(mNativeHandle)}; + return mem; + } + char* getBuffer() const { return mBuffer; } + size_t getSize() const { return mSize; } + std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const { + constexpr size_t kEventSize = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + constexpr size_t kOffsetSize = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD); + constexpr size_t kOffsetToken = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN); + constexpr size_t kOffsetType = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE); + constexpr size_t kOffsetAtomicCounter = static_cast<size_t>( + BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER); + constexpr size_t kOffsetTimestamp = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP); + constexpr size_t kOffsetData = + static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA); + + std::vector<Event> events; + std::vector<float> data(16); + + while (offset + kEventSize <= mSize) { + int64_t atomicCounter = + *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter); + if (atomicCounter <= lastCounter) { + ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter, + lastCounter); + break; + } + + int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize); + if (size != kEventSize) { + // unknown error, events parsed may be wrong, remove all + events.clear(); + break; + } + + int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken); + int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType); + int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp); + + ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32 + ", timestamp %" PRId64, + offset, atomicCounter, token, type, timestamp); + + Event event = { + .timestamp = timestamp, + .sensorHandle = token, + .sensorType = type, + }; + + event.set<Event::Data>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); + // event.u.data = android::hardware::hidl_array<float, + // 16>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData)); + + events.push_back(event); + + lastCounter = atomicCounter; + offset += kEventSize; + } + + return events; + } + + virtual ~SensorsAidlTestSharedMemory() { + switch (mType) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + if (mSize != 0) { + ::munmap(mBuffer, mSize); + mBuffer = nullptr; + + ::native_handle_close(mNativeHandle); + ::native_handle_delete(mNativeHandle); + + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + if (mSize != 0) { + mGrallocWrapper->freeBuffer(mNativeHandle); + mNativeHandle = nullptr; + mSize = 0; + } + break; + } + default: { + if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) { + ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: " + "type %d, native handle %p, size %zu, buffer %p", + this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer); + } + break; + } + } + } + + private: + SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type, size_t size) + : mType(type), mSize(0), mBuffer(nullptr) { + native_handle_t* handle = nullptr; + char* buffer = nullptr; + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: { + int fd; + handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/); + if (handle != nullptr) { + handle->data[0] = fd = + ::ashmem_create_region("SensorsAidlTestSharedMemory", size); + if (handle->data[0] > 0) { + // memory is pinned by default + buffer = static_cast<char*>( + ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + if (buffer != reinterpret_cast<char*>(MAP_FAILED)) { + break; + } + ::native_handle_close(handle); + } + ::native_handle_delete(handle); + handle = nullptr; + } + break; + } + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: { + mGrallocWrapper = std::make_unique<::android::GrallocWrapper>(); + if (!mGrallocWrapper->isInitialized()) { + break; + } + + std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size); + handle = buf.first; + buffer = static_cast<char*>(buf.second); + break; + } + default: + break; + } + + if (buffer != nullptr) { + mNativeHandle = handle; + mSize = size; + mBuffer = buffer; + } + } + + ISensors::SharedMemInfo::SharedMemType mType; + native_handle_t* mNativeHandle; + size_t mSize; + char* mBuffer; + std::unique_ptr<::android::GrallocWrapper> mGrallocWrapper; + + DISALLOW_COPY_AND_ASSIGN(SensorsAidlTestSharedMemory); +}; + +#endif // ANDROID_SENSORS_TEST_SHARED_MEMORY_H diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp index 33645b2a95..1bc7263048 100644 --- a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp +++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp @@ -26,6 +26,7 @@ #include <utils/SystemClock.h> #include "SensorsAidlEnvironment.h" +#include "SensorsAidlTestSharedMemory.h" #include "sensors-vts-utils/SensorsVtsEnvironmentBase.h" #include <cinttypes> @@ -43,6 +44,9 @@ using aidl::android::hardware::sensors::SensorType; using android::ProcessState; using std::chrono::duration_cast; +constexpr size_t kEventSize = + static_cast<size_t>(ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH); + namespace { static void assertTypeMatchStringType(SensorType type, const std::string& stringType) { @@ -97,6 +101,24 @@ static void assertTypeMatchStringType(SensorType type, const std::string& string } } +bool isDirectChannelTypeSupported(SensorInfo sensor, ISensors::SharedMemInfo::SharedMemType type) { + switch (type) { + case ISensors::SharedMemInfo::SharedMemType::ASHMEM: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM) != 0; + case ISensors::SharedMemInfo::SharedMemType::GRALLOC: + return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC) != 0; + default: + return false; + } +} + +bool isDirectReportRateSupported(SensorInfo sensor, ISensors::RateLevel rate) { + unsigned int r = static_cast<unsigned int>(sensor.flags & + SensorInfo::SENSOR_FLAG_BITS_MASK_DIRECT_REPORT) >> + static_cast<unsigned int>(SensorInfo::SENSOR_FLAG_SHIFT_DIRECT_REPORT); + return r >= static_cast<unsigned int>(rate); +} + int expectedReportModeForType(SensorType type) { switch (type) { case SensorType::ACCELEROMETER: @@ -286,6 +308,24 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { std::vector<SensorInfo> getOneShotSensors(); std::vector<SensorInfo> getInjectEventSensors(); + void verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType); + + void verifyRegisterDirectChannel( + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, + bool supportsAnyDirectChannel); + + void verifyConfigure(const SensorInfo& sensor, ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool directChannelSupported); + + void queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, bool* supportsAnyDirectChannel); + + void verifyUnregisterDirectChannel(int32_t* directChannelHandle, bool supportsAnyDirectChannel); + + void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken); + inline std::shared_ptr<ISensors>& getSensors() { return mEnvironment->mSensors; } inline SensorsAidlEnvironment* getEnvironment() { return mEnvironment; } @@ -313,6 +353,18 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { ndk::ScopedAStatus flush(int32_t sensorHandle) { return getSensors()->flush(sensorHandle); } + ndk::ScopedAStatus registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn); + + ndk::ScopedAStatus unregisterDirectChannel(int32_t* channelHandle) { + return getSensors()->unregisterDirectChannel(*channelHandle); + } + + ndk::ScopedAStatus configDirectReport(int32_t sensorHandle, int32_t channelHandle, + ISensors::RateLevel rate, int32_t* reportToken) { + return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, reportToken); + } + void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor, int32_t expectedFlushCount, bool expectedResult); @@ -334,6 +386,19 @@ class SensorsAidlTest : public testing::TestWithParam<std::string> { SensorsAidlEnvironment* mEnvironment; }; +ndk::ScopedAStatus SensorsAidlTest::registerDirectChannel(const ISensors::SharedMemInfo& mem, + int32_t* aidlReturn) { + // If registeration of a channel succeeds, add the handle of channel to a set so that it can be + // unregistered when test fails. Unregister a channel does not remove the handle on purpose. + // Unregistering a channel more than once should not have negative effect. + + ndk::ScopedAStatus status = getSensors()->registerDirectChannel(mem, aidlReturn); + if (status.isOk()) { + mDirectChannelHandles.insert(*aidlReturn); + } + return status; +} + std::vector<SensorInfo> SensorsAidlTest::getSensorsList() { std::vector<SensorInfo> sensorInfoList; checkIsOk(getSensors()->getSensorsList(&sensorInfoList)); @@ -850,12 +915,141 @@ TEST_P(SensorsAidlTest, NoStaleEvents) { } } +void SensorsAidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle, + ISensors::RateLevel rateLevel, int32_t* reportToken) { + ndk::ScopedAStatus status = + configDirectReport(sensor.sensorHandle, directChannelHandle, rateLevel, reportToken); + + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type) + << " name=" << sensor.name); + + if (isDirectReportRateSupported(sensor, rateLevel)) { + ASSERT_TRUE(status.isOk()); + if (rateLevel != ISensors::RateLevel::STOP) { + ASSERT_GT(*reportToken, 0); + } else { + ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT); + } + } +} + +void SensorsAidlTest::queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType, + bool* supportsSharedMemType, + bool* supportsAnyDirectChannel) { + *supportsSharedMemType = false; + *supportsAnyDirectChannel = false; + for (const SensorInfo& curSensor : getSensorsList()) { + if (isDirectChannelTypeSupported(curSensor, memType)) { + *supportsSharedMemType = true; + } + if (isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::ASHMEM) || + isDirectChannelTypeSupported(curSensor, + ISensors::SharedMemInfo::SharedMemType::GRALLOC)) { + *supportsAnyDirectChannel = true; + } + + if (*supportsSharedMemType && *supportsAnyDirectChannel) { + break; + } + } +} + +void SensorsAidlTest::verifyRegisterDirectChannel( + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem, + int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) { + char* buffer = mem->getBuffer(); + size_t size = mem->getSize(); + + if (supportsSharedMemType) { + memset(buffer, 0xff, size); + } + + int32_t channelHandle; + + ::ndk::ScopedAStatus status = registerDirectChannel(mem->getSharedMemInfo(), &channelHandle); + if (supportsSharedMemType) { + ASSERT_TRUE(status.isOk()); + ASSERT_EQ(channelHandle, 0); + } else { + int32_t error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ASSERT_EQ(status.getExceptionCode(), error); + ASSERT_EQ(channelHandle, -1); + } + *directChannelHandle = channelHandle; +} + +void SensorsAidlTest::verifyUnregisterDirectChannel(int32_t* channelHandle, + bool supportsAnyDirectChannel) { + int result = supportsAnyDirectChannel ? EX_NONE : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = unregisterDirectChannel(channelHandle); + ASSERT_EQ(status.getExceptionCode(), result); +} + +void SensorsAidlTest::verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType) { + constexpr size_t kNumEvents = 1; + constexpr size_t kMemSize = kNumEvents * kEventSize; + + std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem( + SensorsAidlTestSharedMemory<SensorType, Event>::create(memType, kMemSize)); + ASSERT_NE(mem, nullptr); + + bool supportsSharedMemType; + bool supportsAnyDirectChannel; + queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel); + + for (const SensorInfo& sensor : getSensorsList()) { + int32_t directChannelHandle = 0; + verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType, + supportsAnyDirectChannel); + verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel); + verifyUnregisterDirectChannel(&directChannelHandle, supportsAnyDirectChannel); + } +} + +void SensorsAidlTest::verifyConfigure(const SensorInfo& sensor, + ISensors::SharedMemInfo::SharedMemType memType, + int32_t directChannelHandle, bool supportsAnyDirectChannel) { + SCOPED_TRACE(::testing::Message() + << " handle=0x" << std::hex << std::setw(8) << std::setfill('0') + << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type) + << " name=" << sensor.name); + + int32_t reportToken = 0; + if (isDirectChannelTypeSupported(sensor, memType)) { + // Verify that each rate level is properly supported + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::NORMAL, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::VERY_FAST, &reportToken); + checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::STOP, &reportToken); + + // Verify that a sensor handle of -1 is only acceptable when using RateLevel::STOP + ndk::ScopedAStatus status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getServiceSpecificError(), android::BAD_VALUE); + + status = configDirectReport(-1 /* sensorHandle */, directChannelHandle, + ISensors::RateLevel::STOP, &reportToken); + ASSERT_TRUE(status.isOk()); + } else { + // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there + // is some level of direct channel report, otherwise return INVALID_OPERATION if direct + // channel is not supported at all + int error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION; + ndk::ScopedAStatus status = configDirectReport(sensor.sensorHandle, directChannelHandle, + ISensors::RateLevel::NORMAL, &reportToken); + ASSERT_EQ(status.getExceptionCode(), error); + } +} + TEST_P(SensorsAidlTest, DirectChannelAshmem) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::ASHMEM); } TEST_P(SensorsAidlTest, DirectChannelGralloc) { - // TODO(b/195593357): Implement this + verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::GRALLOC); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsAidlTest); |