Merge "Enable data injection mode in SensorService."
This commit is contained in:
commit
cc60dc2128
@ -38,7 +38,9 @@ public:
|
||||
DECLARE_META_INTERFACE(SensorServer);
|
||||
|
||||
virtual Vector<Sensor> getSensorList() = 0;
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName) = 0;
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
|
||||
int mode) = 0;
|
||||
virtual status_t enableDataInjection(int enable) = 0;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
status_t flush() const;
|
||||
// Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK.
|
||||
void sendAck(const ASensorEvent* events, int count);
|
||||
|
||||
status_t injectSensorEvent(const ASensorEvent& event);
|
||||
private:
|
||||
sp<Looper> getLooper() const;
|
||||
sp<ISensorEventConnection> mSensorEventConnection;
|
||||
|
@ -53,7 +53,8 @@ public:
|
||||
|
||||
ssize_t getSensorList(Sensor const* const** list) const;
|
||||
Sensor const* getDefaultSensor(int type);
|
||||
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""));
|
||||
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
|
||||
ssize_t enableDataInjection(bool enable);
|
||||
|
||||
private:
|
||||
// DeathRecipient interface
|
||||
|
@ -35,6 +35,7 @@ namespace android {
|
||||
enum {
|
||||
GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
|
||||
CREATE_SENSOR_EVENT_CONNECTION,
|
||||
ENABLE_DATA_INJECTION
|
||||
};
|
||||
|
||||
class BpSensorServer : public BpInterface<ISensorServer>
|
||||
@ -63,14 +64,24 @@ public:
|
||||
return v;
|
||||
}
|
||||
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
|
||||
int mode)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
||||
data.writeString8(packageName);
|
||||
data.writeInt32(mode);
|
||||
remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
|
||||
return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
|
||||
}
|
||||
|
||||
virtual status_t enableDataInjection(int enable) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
||||
data.writeInt32(enable);
|
||||
remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
|
||||
return reply.readInt32();
|
||||
}
|
||||
};
|
||||
|
||||
// Out-of-line virtual method definition to trigger vtable emission in this
|
||||
@ -98,10 +109,18 @@ status_t BnSensorServer::onTransact(
|
||||
case CREATE_SENSOR_EVENT_CONNECTION: {
|
||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||
String8 packageName = data.readString8();
|
||||
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName));
|
||||
int32_t mode = data.readInt32();
|
||||
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode));
|
||||
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||
return NO_ERROR;
|
||||
}
|
||||
case ENABLE_DATA_INJECTION: {
|
||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||
int32_t enable = data.readInt32();
|
||||
status_t ret = enableDataInjection(enable);
|
||||
reply->writeInt32(static_cast<int32_t>(ret));
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
@ -149,6 +149,16 @@ status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const
|
||||
return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
|
||||
}
|
||||
|
||||
status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
|
||||
// Blocking call.
|
||||
ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
|
||||
if (size < 0) {
|
||||
ALOGE("injectSensorEvent failure %zd %d", size, mSensorChannel->getFd());
|
||||
return size;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
|
||||
|
@ -100,8 +100,6 @@ status_t SensorManager::assertStateLocked() const {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssize_t SensorManager::getSensorList(Sensor const* const** list) const
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
@ -139,18 +137,17 @@ Sensor const* SensorManager::getDefaultSensor(int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
||||
{
|
||||
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
|
||||
sp<SensorEventQueue> queue;
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
while (assertStateLocked() == NO_ERROR) {
|
||||
sp<ISensorEventConnection> connection =
|
||||
mSensorServer->createSensorEventConnection(packageName);
|
||||
mSensorServer->createSensorEventConnection(packageName, mode);
|
||||
if (connection == NULL) {
|
||||
// SensorService just died.
|
||||
ALOGE("createEventQueue: connection is NULL. SensorService died.");
|
||||
continue;
|
||||
// SensorService just died or the app doesn't have required permissions.
|
||||
ALOGE("createEventQueue: connection is NULL.");
|
||||
return NULL;
|
||||
}
|
||||
queue = new SensorEventQueue(connection);
|
||||
break;
|
||||
@ -158,5 +155,13 @@ sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
||||
return queue;
|
||||
}
|
||||
|
||||
status_t SensorManager::enableDataInjection(bool enable) {
|
||||
Mutex::Autolock _l(mLock);
|
||||
if (assertStateLocked() == NO_ERROR) {
|
||||
return mSensorServer->enableDataInjection(enable);
|
||||
}
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
@ -367,7 +367,7 @@ void SensorDevice::enableAllSensors() {
|
||||
|
||||
void SensorDevice::disableAllSensors() {
|
||||
Mutex::Autolock _l(mLock);
|
||||
for (size_t i = 0; i< mActivationCount.size(); ++i) {
|
||||
for (size_t i = 0; i< mActivationCount.size(); ++i) {
|
||||
const Info& info = mActivationCount.valueAt(i);
|
||||
// Check if this sensor has been activated previously and disable it.
|
||||
if (info.batchParams.size() > 0) {
|
||||
@ -386,6 +386,27 @@ void SensorDevice::disableAllSensors() {
|
||||
}
|
||||
}
|
||||
|
||||
status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event, size_t count) {
|
||||
ALOGD_IF(DEBUG_CONNECTIONS,
|
||||
"sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
|
||||
injected_sensor_event->sensor,
|
||||
injected_sensor_event->timestamp, injected_sensor_event->data[0],
|
||||
injected_sensor_event->data[1], injected_sensor_event->data[2],
|
||||
injected_sensor_event->data[3], injected_sensor_event->data[4],
|
||||
injected_sensor_event->data[5]);
|
||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event);
|
||||
}
|
||||
|
||||
status_t SensorDevice::setMode(uint32_t mode) {
|
||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
return mSensorModule->set_operation_mode(mode);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
int SensorDevice::Info::numActiveClients() {
|
||||
|
@ -98,9 +98,11 @@ public:
|
||||
// Call batch with timeout zero instead of calling setDelay() for newer devices.
|
||||
status_t setDelay(void* ident, int handle, int64_t ns);
|
||||
status_t flush(void* ident, int handle);
|
||||
status_t setMode(uint32_t mode);
|
||||
void disableAllSensors();
|
||||
void enableAllSensors();
|
||||
void autoDisable(void *ident, int handle);
|
||||
status_t injectSensorData(const sensors_event_t *event, size_t count);
|
||||
void dump(String8& result);
|
||||
};
|
||||
|
||||
|
@ -64,6 +64,9 @@ namespace android {
|
||||
*/
|
||||
|
||||
const char* SensorService::WAKE_LOCK_NAME = "SensorService";
|
||||
// Permissions.
|
||||
static const String16 sDataInjectionPermission("android.permission.HARDWARE_TEST");
|
||||
static const String16 sDump("android.permission.DUMP");
|
||||
|
||||
SensorService::SensorService()
|
||||
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
|
||||
@ -74,7 +77,6 @@ SensorService::SensorService()
|
||||
void SensorService::onFirstRef()
|
||||
{
|
||||
ALOGD("nuSensorService starting...");
|
||||
|
||||
SensorDevice& dev(SensorDevice::getInstance());
|
||||
|
||||
if (dev.initCheck() == NO_ERROR) {
|
||||
@ -190,7 +192,7 @@ void SensorService::onFirstRef()
|
||||
mSensorEventBuffer = new sensors_event_t[minBufferSize];
|
||||
mSensorEventScratch = new sensors_event_t[minBufferSize];
|
||||
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
|
||||
mMode = NORMAL;
|
||||
mCurrentOperatingMode = NORMAL;
|
||||
|
||||
mAckReceiver = new SensorEventAckReceiver(this);
|
||||
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||
@ -229,8 +231,6 @@ SensorService::~SensorService()
|
||||
delete mSensorMap.valueAt(i);
|
||||
}
|
||||
|
||||
static const String16 sDump("android.permission.DUMP");
|
||||
|
||||
status_t SensorService::dump(int fd, const Vector<String16>& args)
|
||||
{
|
||||
String8 result;
|
||||
@ -245,8 +245,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
SensorDevice& dev(SensorDevice::getInstance());
|
||||
if (args[0] == String16("restrict") && mMode == NORMAL) {
|
||||
mMode = RESTRICTED;
|
||||
if (args[0] == String16("restrict") && mCurrentOperatingMode == NORMAL) {
|
||||
mCurrentOperatingMode = RESTRICTED;
|
||||
dev.disableAllSensors();
|
||||
// Clear all pending flush connections for all active sensors. If one of the active
|
||||
// connections has called flush() and the underlying sensor has been disabled before a
|
||||
@ -254,8 +254,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
||||
for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
|
||||
mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
|
||||
}
|
||||
} else if (args[0] == String16("enable") && mMode == RESTRICTED) {
|
||||
mMode = NORMAL;
|
||||
} else if (args[0] == String16("enable") && mCurrentOperatingMode == RESTRICTED) {
|
||||
mCurrentOperatingMode = NORMAL;
|
||||
dev.enableAllSensors();
|
||||
}
|
||||
return status_t(NO_ERROR);
|
||||
@ -363,7 +363,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
||||
mSocketBufferSize/sizeof(sensors_event_t));
|
||||
result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
|
||||
result.appendFormat("Mode :");
|
||||
switch(mMode) {
|
||||
switch(mCurrentOperatingMode) {
|
||||
case NORMAL:
|
||||
result.appendFormat(" NORMAL\n");
|
||||
break;
|
||||
@ -403,8 +403,9 @@ void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnecti
|
||||
sensor->autoDisable(connection.get(), handle);
|
||||
cleanupWithoutDisableLocked(connection, handle);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SensorService::threadLoop()
|
||||
@ -685,13 +686,76 @@ Vector<Sensor> SensorService::getSensorList()
|
||||
return accessibleSensorList;
|
||||
}
|
||||
|
||||
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName)
|
||||
{
|
||||
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
|
||||
int requestedMode) {
|
||||
// Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
|
||||
if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
|
||||
return NULL;
|
||||
}
|
||||
// DATA_INJECTION mode needs to have the required permissions set.
|
||||
if (requestedMode == DATA_INJECTION && !hasDataInjectionPermissions()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
uid_t uid = IPCThreadState::self()->getCallingUid();
|
||||
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName));
|
||||
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
|
||||
requestedMode == DATA_INJECTION));
|
||||
if (requestedMode == DATA_INJECTION) {
|
||||
if (mActiveConnections.indexOf(result) < 0) {
|
||||
mActiveConnections.add(result);
|
||||
}
|
||||
// Add the associated file descriptor to the Looper for polling whenever there is data to
|
||||
// be injected.
|
||||
result->updateLooperRegistration(mLooper);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
status_t SensorService::enableDataInjection(int requestedMode) {
|
||||
if (!hasDataInjectionPermissions()) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
ALOGD_IF(DEBUG_CONNECTIONS, "SensorService::enableDataInjection %d", requestedMode);
|
||||
SensorDevice& dev(SensorDevice::getInstance());
|
||||
status_t err(NO_ERROR);
|
||||
if (requestedMode == DATA_INJECTION) {
|
||||
if (mCurrentOperatingMode == NORMAL) {
|
||||
dev.disableAllSensors();
|
||||
err = dev.setMode(requestedMode);
|
||||
if (err == NO_ERROR) {
|
||||
mCurrentOperatingMode = DATA_INJECTION;
|
||||
} else {
|
||||
// Re-enable sensors.
|
||||
dev.enableAllSensors();
|
||||
}
|
||||
} else if (mCurrentOperatingMode == DATA_INJECTION) {
|
||||
// Already in DATA_INJECTION mode. Treat this as a no_op.
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
// Transition to data injection mode supported only from NORMAL mode.
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
} else if (requestedMode == NORMAL && mCurrentOperatingMode != NORMAL) {
|
||||
err = resetToNormalModeLocked();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t SensorService::resetToNormalMode() {
|
||||
Mutex::Autolock _l(mLock);
|
||||
return resetToNormalModeLocked();
|
||||
}
|
||||
|
||||
status_t SensorService::resetToNormalModeLocked() {
|
||||
SensorDevice& dev(SensorDevice::getInstance());
|
||||
dev.enableAllSensors();
|
||||
status_t err = dev.setMode(NORMAL);
|
||||
mCurrentOperatingMode = NORMAL;
|
||||
return err;
|
||||
}
|
||||
|
||||
void SensorService::cleanupConnection(SensorEventConnection* c)
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
@ -753,7 +817,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
||||
}
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
||||
if (mCurrentOperatingMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
@ -960,6 +1024,15 @@ bool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* oper
|
||||
}
|
||||
}
|
||||
|
||||
bool SensorService::hasDataInjectionPermissions() {
|
||||
if (!PermissionCache::checkCallingPermission(sDataInjectionPermission)) {
|
||||
ALOGE("Permission Denial trying to activate data injection without"
|
||||
" the required permission");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SensorService::checkWakeLockState() {
|
||||
Mutex::Autolock _l(mLock);
|
||||
checkWakeLockStateLocked();
|
||||
@ -1071,9 +1144,10 @@ void SensorService::SensorRecord::clearAllPendingFlushConnections() {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
SensorService::SensorEventConnection::SensorEventConnection(
|
||||
const sp<SensorService>& service, uid_t uid, String8 packageName)
|
||||
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode)
|
||||
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
|
||||
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName) {
|
||||
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName),
|
||||
mDataInjectionMode(isDataInjectionMode) {
|
||||
mChannel = new BitTube(mService->mSocketBufferSize);
|
||||
#if DEBUG_CONNECTIONS
|
||||
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
||||
@ -1105,6 +1179,7 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() {
|
||||
|
||||
void SensorService::SensorEventConnection::dump(String8& result) {
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
result.appendFormat("Operating Mode: %s\n", mDataInjectionMode ? "DATA_INJECTION" : "NORMAL");
|
||||
result.appendFormat("\t%s | WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
|
||||
mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
|
||||
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
||||
@ -1190,7 +1265,8 @@ void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Loo
|
||||
|
||||
void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
|
||||
const sp<Looper>& looper) {
|
||||
bool isConnectionActive = mSensorInfo.size() > 0;
|
||||
bool isConnectionActive = (mSensorInfo.size() > 0 && !mDataInjectionMode) ||
|
||||
mDataInjectionMode;
|
||||
// If all sensors are unregistered OR Looper has encountered an error, we
|
||||
// can remove the Fd from the Looper if it has been previously added.
|
||||
if (!isConnectionActive || mDead) {
|
||||
@ -1204,6 +1280,7 @@ void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
|
||||
|
||||
int looper_flags = 0;
|
||||
if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
|
||||
if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
|
||||
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
||||
const int handle = mSensorInfo.keyAt(i);
|
||||
if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
|
||||
@ -1570,26 +1647,55 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
|
||||
updateLooperRegistrationLocked(mService->getLooper());
|
||||
}
|
||||
mService->checkWakeLockState();
|
||||
if (mDataInjectionMode) {
|
||||
// If the Looper has encountered some error in data injection mode, reset SensorService
|
||||
// back to normal mode.
|
||||
mService->resetToNormalMode();
|
||||
mDataInjectionMode = false;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (events & ALOOPER_EVENT_INPUT) {
|
||||
uint32_t numAcks = 0;
|
||||
ssize_t ret = ::recv(fd, &numAcks, sizeof(numAcks), MSG_DONTWAIT);
|
||||
unsigned char buf[sizeof(sensors_event_t)];
|
||||
ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||
{
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
// Sanity check to ensure there are no read errors in recv, numAcks is always
|
||||
// within the range and not zero. If any of the above don't hold reset mWakeLockRefCount
|
||||
// to zero.
|
||||
if (ret != sizeof(numAcks) || numAcks > mWakeLockRefCount || numAcks == 0) {
|
||||
ALOGE("Looper read error ret=%d numAcks=%d", ret, numAcks);
|
||||
mWakeLockRefCount = 0;
|
||||
} else {
|
||||
mWakeLockRefCount -= numAcks;
|
||||
}
|
||||
if (numBytesRead == sizeof(sensors_event_t)) {
|
||||
if (!mDataInjectionMode) {
|
||||
ALOGE("Data injected in normal mode, dropping event"
|
||||
"package=%s uid=%d", mPackageName.string(), mUid);
|
||||
// Unregister call backs.
|
||||
return 0;
|
||||
}
|
||||
SensorDevice& dev(SensorDevice::getInstance());
|
||||
sensors_event_t sensor_event;
|
||||
memset(&sensor_event, 0, sizeof(sensor_event));
|
||||
memcpy(&sensor_event, buf, sizeof(sensors_event_t));
|
||||
Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
|
||||
sensor_event.type = sensor.getType();
|
||||
dev.injectSensorData(&sensor_event, 1);
|
||||
#if DEBUG_CONNECTIONS
|
||||
mTotalAcksReceived += numAcks;
|
||||
++mEventsReceived;
|
||||
#endif
|
||||
} else if (numBytesRead == sizeof(uint32_t)) {
|
||||
uint32_t numAcks = 0;
|
||||
memcpy(&numAcks, buf, sizeof(numBytesRead));
|
||||
// Sanity check to ensure there are no read errors in recv, numAcks is always
|
||||
// within the range and not zero. If any of the above don't hold reset
|
||||
// mWakeLockRefCount to zero.
|
||||
if (numAcks > 0 && numAcks < mWakeLockRefCount) {
|
||||
mWakeLockRefCount -= numAcks;
|
||||
} else {
|
||||
mWakeLockRefCount = 0;
|
||||
}
|
||||
#if DEBUG_CONNECTIONS
|
||||
mTotalAcksReceived += numAcks;
|
||||
#endif
|
||||
} else {
|
||||
// Read error, reset wakelock refcount.
|
||||
mWakeLockRefCount = 0;
|
||||
}
|
||||
}
|
||||
// Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
|
||||
// here as checkWakeLockState() will need it.
|
||||
|
@ -70,21 +70,33 @@ class SensorService :
|
||||
// The regular operating mode where any application can register/unregister/call flush on
|
||||
// sensors.
|
||||
NORMAL = 0,
|
||||
// This mode is only used for testing purposes. Not all HALs support this mode. In this
|
||||
// mode, the HAL ignores the sensor data provided by physical sensors and accepts the data
|
||||
// that is injected from the SensorService as if it were the real sensor data. This mode
|
||||
// is primarily used for testing various algorithms like vendor provided SensorFusion,
|
||||
// Step Counter and Step Detector etc. Typically in this mode, there will be a client
|
||||
// (a SensorEventConnection) which will be injecting sensor data into the HAL. Normal apps
|
||||
// can unregister and register for any sensor that supports injection. Registering to sensors
|
||||
// that do not support injection will give an error.
|
||||
// TODO(aakella) : Allow exactly one client to inject sensor data at a time.
|
||||
DATA_INJECTION = 1,
|
||||
// This mode is used only for testing sensors. Each sensor can be tested in isolation with
|
||||
// the required sampling_rate and maxReportLatency parameters without having to think about
|
||||
// the data rates requested by other applications. End user devices are always expected to be
|
||||
// in NORMAL mode. When this mode is first activated, all active sensors from all connections
|
||||
// are disabled. Calling flush() will return an error. In this mode, only the requests from
|
||||
// selected apps whose package names are whitelisted are allowed (typically CTS apps). Only
|
||||
// these apps can register/unregister/call flush() on sensors. If SensorService switches to
|
||||
// these apps can register/unregister/call flush() on sensors. If SensorService switches to
|
||||
// NORMAL mode again, all sensors that were previously registered to are activated with the
|
||||
// corresponding paramaters if the application hasn't unregistered for sensors in the mean
|
||||
// time.
|
||||
// NOTE: Non whitelisted app whose sensors were previously deactivated may still receive
|
||||
// events if a whitelisted app requests data from the same sensor.
|
||||
RESTRICTED,
|
||||
// TODO: This mode hasn't been implemented yet.
|
||||
DATA_INJECTION
|
||||
RESTRICTED = 2
|
||||
|
||||
// State Transitions supported.
|
||||
// RESTRICTED <--- NORMAL ---> DATA_INJECTION
|
||||
// ---> <---
|
||||
};
|
||||
|
||||
static const char* WAKE_LOCK_NAME;
|
||||
@ -100,7 +112,9 @@ class SensorService :
|
||||
|
||||
// ISensorServer interface
|
||||
virtual Vector<Sensor> getSensorList();
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName);
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
|
||||
int requestedMode);
|
||||
virtual status_t enableDataInjection(int enable);
|
||||
virtual status_t dump(int fd, const Vector<String16>& args);
|
||||
|
||||
class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
|
||||
@ -177,6 +191,8 @@ class SensorService :
|
||||
// mWakeLockRefCount is reset to zero. needsWakeLock method will always return false, if
|
||||
// this flag is set.
|
||||
bool mDead;
|
||||
|
||||
bool mDataInjectionMode;
|
||||
struct FlushInfo {
|
||||
// The number of flush complete events dropped for this sensor is stored here.
|
||||
// They are sent separately before the next batch of events.
|
||||
@ -191,14 +207,14 @@ class SensorService :
|
||||
sensors_event_t *mEventCache;
|
||||
int mCacheSize, mMaxCacheSize;
|
||||
String8 mPackageName;
|
||||
|
||||
#if DEBUG_CONNECTIONS
|
||||
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
||||
int mTotalAcksNeeded, mTotalAcksReceived;
|
||||
#endif
|
||||
|
||||
public:
|
||||
SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName);
|
||||
SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName,
|
||||
bool isDataInjectionMode);
|
||||
|
||||
status_t sendEvents(sensors_event_t const* buffer, size_t count,
|
||||
sensors_event_t* scratch,
|
||||
@ -257,6 +273,7 @@ class SensorService :
|
||||
sensors_event_t const* buffer, const int count);
|
||||
static bool canAccessSensor(const Sensor& sensor);
|
||||
static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation);
|
||||
static bool hasDataInjectionPermissions();
|
||||
// SensorService acquires a partial wakelock for delivering events from wake up sensors. This
|
||||
// method checks whether all the events from these wake up sensors have been delivered to the
|
||||
// corresponding applications, if yes the wakelock is released.
|
||||
@ -290,6 +307,10 @@ class SensorService :
|
||||
// allowed.
|
||||
bool isWhiteListedPackage(const String8& packageName);
|
||||
|
||||
// Reset the state of SensorService to NORMAL mode.
|
||||
status_t resetToNormalMode();
|
||||
status_t resetToNormalModeLocked();
|
||||
|
||||
// constants
|
||||
Vector<Sensor> mSensorList;
|
||||
Vector<Sensor> mUserSensorListDebug;
|
||||
@ -311,7 +332,7 @@ class SensorService :
|
||||
bool mWakeLockAcquired;
|
||||
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
|
||||
SensorEventConnection const **mMapFlushEventsToConnections;
|
||||
Mode mMode;
|
||||
Mode mCurrentOperatingMode;
|
||||
|
||||
// The size of this vector is constant, only the items are mutable
|
||||
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
|
||||
|
Loading…
Reference in New Issue
Block a user