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/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
index e2aac8c..019d6cb 100644
--- a/libs/sensor/ISensorServer.cpp
+++ b/libs/sensor/ISensorServer.cpp
@@ -139,10 +139,12 @@
}
virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
- uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) {
+ int deviceId, uint32_t size, int32_t type, int32_t format,
+ const native_handle_t *resource) {
Parcel data, reply;
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
data.writeString16(opPackageName);
+ data.writeInt32(deviceId);
data.writeUint32(size);
data.writeInt32(type);
data.writeInt32(format);
@@ -237,6 +239,7 @@
case CREATE_SENSOR_DIRECT_CONNECTION: {
CHECK_INTERFACE(ISensorServer, data, reply);
const String16& opPackageName = data.readString16();
+ const int deviceId = data.readInt32();
uint32_t size = data.readUint32();
int32_t type = data.readInt32();
int32_t format = data.readInt32();
@@ -246,8 +249,8 @@
return BAD_VALUE;
}
native_handle_set_fdsan_tag(resource);
- sp<ISensorEventConnection> ch =
- createSensorDirectConnection(opPackageName, size, type, format, resource);
+ sp<ISensorEventConnection> ch = createSensorDirectConnection(
+ opPackageName, deviceId, size, type, format, resource);
native_handle_close_with_tag(resource);
native_handle_delete(resource);
reply->writeStrongBinder(IInterface::asBinder(ch));
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 44a208d..ba190e0 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -315,6 +315,12 @@
int SensorManager::createDirectChannel(
size_t size, int channelType, const native_handle_t *resourceHandle) {
+ static constexpr int DEFAULT_DEVICE_ID = 0;
+ return createDirectChannel(DEFAULT_DEVICE_ID, size, channelType, resourceHandle);
+}
+
+int SensorManager::createDirectChannel(
+ int deviceId, size_t size, int channelType, const native_handle_t *resourceHandle) {
Mutex::Autolock _l(mLock);
if (assertStateLocked() != NO_ERROR) {
return NO_INIT;
@@ -327,7 +333,7 @@
}
sp<ISensorEventConnection> conn =
- mSensorServer->createSensorDirectConnection(mOpPackageName,
+ mSensorServer->createSensorDirectConnection(mOpPackageName, deviceId,
static_cast<uint32_t>(size),
static_cast<int32_t>(channelType),
SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle);
diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
index 3295196..5815728 100644
--- a/libs/sensor/include/sensor/ISensorServer.h
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -50,7 +50,8 @@
virtual int32_t isDataInjectionEnabled() = 0;
virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
- uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;
+ int deviceId, uint32_t size, int32_t type, int32_t format,
+ const native_handle_t *resource) = 0;
virtual int setOperationParameter(
int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index c31f648..bb44cb8 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -66,6 +66,8 @@
String8 packageName = String8(""), int mode = 0, String16 attributionTag = String16(""));
bool isDataInjectionEnabled();
int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
+ int createDirectChannel(
+ int deviceId, size_t size, int channelType, const native_handle_t *channelData);
void destroyDirectChannel(int channelNativeHandle);
int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
int setOperationParameter(int handle, int type, const Vector<float> &floats, const Vector<int32_t> &ints);
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 4ac9651..4fff8bb 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -28,10 +28,10 @@
SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorService>& service,
uid_t uid, const sensors_direct_mem_t *mem, int32_t halChannelHandle,
- const String16& opPackageName)
+ const String16& opPackageName, int deviceId)
: mService(service), mUid(uid), mMem(*mem),
mHalChannelHandle(halChannelHandle),
- mOpPackageName(opPackageName), mDestroyed(false) {
+ mOpPackageName(opPackageName), mDeviceId(deviceId), mDestroyed(false) {
mUserId = multiuser_get_user_id(mUid);
ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
}
@@ -180,8 +180,7 @@
};
Mutex::Autolock _l(mConnectionLock);
- SensorDevice& dev(SensorDevice::getInstance());
- int ret = dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
+ int ret = configure(handle, &config);
if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
if (ret == NO_ERROR) {
@@ -224,7 +223,6 @@
std::unordered_map<int, int>& existingConnections =
(!temporarilyStopped) ? mActivated : mActivatedBackup;
- SensorDevice& dev(SensorDevice::getInstance());
for (auto &i : existingConnections) {
int handle = i.first;
int rateLevel = i.second;
@@ -239,8 +237,8 @@
// Only reconfigure the channel if it's ongoing
if (!temporarilyStopped) {
// Stopping before reconfiguring is the well-tested path in CTS
- dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
- dev.configureDirectChannel(handle, getHalChannelHandle(), &capConfig);
+ configure(handle, &stopConfig);
+ configure(handle, &capConfig);
}
}
}
@@ -258,7 +256,6 @@
const struct sensors_direct_cfg_t stopConfig = {
.rate_level = SENSOR_DIRECT_RATE_STOP
};
- SensorDevice& dev(SensorDevice::getInstance());
for (auto &i : mMicRateBackup) {
int handle = i.first;
int rateLevel = i.second;
@@ -273,13 +270,23 @@
// Only reconfigure the channel if it's ongoing
if (!temporarilyStopped) {
// Stopping before reconfiguring is the well-tested path in CTS
- dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
- dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
+ configure(handle, &stopConfig);
+ configure(handle, &config);
}
}
mMicRateBackup.clear();
}
+int SensorService::SensorDirectConnection::configure(
+ int handle, const sensors_direct_cfg_t* config) {
+ if (mDeviceId == RuntimeSensor::DEFAULT_DEVICE_ID) {
+ SensorDevice& dev(SensorDevice::getInstance());
+ return dev.configureDirectChannel(handle, getHalChannelHandle(), config);
+ } else {
+ return mService->configureRuntimeSensorDirectChannel(handle, this, config);
+ }
+}
+
void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
Mutex::Autolock _l(mConnectionLock);
stopAllLocked(backupRecord);
@@ -290,9 +297,8 @@
.rate_level = SENSOR_DIRECT_RATE_STOP
};
- SensorDevice& dev(SensorDevice::getInstance());
for (auto &i : mActivated) {
- dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ configure(i.first, &config);
}
if (backupRecord && mActivatedBackup.empty()) {
@@ -306,8 +312,6 @@
if (!mActivatedBackup.empty()) {
stopAllLocked(false);
- SensorDevice& dev(SensorDevice::getInstance());
-
// recover list of report from backup
ALOG_ASSERT(mActivated.empty(),
"mActivated must be empty if mActivatedBackup was non-empty");
@@ -319,7 +323,7 @@
struct sensors_direct_cfg_t config = {
.rate_level = i.second
};
- dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ configure(i.first, &config);
}
}
}
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index d39a073..bfaf811 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -39,7 +39,7 @@
public:
SensorDirectConnection(const sp<SensorService>& service, uid_t uid,
const sensors_direct_mem_t *mem, int32_t halChannelHandle,
- const String16& opPackageName);
+ const String16& opPackageName, int deviceId);
void dump(String8& result) const;
void dump(util::ProtoOutputStream* proto) const;
uid_t getUid() const { return mUid; }
@@ -53,6 +53,7 @@
void onSensorAccessChanged(bool hasAccess);
void onMicSensorAccessChanged(bool isMicToggleOn);
userid_t getUserId() const { return mUserId; }
+ int getDeviceId() const { return mDeviceId; }
protected:
virtual ~SensorDirectConnection();
@@ -68,6 +69,9 @@
private:
bool hasSensorAccess() const;
+ // Sends the configuration to the relevant sensor device.
+ int configure(int handle, const sensors_direct_cfg_t* config);
+
// Stops all active sensor direct report requests.
//
// If backupRecord is true, stopped requests can be recovered
@@ -95,6 +99,7 @@
const sensors_direct_mem_t mMem;
const int32_t mHalChannelHandle;
const String16 mOpPackageName;
+ const int mDeviceId;
mutable Mutex mConnectionLock;
std::unordered_map<int, int> mActivated;
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) {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 3f6a895..fe72a69 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -154,6 +154,10 @@
virtual status_t onConfigurationChanged(int handle, bool enabled,
int64_t samplingPeriodNanos,
int64_t batchReportLatencyNanos) = 0;
+ virtual int onDirectChannelCreated(int fd) = 0;
+ virtual void onDirectChannelDestroyed(int channelHandle) = 0;
+ virtual int onDirectChannelConfigured(int channelHandle, int sensorHandle,
+ int rateLevel) = 0;
};
static char const* getServiceName() ANDROID_API { return "sensorservice"; }
@@ -187,6 +191,9 @@
status_t unregisterRuntimeSensor(int handle) ANDROID_API;
status_t sendRuntimeSensorEvent(const sensors_event_t& event) ANDROID_API;
+ int configureRuntimeSensorDirectChannel(int sensorHandle, const SensorDirectConnection* c,
+ const sensors_direct_cfg_t* config);
+
// Returns true if a sensor should be throttled according to our rate-throttling rules.
static bool isSensorInCappedSet(int sensorType);
@@ -370,7 +377,8 @@
int requestedMode, const String16& opPackageName, const String16& attributionTag);
virtual int isDataInjectionEnabled();
virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
- uint32_t size, int32_t type, int32_t format, const native_handle *resource);
+ int deviceId, uint32_t size, int32_t type, int32_t format,
+ const native_handle *resource);
virtual int setOperationParameter(
int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -380,6 +388,7 @@
String8 getSensorStringType(int handle) const;
bool isVirtualSensor(int handle) const;
std::shared_ptr<SensorInterface> getSensorInterfaceFromHandle(int handle) const;
+ int getDeviceIdFromHandle(int handle) const;
bool isWakeUpSensor(int type) const;
void recordLastValueLocked(sensors_event_t const* buffer, size_t count);
static void sortEventBuffer(sensors_event_t* buffer, size_t count);
@@ -517,6 +526,7 @@
std::unordered_map<int, SensorServiceUtil::RecentEventLogger*> mRecentEvent;
Mode mCurrentOperatingMode;
std::queue<sensors_event_t> mRuntimeSensorEventQueue;
+ std::unordered_map</*deviceId*/int, sp<RuntimeSensorCallback>> mRuntimeSensorCallbacks;
// true if the head tracker sensor type is currently restricted to system usage only
// (can only be unrestricted for testing, via shell cmd)