diff --git a/hidl/sensors/2.1/Android.bp b/aidl/sensors/Android.bp similarity index 76% rename from hidl/sensors/2.1/Android.bp rename to aidl/sensors/Android.bp index a643d479..7cdf37be 100644 --- a/hidl/sensors/2.1/Android.bp +++ b/aidl/sensors/Android.bp @@ -14,19 +14,20 @@ // limitations under the License. cc_binary { - name: "android.hardware.sensors@2.1-service.samsung-multihal", + name: "android.hardware.sensors-service.samsung-multihal", defaults: [ "hidl_defaults", ], vendor: true, relative_install_path: "hw", srcs: [ - "HalProxy.cpp", - "HalProxyCallback.cpp", + "ConvertUtils.cpp", + "HalProxyAidl.cpp", "service.cpp", ], - init_rc: ["android.hardware.sensors@2.1-service.samsung-multihal.rc"], - vintf_fragments: ["android.hardware.sensors@2.1-samsung-multihal.xml"], + local_include_dirs: ["include"], + init_rc: ["android.hardware.sensors-service.samsung-multihal.rc"], + vintf_fragments: ["android.hardware.sensors-samsung-multihal.xml"], header_libs: [ "android.hardware.sensors@2.X-shared-utils", ], @@ -34,7 +35,9 @@ cc_binary { "android.hardware.sensors@2.0", "android.hardware.sensors@2.0-ScopedWakelock", "android.hardware.sensors@2.1", + "android.hardware.sensors-V1-ndk", "libbase", + "libbinder_ndk", "libcutils", "libfmq", "libhidlbase", @@ -45,5 +48,6 @@ cc_binary { static_libs: [ "android.hardware.sensors@1.0-convert", "android.hardware.sensors@2.X-multihal", + "libaidlcommonsupport", ], } diff --git a/aidl/sensors/ConvertUtils.cpp b/aidl/sensors/ConvertUtils.cpp new file mode 100644 index 00000000..bf56ed52 --- /dev/null +++ b/aidl/sensors/ConvertUtils.cpp @@ -0,0 +1,363 @@ +/* + * 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 +#include + +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) { + static_assert(decltype(hidlEvent->u.data)::elementCount() == 16); + 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().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().x; + hidlEvent->u.vec3.y = aidlEvent.payload.get().y; + hidlEvent->u.vec3.z = aidlEvent.payload.get().z; + hidlEvent->u.vec3.status = + (V1_0SensorStatus)aidlEvent.payload.get().status; + break; + case AidlSensorType::GAME_ROTATION_VECTOR: + hidlEvent->u.vec4.x = aidlEvent.payload.get().x; + hidlEvent->u.vec4.y = aidlEvent.payload.get().y; + hidlEvent->u.vec4.z = aidlEvent.payload.get().z; + hidlEvent->u.vec4.w = aidlEvent.payload.get().w; + break; + case AidlSensorType::ROTATION_VECTOR: + case AidlSensorType::GEOMAGNETIC_ROTATION_VECTOR: + std::copy(aidlEvent.payload.get().values.data(), + aidlEvent.payload.get().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().x; + hidlEvent->u.uncal.y = aidlEvent.payload.get().y; + hidlEvent->u.uncal.z = aidlEvent.payload.get().z; + hidlEvent->u.uncal.x_bias = aidlEvent.payload.get().xBias; + hidlEvent->u.uncal.y_bias = aidlEvent.payload.get().yBias; + hidlEvent->u.uncal.z_bias = aidlEvent.payload.get().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(); + break; + case AidlSensorType::STEP_COUNTER: + hidlEvent->u.stepCount = aidlEvent.payload.get(); + break; + case AidlSensorType::HEART_RATE: + hidlEvent->u.heartRate.bpm = + aidlEvent.payload.get().bpm; + hidlEvent->u.heartRate.status = + (V1_0SensorStatus)aidlEvent.payload.get() + .status; + break; + case AidlSensorType::POSE_6DOF: + std::copy(std::begin(aidlEvent.payload.get().values), + std::end(aidlEvent.payload.get().values), + hidlEvent->u.pose6DOF.data()); + break; + case AidlSensorType::DYNAMIC_SENSOR_META: + hidlEvent->u.dynamic.connected = + aidlEvent.payload.get().connected; + hidlEvent->u.dynamic.sensorHandle = + aidlEvent.payload.get().sensorHandle; + std::copy( + std::begin( + aidlEvent.payload.get().uuid.values), + std::end(aidlEvent.payload.get().uuid.values), + hidlEvent->u.dynamic.uuid.data()); + break; + case AidlSensorType::ADDITIONAL_INFO: { + const AdditionalInfo& additionalInfo = + aidlEvent.payload.get(); + 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() + .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() + .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", + static_cast(additionalInfo.payload.getTag())); + break; + } + break; + } + case AidlSensorType::HEAD_TRACKER: { + const auto& ht = aidlEvent.payload.get(); + hidlEvent->u.data[0] = ht.rx; + hidlEvent->u.data[1] = ht.ry; + hidlEvent->u.data[2] = ht.rz; + hidlEvent->u.data[3] = ht.vx; + hidlEvent->u.data[4] = ht.vy; + hidlEvent->u.data[5] = ht.vz; + + // IMPORTANT: Because we want to preserve the data range of discontinuityCount, + // we assume the data can be interpreted as an int32_t directly (e.g. the underlying + // HIDL HAL must be using memcpy or equivalent to store this value). + *(reinterpret_cast(&hidlEvent->u.data[6])) = ht.discontinuityCount; + break; + } + default: { + CHECK_GE((int32_t)aidlEvent.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE); + std::copy(std::begin(aidlEvent.payload.get().values), + std::end(aidlEvent.payload.get().values), + hidlEvent->u.data.data()); + break; + } + } +} + +void convertToAidlEvent(const V2_1Event& hidlEvent, AidlEvent* aidlEvent) { + static_assert(decltype(hidlEvent.u.data)::elementCount() == 16); + 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(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; + vec3.status = (SensorStatus)hidlEvent.u.vec3.status; + aidlEvent->payload.set(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(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(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(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(hidlEvent.u.scalar); + break; + case V2_1SensorType::STEP_COUNTER: + aidlEvent->payload.set(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(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(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(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( + int32Values); + aidlEvent->payload.set(additionalInfo); + break; + } + default: { + if (static_cast(hidlEvent.sensorType) == + static_cast(AidlSensorType::HEAD_TRACKER)) { + Event::EventPayload::HeadTracker headTracker; + headTracker.rx = hidlEvent.u.data[0]; + headTracker.ry = hidlEvent.u.data[1]; + headTracker.rz = hidlEvent.u.data[2]; + headTracker.vx = hidlEvent.u.data[3]; + headTracker.vy = hidlEvent.u.data[4]; + headTracker.vz = hidlEvent.u.data[5]; + + // IMPORTANT: Because we want to preserve the data range of discontinuityCount, + // we assume the data can be interpreted as an int32_t directly (e.g. the underlying + // HIDL HAL must be using memcpy or equivalent to store this value). + headTracker.discontinuityCount = + *(reinterpret_cast(&hidlEvent.u.data[6])); + + aidlEvent->payload.set(headTracker); + } else { + 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(data); + } + break; + } + } +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/aidl/sensors/HalProxyAidl.cpp b/aidl/sensors/HalProxyAidl.cpp new file mode 100644 index 00000000..cdef73a7 --- /dev/null +++ b/aidl/sensors/HalProxyAidl.cpp @@ -0,0 +1,269 @@ +/* + * 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. + */ + +//#define VERBOSE + +#include "HalProxyAidl.h" +#include +#include +#include +#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 ::aidl::android::hardware::sensors::SensorInfo; +using ::android::hardware::sensors::V2_1::implementation::convertToOldEvent; +using ::ndk::ScopedAStatus; + +namespace aidl { +namespace android { +namespace hardware { +namespace sensors { +namespace implementation { + +static ScopedAStatus +resultToAStatus(::android::hardware::sensors::V1_0::Result result) { + switch (result) { + case ::android::hardware::sensors::V1_0::Result::OK: + return ScopedAStatus::ok(); + case ::android::hardware::sensors::V1_0::Result::PERMISSION_DENIED: + return ScopedAStatus::fromExceptionCode(EX_SECURITY); + case ::android::hardware::sensors::V1_0::Result::NO_MEMORY: + return ScopedAStatus::fromServiceSpecificError(ISensors::ERROR_NO_MEMORY); + case ::android::hardware::sensors::V1_0::Result::BAD_VALUE: + return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + case ::android::hardware::sensors::V1_0::Result::INVALID_OPERATION: + return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + default: + return ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED); + } +} + +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; + default: + assert(false); + } +} + +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; + default: + assert(false); + } +} + +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; + default: + assert(false); + } +} + +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; + default: + assert(false); + } +} + +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; +} + +ScopedAStatus HalProxyAidl::activate(int32_t in_sensorHandle, bool in_enabled) { + return resultToAStatus(HalProxy::activate(in_sensorHandle, in_enabled)); +} + +ScopedAStatus HalProxyAidl::batch(int32_t in_sensorHandle, + int64_t in_samplingPeriodNs, + int64_t in_maxReportLatencyNs) { + return resultToAStatus(HalProxy::batch(in_sensorHandle, in_samplingPeriodNs, + in_maxReportLatencyNs)); +} + +ScopedAStatus HalProxyAidl::configDirectReport(int32_t in_sensorHandle, + int32_t in_channelHandle, + ISensors::RateLevel in_rate, + int32_t *_aidl_return) { + ScopedAStatus status = + ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + HalProxy::configDirectReport( + in_sensorHandle, in_channelHandle, convertRateLevel(in_rate), + [&status, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + status = resultToAStatus(result); + *_aidl_return = reportToken; + }); + + return status; +} + +ScopedAStatus HalProxyAidl::flush(int32_t in_sensorHandle) { + return resultToAStatus(HalProxy::flush(in_sensorHandle)); +} + + +ScopedAStatus HalProxyAidl::getSensorsList( + std::vector<::aidl::android::hardware::sensors::SensorInfo> *_aidl_return) { + for (const auto &sensor : HalProxy::getSensors()) { + SensorInfo dst = sensor.second; + + if (dst.requiredPermission == "com.samsung.permission.SSENSOR") { + dst.requiredPermission = ""; + } + + if (dst.typeAsString == "com.samsung.sensor.physical_proximity" || + dst.typeAsString == "com.samsung.sensor.hover_proximity") { + ALOGI("Fixing %s", dst.typeAsString.c_str()); + dst.type = ::android::hardware::sensors::V2_1::SensorType::PROXIMITY; + dst.typeAsString = SENSOR_STRING_TYPE_PROXIMITY; + dst.maxRange = 1; + } + +#ifdef VERBOSE + ALOGI( "SENSOR NAME:%s ", dst.name.c_str()); + ALOGI( " VENDOR:%s ", dst.name.c_str()); + ALOGI( " TYPE:%d ", (uint32_t)dst.type); + ALOGI( " TYPE_AS_STRING:%s ", dst.typeAsString.c_str()); +#endif + + _aidl_return->push_back(convertSensorInfo(dst)); + } + return ScopedAStatus::ok(); +} + +ScopedAStatus HalProxyAidl::initialize( + const MQDescriptor<::aidl::android::hardware::sensors::Event, + SynchronizedReadWrite> &in_eventQueueDescriptor, + const MQDescriptor &in_wakeLockDescriptor, + const std::shared_ptr &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(aidlEventQueue); + + auto aidlWakeLockQueue = std::make_unique< + ::android::AidlMessageQueue>( + in_wakeLockDescriptor, true /* resetPointers */); + std::unique_ptr<::android::hardware::sensors::V2_1::implementation:: + WakeLockMessageQueueWrapperBase> + wakeLockQueue = + std::make_unique(aidlWakeLockQueue); + + return resultToAStatus( + initializeCommon(eventQueue, wakeLockQueue, dynamicCallback)); +} + +ScopedAStatus HalProxyAidl::injectSensorData( + const ::aidl::android::hardware::sensors::Event &in_event) { + ::android::hardware::sensors::V2_1::Event hidlEvent; + convertToHidlEvent(in_event, &hidlEvent); + return resultToAStatus( + HalProxy::injectSensorData(convertToOldEvent(hidlEvent))); +} + +ScopedAStatus +HalProxyAidl::registerDirectChannel(const ISensors::SharedMemInfo &in_mem, + int32_t *_aidl_return) { + ScopedAStatus status = + ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + ::android::hardware::sensors::V1_0::SharedMemInfo sharedMemInfo = + convertSharedMemInfo(in_mem); + + HalProxy::registerDirectChannel( + sharedMemInfo, + [&status, _aidl_return](::android::hardware::sensors::V1_0::Result result, + int32_t reportToken) { + status = resultToAStatus(result); + *_aidl_return = reportToken; + }); + + native_handle_delete(const_cast( + sharedMemInfo.memoryHandle.getNativeHandle())); + + return status; +} + +ScopedAStatus HalProxyAidl::setOperationMode( + ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) { + return resultToAStatus( + HalProxy::setOperationMode(convertOperationMode(in_mode))); +} + +ScopedAStatus HalProxyAidl::unregisterDirectChannel(int32_t in_channelHandle) { + return resultToAStatus(HalProxy::unregisterDirectChannel(in_channelHandle)); +} + +binder_status_t HalProxyAidl::dump(int fd, const char ** /* args */, + uint32_t /* numArgs */) { + native_handle_t *nativeHandle = + native_handle_create(1 /* numFds */, 0 /* numInts */); + nativeHandle->data[0] = fd; + + HalProxy::debug(nativeHandle, {} /* args */); + + native_handle_delete(nativeHandle); + return STATUS_OK; +} + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/aidl/sensors/android.hardware.sensors-samsung-multihal.xml b/aidl/sensors/android.hardware.sensors-samsung-multihal.xml new file mode 100644 index 00000000..f7b8f0ab --- /dev/null +++ b/aidl/sensors/android.hardware.sensors-samsung-multihal.xml @@ -0,0 +1,23 @@ + + + + + android.hardware.sensors + 1 + ISensors/default + + diff --git a/aidl/sensors/android.hardware.sensors-service.samsung-multihal.rc b/aidl/sensors/android.hardware.sensors-service.samsung-multihal.rc new file mode 100644 index 00000000..fff7b7d2 --- /dev/null +++ b/aidl/sensors/android.hardware.sensors-service.samsung-multihal.rc @@ -0,0 +1,7 @@ +service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.samsung-multihal + class hal + user system + group system wakelock context_hub input + task_profiles ServiceCapacityLow + capabilities BLOCK_SUSPEND + rlimit rtprio 10 10 diff --git a/aidl/sensors/include/ConvertUtils.h b/aidl/sensors/include/ConvertUtils.h new file mode 100644 index 00000000..91dfabde --- /dev/null +++ b/aidl/sensors/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 +#include + +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/aidl/sensors/include/EventMessageQueueWrapperAidl.h b/aidl/sensors/include/EventMessageQueueWrapperAidl.h new file mode 100644 index 00000000..3eaa1d43 --- /dev/null +++ b/aidl/sensors/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 +#include +#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* 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/aidl/sensors/include/HalProxyAidl.h b/aidl/sensors/include/HalProxyAidl.h new file mode 100644 index 00000000..5c817159 --- /dev/null +++ b/aidl/sensors/include/HalProxyAidl.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 +#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; + + binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; +}; + +} // namespace implementation +} // namespace sensors +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/aidl/sensors/include/ISensorsCallbackWrapperAidl.h b/aidl/sensors/include/ISensorsCallbackWrapperAidl.h new file mode 100644 index 00000000..6ef6c639 --- /dev/null +++ b/aidl/sensors/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 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 onDynamicSensorsDisconnected( + const ::android::hardware::hidl_vec& 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/aidl/sensors/include/WakeLockMessageQueueWrapperAidl.h b/aidl/sensors/include/WakeLockMessageQueueWrapperAidl.h new file mode 100644 index 00000000..6be0b69a --- /dev/null +++ b/aidl/sensors/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 +#include +#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* 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(wakeLocks), numToRead, + readNotification, writeNotification, timeOutNanos, evFlag); + } + + bool write(const uint32_t* wakeLock) override { + return mQueue->write(reinterpret_cast(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/aidl/sensors/service.cpp b/aidl/sensors/service.cpp new file mode 100644 index 00000000..11c108a3 --- /dev/null +++ b/aidl/sensors/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 +#include +#include +#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(); + 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/hidl/sensors/2.1/HalProxy.cpp b/hidl/sensors/2.1/HalProxy.cpp deleted file mode 100644 index 18af6197..00000000 --- a/hidl/sensors/2.1/HalProxy.cpp +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -//#define VERBOSE - -#include "HalProxy.h" - -#include - -#include -#include "hardware_legacy/power.h" - -#include - -#include -#include -#include -#include -#include - -namespace android { -namespace hardware { -namespace sensors { -namespace V2_1 { -namespace implementation { - -using ::android::hardware::sensors::V1_0::Result; -using ::android::hardware::sensors::V2_0::EventQueueFlagBits; -using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits; -using ::android::hardware::sensors::V2_0::implementation::getTimeNow; -using ::android::hardware::sensors::V2_0::implementation::kWakelockTimeoutNs; - -typedef V2_0::implementation::ISensorsSubHal*(SensorsHalGetSubHalFunc)(uint32_t*); -typedef V2_1::implementation::ISensorsSubHal*(SensorsHalGetSubHalV2_1Func)(uint32_t*); - -static constexpr int32_t kBitsAfterSubHalIndex = 24; - -/** - * Set the subhal index as first byte of sensor handle and return this modified version. - * - * @param sensorHandle The sensor handle to modify. - * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to. - * - * @return The modified sensor handle. - */ -int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) { - return sensorHandle | (static_cast(subHalIndex) << kBitsAfterSubHalIndex); -} - -/** - * Extract the subHalIndex from sensorHandle. - * - * @param sensorHandle The sensorHandle to extract from. - * - * @return The subhal index. - */ -size_t extractSubHalIndex(int32_t sensorHandle) { - return static_cast(sensorHandle >> kBitsAfterSubHalIndex); -} - -/** - * Convert nanoseconds to milliseconds. - * - * @param nanos The nanoseconds input. - * - * @return The milliseconds count. - */ -int64_t msFromNs(int64_t nanos) { - constexpr int64_t nanosecondsInAMillsecond = 1000000; - return nanos / nanosecondsInAMillsecond; -} - -HalProxy::HalProxy() { - const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf"; - initializeSubHalListFromConfigFile(kMultiHalConfigFile); - init(); -} - -HalProxy::HalProxy(std::vector& subHalList) { - for (ISensorsSubHalV2_0* subHal : subHalList) { - mSubHalList.push_back(std::make_unique(subHal)); - } - - init(); -} - -HalProxy::HalProxy(std::vector& subHalList, - std::vector& subHalListV2_1) { - for (ISensorsSubHalV2_0* subHal : subHalList) { - mSubHalList.push_back(std::make_unique(subHal)); - } - - for (ISensorsSubHalV2_1* subHal : subHalListV2_1) { - mSubHalList.push_back(std::make_unique(subHal)); - } - - init(); -} - -HalProxy::~HalProxy() { - stopThreads(); -} - -Return HalProxy::getSensorsList_2_1(ISensorsV2_1::getSensorsList_2_1_cb _hidl_cb) { - std::vector sensors; - for (const auto& iter : mSensors) { - V2_1::SensorInfo dst = iter.second; - - if (dst.requiredPermission == "com.samsung.permission.SSENSOR") { - dst.requiredPermission = ""; - } - - if (dst.typeAsString == "com.samsung.sensor.physical_proximity" || - dst.typeAsString == "com.samsung.sensor.hover_proximity") { - ALOGI("Fixing %s", dst.typeAsString.c_str()); - dst.type = V2_1::SensorType::PROXIMITY; - dst.typeAsString = SENSOR_STRING_TYPE_PROXIMITY; - dst.maxRange = 1; - } - -#ifdef VERBOSE - ALOGI( "SENSOR NAME:%s ", dst.name.c_str()); - ALOGI( " VENDOR:%s ", dst.name.c_str()); - ALOGI( " TYPE:%d ", (uint32_t)dst.type); - ALOGI( " TYPE_AS_STRING:%s ", dst.typeAsString.c_str()); -#endif - sensors.push_back(dst); - } - _hidl_cb(sensors); - return Void(); -} - -Return HalProxy::getSensorsList(ISensorsV2_0::getSensorsList_cb _hidl_cb) { - std::vector sensors; - for (const auto& iter : mSensors) { - sensors.push_back(convertToOldSensorInfo(iter.second)); - } - _hidl_cb(sensors); - return Void(); -} - -Return HalProxy::setOperationMode(OperationMode mode) { - Result result = Result::OK; - size_t subHalIndex; - for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) { - result = mSubHalList[subHalIndex]->setOperationMode(mode); - if (result != Result::OK) { - ALOGE("setOperationMode failed for SubHal: %s", - mSubHalList[subHalIndex]->getName().c_str()); - break; - } - } - - if (result != Result::OK) { - // Reset the subhal operation modes that have been flipped - for (size_t i = 0; i < subHalIndex; i++) { - mSubHalList[i]->setOperationMode(mCurrentOperationMode); - } - } else { - mCurrentOperationMode = mode; - } - return result; -} - -Return HalProxy::activate(int32_t sensorHandle, bool enabled) { - if (!isSubHalIndexValid(sensorHandle)) { - return Result::BAD_VALUE; - } - return getSubHalForSensorHandle(sensorHandle) - ->activate(clearSubHalIndex(sensorHandle), enabled); -} - -Return HalProxy::initialize_2_1( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) { - sp dynamicCallback = - new ISensorsCallbackWrapperV2_1(sensorsCallback); - - // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. - auto eventQueue = - std::make_unique(eventQueueDescriptor, true /* resetPointers */); - std::unique_ptr queue = - std::make_unique(eventQueue); - - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); -} - -Return HalProxy::initialize( - const ::android::hardware::MQDescriptorSync& eventQueueDescriptor, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) { - sp dynamicCallback = - new ISensorsCallbackWrapperV2_0(sensorsCallback); - - // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. - auto eventQueue = - std::make_unique(eventQueueDescriptor, true /* resetPointers */); - std::unique_ptr queue = - std::make_unique(eventQueue); - - return initializeCommon(queue, wakeLockDescriptor, dynamicCallback); -} - -Return HalProxy::initializeCommon( - std::unique_ptr& eventQueue, - const ::android::hardware::MQDescriptorSync& wakeLockDescriptor, - const sp& sensorsCallback) { - Result result = Result::OK; - - stopThreads(); - resetSharedWakelock(); - - // So that the pending write events queue can be cleared safely and when we start threads - // again we do not get new events until after initialize resets the subhals. - disableAllSensors(); - - // Clears the queue if any events were pending write before. - mPendingWriteEventsQueue = std::queue, size_t>>(); - mSizePendingWriteEventsQueue = 0; - - // Clears previously connected dynamic sensors - mDynamicSensors.clear(); - - mDynamicSensorsCallback = sensorsCallback; - - // Create the Event FMQ from the eventQueueDescriptor. Reset the read/write positions. - mEventQueue = std::move(eventQueue); - - // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP - // events have been successfully read and handled by the framework. - mWakeLockQueue = - std::make_unique(wakeLockDescriptor, true /* resetPointers */); - - if (mEventQueueFlag != nullptr) { - EventFlag::deleteEventFlag(&mEventQueueFlag); - } - if (mWakelockQueueFlag != nullptr) { - EventFlag::deleteEventFlag(&mWakelockQueueFlag); - } - if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) { - result = Result::BAD_VALUE; - } - if (EventFlag::createEventFlag(mWakeLockQueue->getEventFlagWord(), &mWakelockQueueFlag) != OK) { - result = Result::BAD_VALUE; - } - if (!mDynamicSensorsCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) { - result = Result::BAD_VALUE; - } - - mThreadsRun.store(true); - - mPendingWritesThread = std::thread(startPendingWritesThread, this); - mWakelockThread = std::thread(startWakelockThread, this); - - for (size_t i = 0; i < mSubHalList.size(); i++) { - Result currRes = mSubHalList[i]->initialize(this, this, i); - if (currRes != Result::OK) { - result = currRes; - ALOGE("Subhal '%s' failed to initialize.", mSubHalList[i]->getName().c_str()); - break; - } - } - - mCurrentOperationMode = OperationMode::NORMAL; - - return result; -} - -Return HalProxy::batch(int32_t sensorHandle, int64_t samplingPeriodNs, - int64_t maxReportLatencyNs) { - if (!isSubHalIndexValid(sensorHandle)) { - return Result::BAD_VALUE; - } - return getSubHalForSensorHandle(sensorHandle) - ->batch(clearSubHalIndex(sensorHandle), samplingPeriodNs, maxReportLatencyNs); -} - -Return HalProxy::flush(int32_t sensorHandle) { - if (!isSubHalIndexValid(sensorHandle)) { - return Result::BAD_VALUE; - } - return getSubHalForSensorHandle(sensorHandle)->flush(clearSubHalIndex(sensorHandle)); -} - -Return HalProxy::injectSensorData_2_1(const V2_1::Event& event) { - return injectSensorData(convertToOldEvent(event)); -} - -Return HalProxy::injectSensorData(const V1_0::Event& event) { - Result result = Result::OK; - if (mCurrentOperationMode == OperationMode::NORMAL && - event.sensorType != V1_0::SensorType::ADDITIONAL_INFO) { - ALOGE("An event with type != ADDITIONAL_INFO passed to injectSensorData while operation" - " mode was NORMAL."); - result = Result::BAD_VALUE; - } - if (result == Result::OK) { - V1_0::Event subHalEvent = event; - if (!isSubHalIndexValid(event.sensorHandle)) { - return Result::BAD_VALUE; - } - subHalEvent.sensorHandle = clearSubHalIndex(event.sensorHandle); - result = getSubHalForSensorHandle(event.sensorHandle) - ->injectSensorData(convertToNewEvent(subHalEvent)); - } - return result; -} - -Return HalProxy::registerDirectChannel(const SharedMemInfo& mem, - ISensorsV2_0::registerDirectChannel_cb _hidl_cb) { - if (mDirectChannelSubHal == nullptr) { - _hidl_cb(Result::INVALID_OPERATION, -1 /* channelHandle */); - } else { - mDirectChannelSubHal->registerDirectChannel(mem, _hidl_cb); - } - return Return(); -} - -Return HalProxy::unregisterDirectChannel(int32_t channelHandle) { - Result result; - if (mDirectChannelSubHal == nullptr) { - result = Result::INVALID_OPERATION; - } else { - result = mDirectChannelSubHal->unregisterDirectChannel(channelHandle); - } - return result; -} - -Return HalProxy::configDirectReport(int32_t sensorHandle, int32_t channelHandle, - RateLevel rate, - ISensorsV2_0::configDirectReport_cb _hidl_cb) { - if (mDirectChannelSubHal == nullptr) { - _hidl_cb(Result::INVALID_OPERATION, -1 /* reportToken */); - } else if (sensorHandle == -1 && rate != RateLevel::STOP) { - _hidl_cb(Result::BAD_VALUE, -1 /* reportToken */); - } else { - // -1 denotes all sensors should be disabled - if (sensorHandle != -1) { - sensorHandle = clearSubHalIndex(sensorHandle); - } - mDirectChannelSubHal->configDirectReport(sensorHandle, channelHandle, rate, _hidl_cb); - } - return Return(); -} - -Return HalProxy::debug(const hidl_handle& fd, const hidl_vec& /*args*/) { - if (fd.getNativeHandle() == nullptr || fd->numFds < 1) { - ALOGE("%s: missing fd for writing", __FUNCTION__); - return Void(); - } - - android::base::borrowed_fd writeFd = dup(fd->data[0]); - - std::ostringstream stream; - stream << "===HalProxy===" << std::endl; - stream << "Internal values:" << std::endl; - stream << " Threads are running: " << (mThreadsRun.load() ? "true" : "false") << std::endl; - int64_t now = getTimeNow(); - stream << " Wakelock timeout start time: " << msFromNs(now - mWakelockTimeoutStartTime) - << " ms ago" << std::endl; - stream << " Wakelock timeout reset time: " << msFromNs(now - mWakelockTimeoutResetTime) - << " ms ago" << std::endl; - // TODO(b/142969448): Add logging for history of wakelock acquisition per subhal. - stream << " Wakelock ref count: " << mWakelockRefCount << std::endl; - stream << " # of events on pending write writes queue: " << mSizePendingWriteEventsQueue - << std::endl; - stream << " Most events seen on pending write events queue: " - << mMostEventsObservedPendingWriteEventsQueue << std::endl; - if (!mPendingWriteEventsQueue.empty()) { - stream << " Size of events list on front of pending writes queue: " - << mPendingWriteEventsQueue.front().first.size() << std::endl; - } - stream << " # of non-dynamic sensors across all subhals: " << mSensors.size() << std::endl; - stream << " # of dynamic sensors across all subhals: " << mDynamicSensors.size() << std::endl; - stream << "SubHals (" << mSubHalList.size() << "):" << std::endl; - for (auto& subHal : mSubHalList) { - stream << " Name: " << subHal->getName() << std::endl; - stream << " Debug dump: " << std::endl; - android::base::WriteStringToFd(stream.str(), writeFd); - subHal->debug(fd, {}); - stream.str(""); - stream << std::endl; - } - android::base::WriteStringToFd(stream.str(), writeFd); - return Return(); -} - -Return HalProxy::onDynamicSensorsConnected(const hidl_vec& dynamicSensorsAdded, - int32_t subHalIndex) { - std::vector sensors; - { - std::lock_guard lock(mDynamicSensorsMutex); - for (SensorInfo sensor : dynamicSensorsAdded) { - if (!subHalIndexIsClear(sensor.sensorHandle)) { - ALOGE("Dynamic sensor added %s had sensorHandle with first byte not 0.", - sensor.name.c_str()); - } else { - sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex); - mDynamicSensors[sensor.sensorHandle] = sensor; - sensors.push_back(sensor); - } - } - } - mDynamicSensorsCallback->onDynamicSensorsConnected(sensors); - return Return(); -} - -Return HalProxy::onDynamicSensorsDisconnected( - const hidl_vec& dynamicSensorHandlesRemoved, int32_t subHalIndex) { - // TODO(b/143302327): Block this call until all pending events are flushed from queue - std::vector sensorHandles; - { - std::lock_guard lock(mDynamicSensorsMutex); - for (int32_t sensorHandle : dynamicSensorHandlesRemoved) { - if (!subHalIndexIsClear(sensorHandle)) { - ALOGE("Dynamic sensorHandle removed had first byte not 0."); - } else { - sensorHandle = setSubHalIndex(sensorHandle, subHalIndex); - if (mDynamicSensors.find(sensorHandle) != mDynamicSensors.end()) { - mDynamicSensors.erase(sensorHandle); - sensorHandles.push_back(sensorHandle); - } - } - } - } - mDynamicSensorsCallback->onDynamicSensorsDisconnected(sensorHandles); - return Return(); -} - -void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) { - std::ifstream subHalConfigStream(configFileName); - if (!subHalConfigStream) { - ALOGE("Failed to load subHal config file: %s", configFileName); - } else { - std::string subHalLibraryFile; - while (subHalConfigStream >> subHalLibraryFile) { - void* handle = getHandleForSubHalSharedObject(subHalLibraryFile); - if (handle == nullptr) { - ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str()); - } else { - SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr = - (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal"); - if (sensorsHalGetSubHalPtr != nullptr) { - std::function sensorsHalGetSubHal = - *sensorsHalGetSubHalPtr; - uint32_t version; - ISensorsSubHalV2_0* subHal = sensorsHalGetSubHal(&version); - if (version != SUB_HAL_2_0_VERSION) { - ALOGE("SubHal version was not 2.0 for library: %s", - subHalLibraryFile.c_str()); - } else { - ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str()); - mSubHalList.push_back(std::make_unique(subHal)); - } - } else { - SensorsHalGetSubHalV2_1Func* getSubHalV2_1Ptr = - (SensorsHalGetSubHalV2_1Func*)dlsym(handle, "sensorsHalGetSubHal_2_1"); - - if (getSubHalV2_1Ptr == nullptr) { - ALOGE("Failed to locate sensorsHalGetSubHal function for library: %s", - subHalLibraryFile.c_str()); - } else { - std::function sensorsHalGetSubHal_2_1 = - *getSubHalV2_1Ptr; - uint32_t version; - ISensorsSubHalV2_1* subHal = sensorsHalGetSubHal_2_1(&version); - if (version != SUB_HAL_2_1_VERSION) { - ALOGE("SubHal version was not 2.1 for library: %s", - subHalLibraryFile.c_str()); - } else { - ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str()); - mSubHalList.push_back(std::make_unique(subHal)); - } - } - } - } - } - } -} - -void HalProxy::initializeSensorList() { - for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) { - auto result = mSubHalList[subHalIndex]->getSensorsList([&](const auto& list) { - for (SensorInfo sensor : list) { - if (!subHalIndexIsClear(sensor.sensorHandle)) { - ALOGE("SubHal sensorHandle's first byte was not 0"); - } else { - ALOGV("Loaded sensor: %s", sensor.name.c_str()); - sensor.sensorHandle = setSubHalIndex(sensor.sensorHandle, subHalIndex); - setDirectChannelFlags(&sensor, mSubHalList[subHalIndex]); - mSensors[sensor.sensorHandle] = sensor; - } - } - }); - if (!result.isOk()) { - ALOGE("getSensorsList call failed for SubHal: %s", - mSubHalList[subHalIndex]->getName().c_str()); - } - } -} - -void* HalProxy::getHandleForSubHalSharedObject(const std::string& filename) { - static const std::string kSubHalShareObjectLocations[] = { - "", // Default locations will be searched -#ifdef __LP64__ - "/vendor/lib64/hw/", "/odm/lib64/hw/" -#else - "/vendor/lib/hw/", "/odm/lib/hw/" -#endif - }; - - for (const std::string& dir : kSubHalShareObjectLocations) { - void* handle = dlopen((dir + filename).c_str(), RTLD_NOW); - if (handle != nullptr) { - return handle; - } - } - return nullptr; -} - -void HalProxy::init() { - initializeSensorList(); -} - -void HalProxy::stopThreads() { - mThreadsRun.store(false); - if (mEventQueueFlag != nullptr && mEventQueue != nullptr) { - size_t numToRead = mEventQueue->availableToRead(); - std::vector events(numToRead); - mEventQueue->read(events.data(), numToRead); - mEventQueueFlag->wake(static_cast(EventQueueFlagBits::EVENTS_READ)); - } - if (mWakelockQueueFlag != nullptr && mWakeLockQueue != nullptr) { - uint32_t kZero = 0; - mWakeLockQueue->write(&kZero); - mWakelockQueueFlag->wake(static_cast(WakeLockQueueFlagBits::DATA_WRITTEN)); - } - mWakelockCV.notify_one(); - mEventQueueWriteCV.notify_one(); - if (mPendingWritesThread.joinable()) { - mPendingWritesThread.join(); - } - if (mWakelockThread.joinable()) { - mWakelockThread.join(); - } -} - -void HalProxy::disableAllSensors() { - for (const auto& sensorEntry : mSensors) { - int32_t sensorHandle = sensorEntry.first; - activate(sensorHandle, false /* enabled */); - } - std::lock_guard dynamicSensorsLock(mDynamicSensorsMutex); - for (const auto& sensorEntry : mDynamicSensors) { - int32_t sensorHandle = sensorEntry.first; - activate(sensorHandle, false /* enabled */); - } -} - -void HalProxy::startPendingWritesThread(HalProxy* halProxy) { - halProxy->handlePendingWrites(); -} - -void HalProxy::handlePendingWrites() { - // TODO(b/143302327): Find a way to optimize locking strategy maybe using two mutexes instead of - // one. - std::unique_lock lock(mEventQueueWriteMutex); - while (mThreadsRun.load()) { - mEventQueueWriteCV.wait( - lock, [&] { return !mPendingWriteEventsQueue.empty() || !mThreadsRun.load(); }); - if (mThreadsRun.load()) { - std::vector& pendingWriteEvents = mPendingWriteEventsQueue.front().first; - size_t numWakeupEvents = mPendingWriteEventsQueue.front().second; - size_t eventQueueSize = mEventQueue->getQuantumCount(); - size_t numToWrite = std::min(pendingWriteEvents.size(), eventQueueSize); - lock.unlock(); - if (!mEventQueue->writeBlocking( - pendingWriteEvents.data(), numToWrite, - static_cast(EventQueueFlagBits::EVENTS_READ), - static_cast(EventQueueFlagBits::READ_AND_PROCESS), - kPendingWriteTimeoutNs, mEventQueueFlag)) { - ALOGE("Dropping %zu events after blockingWrite failed.", numToWrite); - if (numWakeupEvents > 0) { - if (pendingWriteEvents.size() > eventQueueSize) { - decrementRefCountAndMaybeReleaseWakelock( - countNumWakeupEvents(pendingWriteEvents, eventQueueSize)); - } else { - decrementRefCountAndMaybeReleaseWakelock(numWakeupEvents); - } - } - } - lock.lock(); - mSizePendingWriteEventsQueue -= numToWrite; - if (pendingWriteEvents.size() > eventQueueSize) { - // TODO(b/143302327): Check if this erase operation is too inefficient. It will copy - // all the events ahead of it down to fill gap off array at front after the erase. - pendingWriteEvents.erase(pendingWriteEvents.begin(), - pendingWriteEvents.begin() + eventQueueSize); - } else { - mPendingWriteEventsQueue.pop(); - } - } - } -} - -void HalProxy::startWakelockThread(HalProxy* halProxy) { - halProxy->handleWakelocks(); -} - -void HalProxy::handleWakelocks() { - std::unique_lock lock(mWakelockMutex); - while (mThreadsRun.load()) { - mWakelockCV.wait(lock, [&] { return mWakelockRefCount > 0 || !mThreadsRun.load(); }); - if (mThreadsRun.load()) { - int64_t timeLeft; - if (sharedWakelockDidTimeout(&timeLeft)) { - resetSharedWakelock(); - } else { - uint32_t numWakeLocksProcessed; - lock.unlock(); - bool success = mWakeLockQueue->readBlocking( - &numWakeLocksProcessed, 1, 0, - static_cast(WakeLockQueueFlagBits::DATA_WRITTEN), timeLeft); - lock.lock(); - if (success) { - decrementRefCountAndMaybeReleaseWakelock( - static_cast(numWakeLocksProcessed)); - } - } - } - } - resetSharedWakelock(); -} - -bool HalProxy::sharedWakelockDidTimeout(int64_t* timeLeft) { - bool didTimeout; - int64_t duration = getTimeNow() - mWakelockTimeoutStartTime; - if (duration > kWakelockTimeoutNs) { - didTimeout = true; - } else { - didTimeout = false; - *timeLeft = kWakelockTimeoutNs - duration; - } - return didTimeout; -} - -void HalProxy::resetSharedWakelock() { - std::lock_guard lockGuard(mWakelockMutex); - decrementRefCountAndMaybeReleaseWakelock(mWakelockRefCount); - mWakelockTimeoutResetTime = getTimeNow(); -} - -void HalProxy::postEventsToMessageQueue(const std::vector& events, size_t numWakeupEvents, - V2_0::implementation::ScopedWakelock wakelock) { - size_t numToWrite = 0; - std::lock_guard lock(mEventQueueWriteMutex); - if (wakelock.isLocked()) { - incrementRefCountAndMaybeAcquireWakelock(numWakeupEvents); - } - if (mPendingWriteEventsQueue.empty()) { - numToWrite = std::min(events.size(), mEventQueue->availableToWrite()); - if (numToWrite > 0) { - if (mEventQueue->write(events.data(), numToWrite)) { - // TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit - // in more writes immediately - mEventQueueFlag->wake(static_cast(EventQueueFlagBits::READ_AND_PROCESS)); - } else { - numToWrite = 0; - } - } - } - size_t numLeft = events.size() - numToWrite; - if (numToWrite < events.size() && - mSizePendingWriteEventsQueue + numLeft <= kMaxSizePendingWriteEventsQueue) { - std::vector eventsLeft(events.begin() + numToWrite, events.end()); - mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents}); - mSizePendingWriteEventsQueue += numLeft; - mMostEventsObservedPendingWriteEventsQueue = - std::max(mMostEventsObservedPendingWriteEventsQueue, mSizePendingWriteEventsQueue); - mEventQueueWriteCV.notify_one(); - } -} - -bool HalProxy::incrementRefCountAndMaybeAcquireWakelock(size_t delta, - int64_t* timeoutStart /* = nullptr */) { - if (!mThreadsRun.load()) return false; - std::lock_guard lockGuard(mWakelockMutex); - if (mWakelockRefCount == 0) { - acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakelockName); - mWakelockCV.notify_one(); - } - mWakelockTimeoutStartTime = getTimeNow(); - mWakelockRefCount += delta; - if (timeoutStart != nullptr) { - *timeoutStart = mWakelockTimeoutStartTime; - } - return true; -} - -void HalProxy::decrementRefCountAndMaybeReleaseWakelock(size_t delta, - int64_t timeoutStart /* = -1 */) { - if (!mThreadsRun.load()) return; - std::lock_guard lockGuard(mWakelockMutex); - if (delta > mWakelockRefCount) { - ALOGE("Decrementing wakelock ref count by %zu when count is %zu", - delta, mWakelockRefCount); - } - if (timeoutStart == -1) timeoutStart = mWakelockTimeoutResetTime; - if (mWakelockRefCount == 0 || timeoutStart < mWakelockTimeoutResetTime) return; - mWakelockRefCount -= std::min(mWakelockRefCount, delta); - if (mWakelockRefCount == 0) { - release_wake_lock(kWakelockName); - } -} - -void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, - std::shared_ptr subHal) { - bool sensorSupportsDirectChannel = - (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT | - V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0; - if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) { - mDirectChannelSubHal = subHal; - } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) { - // disable direct channel capability for sensors in subHals that are not - // the only one we will enable - sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT | - V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL); - } -} - -std::shared_ptr HalProxy::getSubHalForSensorHandle(int32_t sensorHandle) { - return mSubHalList[extractSubHalIndex(sensorHandle)]; -} - -bool HalProxy::isSubHalIndexValid(int32_t sensorHandle) { - return extractSubHalIndex(sensorHandle) < mSubHalList.size(); -} - -size_t HalProxy::countNumWakeupEvents(const std::vector& events, size_t n) { - size_t numWakeupEvents = 0; - for (size_t i = 0; i < n; i++) { - int32_t sensorHandle = events[i].sensorHandle; - if (mSensors[sensorHandle].flags & static_cast(V1_0::SensorFlagBits::WAKE_UP)) { - numWakeupEvents++; - } - } - return numWakeupEvents; -} - -int32_t HalProxy::clearSubHalIndex(int32_t sensorHandle) { - return sensorHandle & (~kSensorHandleSubHalIndexMask); -} - -bool HalProxy::subHalIndexIsClear(int32_t sensorHandle) { - return (sensorHandle & kSensorHandleSubHalIndexMask) == 0; -} - -} // namespace implementation -} // namespace V2_1 -} // namespace sensors -} // namespace hardware -} // namespace android diff --git a/hidl/sensors/2.1/HalProxyCallback.cpp b/hidl/sensors/2.1/HalProxyCallback.cpp deleted file mode 100644 index 3c1b17c8..00000000 --- a/hidl/sensors/2.1/HalProxyCallback.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2019 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 "HalProxyCallback.h" - -#include - -namespace android { -namespace hardware { -namespace sensors { -namespace V2_0 { -namespace implementation { - -static constexpr int32_t kBitsAfterSubHalIndex = 24; - -/** - * Set the subhal index as first byte of sensor handle and return this modified version. - * - * @param sensorHandle The sensor handle to modify. - * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to. - * - * @return The modified sensor handle. - */ -int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) { - return sensorHandle | (static_cast(subHalIndex) << kBitsAfterSubHalIndex); -} - -void HalProxyCallbackBase::postEvents(const std::vector& events, - ScopedWakelock wakelock) { - if (events.empty() || !mCallback->areThreadsRunning()) return; - size_t numWakeupEvents; - std::vector processedEvents = processEvents(events, &numWakeupEvents); - if (numWakeupEvents > 0) { - ALOG_ASSERT(wakelock.isLocked(), - "Wakeup events posted while wakelock unlocked for subhal" - " w/ index %" PRId32 ".", - mSubHalIndex); - } else { - ALOG_ASSERT(!wakelock.isLocked(), - "No Wakeup events posted but wakelock locked for subhal" - " w/ index %" PRId32 ".", - mSubHalIndex); - } - mCallback->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock)); -} - -ScopedWakelock HalProxyCallbackBase::createScopedWakelock(bool lock) { - ScopedWakelock wakelock(mRefCounter, lock); - return wakelock; -} - -std::vector HalProxyCallbackBase::processEvents(const std::vector& events, - size_t* numWakeupEvents) const { - *numWakeupEvents = 0; - std::vector eventsOut; - for (V2_1::Event event : events) { - event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex); - eventsOut.push_back(event); - const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle); - if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) { - (*numWakeupEvents)++; - } - } - return eventsOut; -} - -} // namespace implementation -} // namespace V2_0 -} // namespace sensors -} // namespace hardware -} // namespace android diff --git a/hidl/sensors/2.1/android.hardware.sensors@2.1-samsung-multihal.xml b/hidl/sensors/2.1/android.hardware.sensors@2.1-samsung-multihal.xml deleted file mode 100644 index fd2f78ac..00000000 --- a/hidl/sensors/2.1/android.hardware.sensors@2.1-samsung-multihal.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - android.hardware.sensors - hwbinder - 2.1 - - ISensors - default - - - diff --git a/hidl/sensors/2.1/android.hardware.sensors@2.1-service.samsung-multihal.rc b/hidl/sensors/2.1/android.hardware.sensors@2.1-service.samsung-multihal.rc deleted file mode 100644 index be609b24..00000000 --- a/hidl/sensors/2.1/android.hardware.sensors@2.1-service.samsung-multihal.rc +++ /dev/null @@ -1,7 +0,0 @@ -service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.samsung-multihal - class hal - user system - group system wakelock context_hub input - writepid /dev/cpuset/system-background/tasks - capabilities BLOCK_SUSPEND - rlimit rtprio 10 10 diff --git a/hidl/sensors/2.1/service.cpp b/hidl/sensors/2.1/service.cpp deleted file mode 100644 index d68d9a3e..00000000 --- a/hidl/sensors/2.1/service.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020 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 -#include -#include -#include -#include "HalProxy.h" - -using android::hardware::configureRpcThreadpool; -using android::hardware::joinRpcThreadpool; -using android::hardware::sensors::V2_1::ISensors; -using android::hardware::sensors::V2_1::implementation::HalProxyV2_1; - -int main(int /* argc */, char** /* argv */) { - configureRpcThreadpool(1, true); - - android::sp halProxy = new HalProxyV2_1(); - if (halProxy->registerAsService() != ::android::OK) { - ALOGE("Failed to register Sensors HAL instance"); - return -1; - } - - joinRpcThreadpool(); - return 1; // joinRpcThreadpool shouldn't exit -}