diff options
-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; } |