diff options
author | 2023-07-07 20:07:18 +0000 | |
---|---|---|
committer | 2023-10-11 18:37:10 +0000 | |
commit | 8f285d987a63ecb3c132b06a14bd5bf63aa72fd8 (patch) | |
tree | fd46103eed8fbbdd199f08807bf8a07056307c4d | |
parent | ca7ea7b97a4b99b964e9e5f8245ab81e92bd9524 (diff) |
Add HAL Bypass Data Injection mode to Sensor Service
Add a new mode, HAL_BYPASS_REPLAY_DATA_INJECTION, which behaves similar
to Replay Data Injection with the difference that injected sensor data
is not injected into the HAL but simply passed back up to clients in
the platform.
Also, while I was in there, hook up the remaining bits and bobs to get
Replay Data Injection working and accessible from APIs in
SystemSensorManager in the platform.
Bug: 287257057
Test: manual
Change-Id: I9fc33a8bf5b67c02483089f849ba7ff0346d8097
(cherry picked from commit b0df44e2a6a40fb70a6e98a1e4e629945995a5f6)
-rw-r--r-- | libs/sensor/ISensorServer.cpp | 28 | ||||
-rw-r--r-- | libs/sensor/SensorManager.cpp | 16 | ||||
-rw-r--r-- | libs/sensor/include/sensor/ISensorServer.h | 2 | ||||
-rw-r--r-- | libs/sensor/include/sensor/SensorManager.h | 2 | ||||
-rw-r--r-- | services/sensorservice/SensorDevice.cpp | 64 | ||||
-rw-r--r-- | services/sensorservice/SensorDevice.h | 9 | ||||
-rw-r--r-- | services/sensorservice/SensorService.cpp | 56 | ||||
-rw-r--r-- | services/sensorservice/SensorService.h | 9 |
8 files changed, 168 insertions, 18 deletions
diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp index 634d35a5b8..12f600e97e 100644 --- a/libs/sensor/ISensorServer.cpp +++ b/libs/sensor/ISensorServer.cpp @@ -43,6 +43,8 @@ enum { CREATE_SENSOR_DIRECT_CONNECTION, SET_OPERATION_PARAMETER, GET_RUNTIME_SENSOR_LIST, + ENABLE_REPLAY_DATA_INJECTION, + ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION, }; class BpSensorServer : public BpInterface<ISensorServer> @@ -162,6 +164,20 @@ public: return reply.readInt32(); } + virtual int isReplayDataInjectionEnabled() { + Parcel data, reply; + data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + remote()->transact(ENABLE_REPLAY_DATA_INJECTION, data, &reply); + return reply.readInt32(); + } + + virtual int isHalBypassReplayDataInjectionEnabled() { + Parcel data, reply; + data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + remote()->transact(ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION, data, &reply); + return reply.readInt32(); + } + virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, int deviceId, uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) { @@ -237,6 +253,18 @@ status_t BnSensorServer::onTransact( reply->writeInt32(static_cast<int32_t>(ret)); return NO_ERROR; } + case ENABLE_REPLAY_DATA_INJECTION: { + CHECK_INTERFACE(ISensorServer, data, reply); + int32_t ret = isReplayDataInjectionEnabled(); + reply->writeInt32(static_cast<int32_t>(ret)); + return NO_ERROR; + } + case ENABLE_HAL_BYPASS_REPLAY_DATA_INJECTION: { + CHECK_INTERFACE(ISensorServer, data, reply); + int32_t ret = isHalBypassReplayDataInjectionEnabled(); + reply->writeInt32(static_cast<int32_t>(ret)); + return NO_ERROR; + } case GET_DYNAMIC_SENSOR_LIST: { CHECK_INTERFACE(ISensorServer, data, reply); const String16& opPackageName = data.readString16(); diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp index 980f8d16d2..3ed8c8ac26 100644 --- a/libs/sensor/SensorManager.cpp +++ b/libs/sensor/SensorManager.cpp @@ -310,6 +310,22 @@ bool SensorManager::isDataInjectionEnabled() { return false; } +bool SensorManager::isReplayDataInjectionEnabled() { + Mutex::Autolock _l(mLock); + if (assertStateLocked() == NO_ERROR) { + return mSensorServer->isReplayDataInjectionEnabled(); + } + return false; +} + +bool SensorManager::isHalBypassReplayDataInjectionEnabled() { + Mutex::Autolock _l(mLock); + if (assertStateLocked() == NO_ERROR) { + return mSensorServer->isHalBypassReplayDataInjectionEnabled(); + } + return false; +} + int SensorManager::createDirectChannel( size_t size, int channelType, const native_handle_t *resourceHandle) { static constexpr int DEFAULT_DEVICE_ID = 0; diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h index 58157280b1..00bc1d68b8 100644 --- a/libs/sensor/include/sensor/ISensorServer.h +++ b/libs/sensor/include/sensor/ISensorServer.h @@ -48,6 +48,8 @@ public: virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, int mode, const String16& opPackageName, const String16& attributionTag) = 0; virtual int32_t isDataInjectionEnabled() = 0; + virtual int32_t isReplayDataInjectionEnabled() = 0; + virtual int32_t isHalBypassReplayDataInjectionEnabled() = 0; virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, int deviceId, uint32_t size, int32_t type, int32_t format, diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h index bb44cb8869..64b4501868 100644 --- a/libs/sensor/include/sensor/SensorManager.h +++ b/libs/sensor/include/sensor/SensorManager.h @@ -65,6 +65,8 @@ public: sp<SensorEventQueue> createEventQueue( String8 packageName = String8(""), int mode = 0, String16 attributionTag = String16("")); bool isDataInjectionEnabled(); + bool isReplayDataInjectionEnabled(); + bool isHalBypassReplayDataInjectionEnabled(); 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); diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp index 3155b4ceaf..c86022e748 100644 --- a/services/sensorservice/SensorDevice.cpp +++ b/services/sensorservice/SensorDevice.cpp @@ -37,6 +37,8 @@ #include <cinttypes> #include <cstddef> #include <thread> +#include <mutex> +#include <condition_variable> using namespace android::hardware::sensors; using android::util::ProtoOutputStream; @@ -352,13 +354,17 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { if (mHalWrapper == nullptr) return NO_INIT; ssize_t eventsRead = 0; - if (mHalWrapper->supportsMessageQueues()) { - eventsRead = mHalWrapper->pollFmq(buffer, count); - } else if (mHalWrapper->supportsPolling()) { - eventsRead = mHalWrapper->poll(buffer, count); + if (mInHalBypassMode) [[unlikely]] { + eventsRead = getHalBypassInjectedEvents(buffer, count); } else { - ALOGE("Must support polling or FMQ"); - eventsRead = -1; + if (mHalWrapper->supportsMessageQueues()) { + eventsRead = mHalWrapper->pollFmq(buffer, count); + } else if (mHalWrapper->supportsPolling()) { + eventsRead = mHalWrapper->poll(buffer, count); + } else { + ALOGE("Must support polling or FMQ"); + eventsRead = -1; + } } if (eventsRead > 0) { @@ -762,11 +768,38 @@ status_t SensorDevice::injectSensorData(const sensors_event_t* injected_sensor_e injected_sensor_event->data[2], injected_sensor_event->data[3], injected_sensor_event->data[4], injected_sensor_event->data[5]); + if (mInHalBypassMode) { + std::lock_guard _l(mHalBypassLock); + mHalBypassInjectedEventQueue.push(*injected_sensor_event); + mHalBypassCV.notify_one(); + return OK; + } return mHalWrapper->injectSensorData(injected_sensor_event); } status_t SensorDevice::setMode(uint32_t mode) { if (mHalWrapper == nullptr) return NO_INIT; + if (mode == SensorService::Mode::HAL_BYPASS_REPLAY_DATA_INJECTION) { + if (!mInHalBypassMode) { + std::lock_guard _l(mHalBypassLock); + while (!mHalBypassInjectedEventQueue.empty()) { + // flush any stale events from the injected event queue + mHalBypassInjectedEventQueue.pop(); + } + mInHalBypassMode = true; + } + return OK; + } else { + if (mInHalBypassMode) { + // We are transitioning out of HAL Bypass mode. We need to notify the reader thread + // (specifically getHalBypassInjectedEvents()) of this change in state so that it is not + // stuck waiting on more injected events to come and therefore preventing events coming + // from the HAL from being read. + std::lock_guard _l(mHalBypassLock); + mInHalBypassMode = false; + mHalBypassCV.notify_one(); + } + } return mHalWrapper->setOperationMode(static_cast<SensorService::Mode>(mode)); } @@ -872,5 +905,24 @@ float SensorDevice::getResolutionForSensor(int sensorHandle) { return 0; } +ssize_t SensorDevice::getHalBypassInjectedEvents(sensors_event_t* buffer, + size_t maxNumEventsToRead) { + std::unique_lock _l(mHalBypassLock); + if (mHalBypassInjectedEventQueue.empty()) { + // if the injected event queue is empty, block and wait till there are events to process + // or if we are no longer in HAL Bypass mode so that this method is not called in a tight + // loop. Otherwise, continue copying the injected events into the supplied buffer. + mHalBypassCV.wait(_l, [this] { + return (!mHalBypassInjectedEventQueue.empty() || !mInHalBypassMode); + }); + } + size_t eventsToRead = std::min(mHalBypassInjectedEventQueue.size(), maxNumEventsToRead); + for (size_t i = 0; i < eventsToRead; i++) { + buffer[i] = mHalBypassInjectedEventQueue.front(); + mHalBypassInjectedEventQueue.pop(); + } + return eventsToRead; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h index 747a6b0926..f127c0f8cd 100644 --- a/services/sensorservice/SensorDevice.h +++ b/services/sensorservice/SensorDevice.h @@ -35,6 +35,9 @@ #include <utils/Timers.h> #include <algorithm> //std::max std::min +#include <condition_variable> +#include <mutex> +#include <queue> #include <string> #include <unordered_map> #include <vector> @@ -225,6 +228,12 @@ private: float getResolutionForSensor(int sensorHandle); bool mIsDirectReportSupported; + + std::mutex mHalBypassLock; + std::condition_variable mHalBypassCV; + std::queue<sensors_event_t> mHalBypassInjectedEventQueue; + ssize_t getHalBypassInjectedEvents(sensors_event_t* buffer, size_t count); + bool mInHalBypassMode; }; // --------------------------------------------------------------------------- diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 9c51fd9586..44d0d708e0 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -665,6 +665,10 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { result.appendFormat(" REPLAY_DATA_INJECTION : %s\n", mAllowListedPackage.c_str()); break; + case HAL_BYPASS_REPLAY_DATA_INJECTION: + result.appendFormat(" HAL_BYPASS_REPLAY_DATA_INJECTION : %s\n", + mAllowListedPackage.c_str()); + break; default: result.appendFormat(" UNKNOWN\n"); break; @@ -1529,10 +1533,9 @@ Vector<Sensor> SensorService::getRuntimeSensorList(const String16& opPackageName sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, int requestedMode, const String16& opPackageName, const String16& attributionTag) { - // Only 3 modes supported for a SensorEventConnection ... NORMAL, DATA_INJECTION and - // REPLAY_DATA_INJECTION. - if (requestedMode != NORMAL && requestedMode != DATA_INJECTION && - requestedMode != REPLAY_DATA_INJECTION) { + // Only 4 modes supported for a SensorEventConnection ... NORMAL, DATA_INJECTION, + // REPLAY_DATA_INJECTION and HAL_BYPASS_REPLAY_DATA_INJECTION + if (requestedMode != NORMAL && !isInjectionMode(requestedMode)) { return nullptr; } resetTargetSdkVersionCache(opPackageName); @@ -1553,9 +1556,9 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri String16 connOpPackageName = (opPackageName == String16("")) ? String16(connPackageName) : opPackageName; sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName, - requestedMode == DATA_INJECTION || requestedMode == REPLAY_DATA_INJECTION, - connOpPackageName, attributionTag)); - if (requestedMode == DATA_INJECTION || requestedMode == REPLAY_DATA_INJECTION) { + isInjectionMode(requestedMode), + connOpPackageName, attributionTag)); + if (isInjectionMode(requestedMode)) { mConnectionHolder.addEventConnectionIfNotPresent(result); // Add the associated file descriptor to the Looper for polling whenever there is data to // be injected. @@ -1566,7 +1569,22 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri int SensorService::isDataInjectionEnabled() { Mutex::Autolock _l(mLock); - return (mCurrentOperatingMode == DATA_INJECTION); + return mCurrentOperatingMode == DATA_INJECTION; +} + +int SensorService::isReplayDataInjectionEnabled() { + Mutex::Autolock _l(mLock); + return mCurrentOperatingMode == REPLAY_DATA_INJECTION; +} + +int SensorService::isHalBypassReplayDataInjectionEnabled() { + Mutex::Autolock _l(mLock); + return mCurrentOperatingMode == HAL_BYPASS_REPLAY_DATA_INJECTION; +} + +bool SensorService::isInjectionMode(int mode) { + return (mode == DATA_INJECTION || mode == REPLAY_DATA_INJECTION || + mode == HAL_BYPASS_REPLAY_DATA_INJECTION); } sp<ISensorEventConnection> SensorService::createSensorDirectConnection( @@ -2332,6 +2350,10 @@ bool SensorService::getTargetOperatingMode(const std::string &inputString, Mode *targetModeOut = REPLAY_DATA_INJECTION; return true; } + if (inputString == std::string("hal_bypass_replay_data_injection")) { + *targetModeOut = HAL_BYPASS_REPLAY_DATA_INJECTION; + return true; + } return false; } @@ -2357,7 +2379,8 @@ status_t SensorService::changeOperatingMode(const Vector<String16>& args, dev.disableAllSensors(); } if (mCurrentOperatingMode == DATA_INJECTION || - mCurrentOperatingMode == REPLAY_DATA_INJECTION) { + mCurrentOperatingMode == REPLAY_DATA_INJECTION || + mCurrentOperatingMode == HAL_BYPASS_REPLAY_DATA_INJECTION) { resetToNormalModeLocked(); } mAllowListedPackage.clear(); @@ -2373,6 +2396,8 @@ status_t SensorService::changeOperatingMode(const Vector<String16>& args, disableAllSensorsLocked(&connLock); mAllowListedPackage = String8(args[1]); return status_t(NO_ERROR); + case HAL_BYPASS_REPLAY_DATA_INJECTION: + FALLTHROUGH_INTENDED; case REPLAY_DATA_INJECTION: if (SensorServiceUtil::isUserBuild()) { return INVALID_OPERATION; @@ -2381,9 +2406,16 @@ status_t SensorService::changeOperatingMode(const Vector<String16>& args, case DATA_INJECTION: if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); - // Always use DATA_INJECTION here since this value goes to the HAL and the HAL - // doesn't have an understanding of replay vs. normal data injection. - status_t err = dev.setMode(DATA_INJECTION); + status_t err = NO_ERROR; + if (targetOperatingMode == HAL_BYPASS_REPLAY_DATA_INJECTION) { + // Set SensorDevice to HAL_BYPASS_REPLAY_DATA_INJECTION_MODE. This value is not + // injected into the HAL, nor will any events be injected into the HAL + err = dev.setMode(HAL_BYPASS_REPLAY_DATA_INJECTION); + } else { + // Otherwise use DATA_INJECTION here since this value goes to the HAL and the HAL + // doesn't have an understanding of replay vs. normal data injection. + err = dev.setMode(DATA_INJECTION); + } if (err == NO_ERROR) { mCurrentOperatingMode = targetOperatingMode; } diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index bf4310119d..b643f6b382 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -122,6 +122,11 @@ public: // delivered to all requesting apps rather than just the package allowed to inject data. // This mode is only allowed to be used on development builds. REPLAY_DATA_INJECTION = 3, + // Like REPLAY_DATA_INJECTION but injected data is not sent into the HAL. It is stored in a + // buffer in SensorDevice and played back to SensorService when SensorDevice::poll() is + // called. This is useful for playing back sensor data on the platform without relying on + // the HAL to support data injection. + HAL_BYPASS_REPLAY_DATA_INJECTION = 4, // State Transitions supported. // RESTRICTED <--- NORMAL ---> DATA_INJECTION/REPLAY_DATA_INJECTION @@ -389,6 +394,8 @@ private: const String8& packageName, int requestedMode, const String16& opPackageName, const String16& attributionTag); virtual int isDataInjectionEnabled(); + virtual int isReplayDataInjectionEnabled(); + virtual int isHalBypassReplayDataInjectionEnabled(); virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName, int deviceId, uint32_t size, int32_t type, int32_t format, const native_handle *resource); @@ -507,6 +514,8 @@ private: // Removes the capped rate on active direct connections (when the mic toggle is flipped to off) void uncapRates(); + bool isInjectionMode(int mode); + static inline bool isAudioServerOrSystemServerUid(uid_t uid) { return multiuser_get_app_id(uid) == AID_SYSTEM || uid == AID_AUDIOSERVER; } |