summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/sensor/ISensorServer.cpp28
-rw-r--r--libs/sensor/SensorManager.cpp16
-rw-r--r--libs/sensor/include/sensor/ISensorServer.h2
-rw-r--r--libs/sensor/include/sensor/SensorManager.h2
-rw-r--r--services/sensorservice/SensorDevice.cpp64
-rw-r--r--services/sensorservice/SensorDevice.h9
-rw-r--r--services/sensorservice/SensorService.cpp56
-rw-r--r--services/sensorservice/SensorService.h9
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;
}