Native runtime sensors direct connection support.
When a direct channel is (un-)registered or configured, notify the
runtime sensor callback instead of the HAL and pass the shared memory
region to it. The SensorDirectConnection object is tied to a deviceId
and may only be configured for sensors of that device.
Only ashmem direct channel type is supported for runtime sensors.
Bug: 266042170
Test: atest CtsSensorTestCases
Change-Id: Ie1a628650bd94b6d81e95d3b9f8f25fcf445666c
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 3a0329c..0fb3cad 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -181,7 +181,7 @@
handle, sensor.type, sensor.name);
sp<RuntimeSensor::SensorCallback> runtimeSensorCallback(
- new RuntimeSensorCallbackProxy(std::move(callback)));
+ new RuntimeSensorCallbackProxy(callback));
sensor_t runtimeSensor = sensor;
// force the handle to be consistent
runtimeSensor.handle = handle;
@@ -193,11 +193,15 @@
return mSensors.getNonSensor().getHandle();
}
+ if (mRuntimeSensorCallbacks.find(deviceId) == mRuntimeSensorCallbacks.end()) {
+ mRuntimeSensorCallbacks.emplace(deviceId, callback);
+ }
return handle;
}
status_t SensorService::unregisterRuntimeSensor(int handle) {
ALOGI("Unregistering runtime sensor handle 0x%x disconnected", handle);
+ int deviceId = getDeviceIdFromHandle(handle);
{
Mutex::Autolock _l(mLock);
if (!unregisterDynamicSensorLocked(handle)) {
@@ -210,6 +214,20 @@
for (const sp<SensorEventConnection>& connection : connLock.getActiveConnections()) {
connection->removeSensor(handle);
}
+
+ // If this was the last sensor for this device, remove its callback.
+ bool deviceHasSensors = false;
+ mSensors.forEachEntry(
+ [&deviceId, &deviceHasSensors] (const SensorServiceUtil::SensorList::Entry& e) -> bool {
+ if (e.deviceId == deviceId) {
+ deviceHasSensors = true;
+ return false; // stop iterating
+ }
+ return true;
+ });
+ if (!deviceHasSensors) {
+ mRuntimeSensorCallbacks.erase(deviceId);
+ }
return OK;
}
@@ -1517,7 +1535,7 @@
}
sp<ISensorEventConnection> SensorService::createSensorDirectConnection(
- const String16& opPackageName, uint32_t size, int32_t type, int32_t format,
+ const String16& opPackageName, int deviceId, uint32_t size, int32_t type, int32_t format,
const native_handle *resource) {
resetTargetSdkVersionCache(opPackageName);
ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
@@ -1593,14 +1611,25 @@
native_handle_set_fdsan_tag(clone);
sp<SensorDirectConnection> conn;
- SensorDevice& dev(SensorDevice::getInstance());
- int channelHandle = dev.registerDirectChannel(&mem);
+ int channelHandle = 0;
+ if (deviceId == RuntimeSensor::DEFAULT_DEVICE_ID) {
+ SensorDevice& dev(SensorDevice::getInstance());
+ channelHandle = dev.registerDirectChannel(&mem);
+ } else {
+ auto runtimeSensorCallback = mRuntimeSensorCallbacks.find(deviceId);
+ if (runtimeSensorCallback == mRuntimeSensorCallbacks.end()) {
+ ALOGE("Runtime sensor callback for deviceId %d not found", deviceId);
+ } else {
+ int fd = dup(clone->data[0]);
+ channelHandle = runtimeSensorCallback->second->onDirectChannelCreated(fd);
+ }
+ }
if (channelHandle <= 0) {
ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle);
} else {
mem.handle = clone;
- conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName);
+ conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName, deviceId);
}
if (conn == nullptr) {
@@ -1614,6 +1643,24 @@
return conn;
}
+int SensorService::configureRuntimeSensorDirectChannel(
+ int sensorHandle, const SensorDirectConnection* c, const sensors_direct_cfg_t* config) {
+ int deviceId = c->getDeviceId();
+ int sensorDeviceId = getDeviceIdFromHandle(sensorHandle);
+ if (sensorDeviceId != c->getDeviceId()) {
+ ALOGE("Cannot configure direct channel created for device %d with a sensor that belongs"
+ "to device %d", c->getDeviceId(), sensorDeviceId);
+ return BAD_VALUE;
+ }
+ auto runtimeSensorCallback = mRuntimeSensorCallbacks.find(deviceId);
+ if (runtimeSensorCallback == mRuntimeSensorCallbacks.end()) {
+ ALOGE("Runtime sensor callback for deviceId %d not found", deviceId);
+ return BAD_VALUE;
+ }
+ return runtimeSensorCallback->second->onDirectChannelConfigured(
+ c->getHalChannelHandle(), sensorHandle, config->rate_level);
+}
+
int SensorService::setOperationParameter(
int32_t handle, int32_t type,
const Vector<float> &floats, const Vector<int32_t> &ints) {
@@ -1769,8 +1816,18 @@
void SensorService::cleanupConnection(SensorDirectConnection* c) {
Mutex::Autolock _l(mLock);
- SensorDevice& dev(SensorDevice::getInstance());
- dev.unregisterDirectChannel(c->getHalChannelHandle());
+ int deviceId = c->getDeviceId();
+ if (deviceId == RuntimeSensor::DEFAULT_DEVICE_ID) {
+ SensorDevice& dev(SensorDevice::getInstance());
+ dev.unregisterDirectChannel(c->getHalChannelHandle());
+ } else {
+ auto runtimeSensorCallback = mRuntimeSensorCallbacks.find(deviceId);
+ if (runtimeSensorCallback != mRuntimeSensorCallbacks.end()) {
+ runtimeSensorCallback->second->onDirectChannelDestroyed(c->getHalChannelHandle());
+ } else {
+ ALOGE("Runtime sensor callback for deviceId %d not found", deviceId);
+ }
+ }
mConnectionHolder.removeDirectConnection(c);
}
@@ -1848,6 +1905,19 @@
return mSensors.getInterface(handle);
}
+int SensorService::getDeviceIdFromHandle(int handle) const {
+ int deviceId = RuntimeSensor::DEFAULT_DEVICE_ID;
+ mSensors.forEachEntry(
+ [&deviceId, handle] (const SensorServiceUtil::SensorList::Entry& e) -> bool {
+ if (e.si->getSensor().getHandle() == handle) {
+ deviceId = e.deviceId;
+ return false; // stop iterating
+ }
+ return true;
+ });
+ return deviceId;
+}
+
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName) {