Enable data injection mode in SensorService.
Change-Id: I0cd32a017235c31c54816e4a357ce3b988350ed6
This commit is contained in:
parent
3804378e6a
commit
a9e6cc3870
@ -38,7 +38,9 @@ public:
|
|||||||
DECLARE_META_INTERFACE(SensorServer);
|
DECLARE_META_INTERFACE(SensorServer);
|
||||||
|
|
||||||
virtual Vector<Sensor> getSensorList() = 0;
|
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;
|
status_t flush() const;
|
||||||
// Send an ack for every wake_up sensor event that is set to WAKE_UP_SENSOR_EVENT_NEEDS_ACK.
|
// 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);
|
void sendAck(const ASensorEvent* events, int count);
|
||||||
|
|
||||||
|
status_t injectSensorEvent(const ASensorEvent& event);
|
||||||
private:
|
private:
|
||||||
sp<Looper> getLooper() const;
|
sp<Looper> getLooper() const;
|
||||||
sp<ISensorEventConnection> mSensorEventConnection;
|
sp<ISensorEventConnection> mSensorEventConnection;
|
||||||
|
@ -53,7 +53,8 @@ public:
|
|||||||
|
|
||||||
ssize_t getSensorList(Sensor const* const** list) const;
|
ssize_t getSensorList(Sensor const* const** list) const;
|
||||||
Sensor const* getDefaultSensor(int type);
|
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:
|
private:
|
||||||
// DeathRecipient interface
|
// DeathRecipient interface
|
||||||
|
@ -35,6 +35,7 @@ namespace android {
|
|||||||
enum {
|
enum {
|
||||||
GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
|
GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
|
||||||
CREATE_SENSOR_EVENT_CONNECTION,
|
CREATE_SENSOR_EVENT_CONNECTION,
|
||||||
|
ENABLE_DATA_INJECTION
|
||||||
};
|
};
|
||||||
|
|
||||||
class BpSensorServer : public BpInterface<ISensorServer>
|
class BpSensorServer : public BpInterface<ISensorServer>
|
||||||
@ -63,14 +64,24 @@ public:
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
|
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
|
||||||
|
int mode)
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
||||||
data.writeString8(packageName);
|
data.writeString8(packageName);
|
||||||
|
data.writeInt32(mode);
|
||||||
remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
|
remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
|
||||||
return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
|
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
|
// 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: {
|
case CREATE_SENSOR_EVENT_CONNECTION: {
|
||||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||||
String8 packageName = data.readString8();
|
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));
|
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||||
return NO_ERROR;
|
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);
|
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);
|
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) {
|
void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
|
if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) {
|
||||||
|
@ -100,8 +100,6 @@ status_t SensorManager::assertStateLocked() const {
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t SensorManager::getSensorList(Sensor const* const** list) const
|
ssize_t SensorManager::getSensorList(Sensor const* const** list) const
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
@ -139,18 +137,17 @@ Sensor const* SensorManager::getDefaultSensor(int type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) {
|
||||||
{
|
|
||||||
sp<SensorEventQueue> queue;
|
sp<SensorEventQueue> queue;
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
while (assertStateLocked() == NO_ERROR) {
|
while (assertStateLocked() == NO_ERROR) {
|
||||||
sp<ISensorEventConnection> connection =
|
sp<ISensorEventConnection> connection =
|
||||||
mSensorServer->createSensorEventConnection(packageName);
|
mSensorServer->createSensorEventConnection(packageName, mode);
|
||||||
if (connection == NULL) {
|
if (connection == NULL) {
|
||||||
// SensorService just died.
|
// SensorService just died or the app doesn't have required permissions.
|
||||||
ALOGE("createEventQueue: connection is NULL. SensorService died.");
|
ALOGE("createEventQueue: connection is NULL.");
|
||||||
continue;
|
return NULL;
|
||||||
}
|
}
|
||||||
queue = new SensorEventQueue(connection);
|
queue = new SensorEventQueue(connection);
|
||||||
break;
|
break;
|
||||||
@ -158,5 +155,13 @@ sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
|||||||
return queue;
|
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
|
}; // namespace android
|
||||||
|
@ -367,7 +367,7 @@ void SensorDevice::enableAllSensors() {
|
|||||||
|
|
||||||
void SensorDevice::disableAllSensors() {
|
void SensorDevice::disableAllSensors() {
|
||||||
Mutex::Autolock _l(mLock);
|
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);
|
const Info& info = mActivationCount.valueAt(i);
|
||||||
// Check if this sensor has been activated previously and disable it.
|
// Check if this sensor has been activated previously and disable it.
|
||||||
if (info.batchParams.size() > 0) {
|
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() {
|
int SensorDevice::Info::numActiveClients() {
|
||||||
|
@ -98,9 +98,11 @@ public:
|
|||||||
// Call batch with timeout zero instead of calling setDelay() for newer devices.
|
// Call batch with timeout zero instead of calling setDelay() for newer devices.
|
||||||
status_t setDelay(void* ident, int handle, int64_t ns);
|
status_t setDelay(void* ident, int handle, int64_t ns);
|
||||||
status_t flush(void* ident, int handle);
|
status_t flush(void* ident, int handle);
|
||||||
|
status_t setMode(uint32_t mode);
|
||||||
void disableAllSensors();
|
void disableAllSensors();
|
||||||
void enableAllSensors();
|
void enableAllSensors();
|
||||||
void autoDisable(void *ident, int handle);
|
void autoDisable(void *ident, int handle);
|
||||||
|
status_t injectSensorData(const sensors_event_t *event, size_t count);
|
||||||
void dump(String8& result);
|
void dump(String8& result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,6 +64,9 @@ namespace android {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const char* SensorService::WAKE_LOCK_NAME = "SensorService";
|
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()
|
SensorService::SensorService()
|
||||||
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
|
: mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
|
||||||
@ -74,7 +77,6 @@ SensorService::SensorService()
|
|||||||
void SensorService::onFirstRef()
|
void SensorService::onFirstRef()
|
||||||
{
|
{
|
||||||
ALOGD("nuSensorService starting...");
|
ALOGD("nuSensorService starting...");
|
||||||
|
|
||||||
SensorDevice& dev(SensorDevice::getInstance());
|
SensorDevice& dev(SensorDevice::getInstance());
|
||||||
|
|
||||||
if (dev.initCheck() == NO_ERROR) {
|
if (dev.initCheck() == NO_ERROR) {
|
||||||
@ -190,7 +192,7 @@ void SensorService::onFirstRef()
|
|||||||
mSensorEventBuffer = new sensors_event_t[minBufferSize];
|
mSensorEventBuffer = new sensors_event_t[minBufferSize];
|
||||||
mSensorEventScratch = new sensors_event_t[minBufferSize];
|
mSensorEventScratch = new sensors_event_t[minBufferSize];
|
||||||
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
|
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
|
||||||
mMode = NORMAL;
|
mCurrentOperatingMode = NORMAL;
|
||||||
|
|
||||||
mAckReceiver = new SensorEventAckReceiver(this);
|
mAckReceiver = new SensorEventAckReceiver(this);
|
||||||
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||||
@ -229,8 +231,6 @@ SensorService::~SensorService()
|
|||||||
delete mSensorMap.valueAt(i);
|
delete mSensorMap.valueAt(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const String16 sDump("android.permission.DUMP");
|
|
||||||
|
|
||||||
status_t SensorService::dump(int fd, const Vector<String16>& args)
|
status_t SensorService::dump(int fd, const Vector<String16>& args)
|
||||||
{
|
{
|
||||||
String8 result;
|
String8 result;
|
||||||
@ -245,8 +245,8 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
|||||||
}
|
}
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
SensorDevice& dev(SensorDevice::getInstance());
|
SensorDevice& dev(SensorDevice::getInstance());
|
||||||
if (args[0] == String16("restrict") && mMode == NORMAL) {
|
if (args[0] == String16("restrict") && mCurrentOperatingMode == NORMAL) {
|
||||||
mMode = RESTRICTED;
|
mCurrentOperatingMode = RESTRICTED;
|
||||||
dev.disableAllSensors();
|
dev.disableAllSensors();
|
||||||
// Clear all pending flush connections for all active sensors. If one of the active
|
// 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
|
// 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) {
|
for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
|
||||||
mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
|
mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
|
||||||
}
|
}
|
||||||
} else if (args[0] == String16("enable") && mMode == RESTRICTED) {
|
} else if (args[0] == String16("enable") && mCurrentOperatingMode == RESTRICTED) {
|
||||||
mMode = NORMAL;
|
mCurrentOperatingMode = NORMAL;
|
||||||
dev.enableAllSensors();
|
dev.enableAllSensors();
|
||||||
}
|
}
|
||||||
return status_t(NO_ERROR);
|
return status_t(NO_ERROR);
|
||||||
@ -363,7 +363,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
|
|||||||
mSocketBufferSize/sizeof(sensors_event_t));
|
mSocketBufferSize/sizeof(sensors_event_t));
|
||||||
result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
|
result.appendFormat("WakeLock Status: %s \n", mWakeLockAcquired ? "acquired" : "not held");
|
||||||
result.appendFormat("Mode :");
|
result.appendFormat("Mode :");
|
||||||
switch(mMode) {
|
switch(mCurrentOperatingMode) {
|
||||||
case NORMAL:
|
case NORMAL:
|
||||||
result.appendFormat(" NORMAL\n");
|
result.appendFormat(" NORMAL\n");
|
||||||
break;
|
break;
|
||||||
@ -403,8 +403,9 @@ void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnecti
|
|||||||
sensor->autoDisable(connection.get(), handle);
|
sensor->autoDisable(connection.get(), handle);
|
||||||
cleanupWithoutDisableLocked(connection, handle);
|
cleanupWithoutDisableLocked(connection, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SensorService::threadLoop()
|
bool SensorService::threadLoop()
|
||||||
@ -685,13 +686,76 @@ Vector<Sensor> SensorService::getSensorList()
|
|||||||
return accessibleSensorList;
|
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();
|
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;
|
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)
|
void SensorService::cleanupConnection(SensorEventConnection* c)
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
@ -753,7 +817,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
if (mCurrentOperatingMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
||||||
return INVALID_OPERATION;
|
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() {
|
void SensorService::checkWakeLockState() {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
checkWakeLockStateLocked();
|
checkWakeLockStateLocked();
|
||||||
@ -1071,9 +1144,10 @@ void SensorService::SensorRecord::clearAllPendingFlushConnections() {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SensorService::SensorEventConnection::SensorEventConnection(
|
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),
|
: 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);
|
mChannel = new BitTube(mService->mSocketBufferSize);
|
||||||
#if DEBUG_CONNECTIONS
|
#if DEBUG_CONNECTIONS
|
||||||
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
||||||
@ -1105,6 +1179,7 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() {
|
|||||||
|
|
||||||
void SensorService::SensorEventConnection::dump(String8& result) {
|
void SensorService::SensorEventConnection::dump(String8& result) {
|
||||||
Mutex::Autolock _l(mConnectionLock);
|
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",
|
result.appendFormat("\t%s | WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
|
||||||
mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
|
mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
|
||||||
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
||||||
@ -1190,7 +1265,8 @@ void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Loo
|
|||||||
|
|
||||||
void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
|
void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
|
||||||
const sp<Looper>& looper) {
|
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
|
// 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.
|
// can remove the Fd from the Looper if it has been previously added.
|
||||||
if (!isConnectionActive || mDead) {
|
if (!isConnectionActive || mDead) {
|
||||||
@ -1204,6 +1280,7 @@ void SensorService::SensorEventConnection::updateLooperRegistrationLocked(
|
|||||||
|
|
||||||
int looper_flags = 0;
|
int looper_flags = 0;
|
||||||
if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
|
if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
|
||||||
|
if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
|
||||||
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
for (size_t i = 0; i < mSensorInfo.size(); ++i) {
|
||||||
const int handle = mSensorInfo.keyAt(i);
|
const int handle = mSensorInfo.keyAt(i);
|
||||||
if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
|
if (mService->getSensorFromHandle(handle).isWakeUpSensor()) {
|
||||||
@ -1570,26 +1647,55 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
|
|||||||
updateLooperRegistrationLocked(mService->getLooper());
|
updateLooperRegistrationLocked(mService->getLooper());
|
||||||
}
|
}
|
||||||
mService->checkWakeLockState();
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events & ALOOPER_EVENT_INPUT) {
|
if (events & ALOOPER_EVENT_INPUT) {
|
||||||
uint32_t numAcks = 0;
|
unsigned char buf[sizeof(sensors_event_t)];
|
||||||
ssize_t ret = ::recv(fd, &numAcks, sizeof(numAcks), MSG_DONTWAIT);
|
ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mConnectionLock);
|
Mutex::Autolock _l(mConnectionLock);
|
||||||
// Sanity check to ensure there are no read errors in recv, numAcks is always
|
if (numBytesRead == sizeof(sensors_event_t)) {
|
||||||
// within the range and not zero. If any of the above don't hold reset mWakeLockRefCount
|
if (!mDataInjectionMode) {
|
||||||
// to zero.
|
ALOGE("Data injected in normal mode, dropping event"
|
||||||
if (ret != sizeof(numAcks) || numAcks > mWakeLockRefCount || numAcks == 0) {
|
"package=%s uid=%d", mPackageName.string(), mUid);
|
||||||
ALOGE("Looper read error ret=%d numAcks=%d", ret, numAcks);
|
// Unregister call backs.
|
||||||
mWakeLockRefCount = 0;
|
return 0;
|
||||||
} else {
|
}
|
||||||
mWakeLockRefCount -= numAcks;
|
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
|
#if DEBUG_CONNECTIONS
|
||||||
mTotalAcksReceived += numAcks;
|
++mEventsReceived;
|
||||||
#endif
|
#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
|
// Check if wakelock can be released by sensorservice. mConnectionLock needs to be released
|
||||||
// here as checkWakeLockState() will need it.
|
// 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
|
// The regular operating mode where any application can register/unregister/call flush on
|
||||||
// sensors.
|
// sensors.
|
||||||
NORMAL = 0,
|
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
|
// 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 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
|
// 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
|
// 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
|
// 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
|
// 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
|
// 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
|
// corresponding paramaters if the application hasn't unregistered for sensors in the mean
|
||||||
// time.
|
// time.
|
||||||
// NOTE: Non whitelisted app whose sensors were previously deactivated may still receive
|
// NOTE: Non whitelisted app whose sensors were previously deactivated may still receive
|
||||||
// events if a whitelisted app requests data from the same sensor.
|
// events if a whitelisted app requests data from the same sensor.
|
||||||
RESTRICTED,
|
RESTRICTED = 2
|
||||||
// TODO: This mode hasn't been implemented yet.
|
|
||||||
DATA_INJECTION
|
// State Transitions supported.
|
||||||
|
// RESTRICTED <--- NORMAL ---> DATA_INJECTION
|
||||||
|
// ---> <---
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* WAKE_LOCK_NAME;
|
static const char* WAKE_LOCK_NAME;
|
||||||
@ -100,7 +112,9 @@ class SensorService :
|
|||||||
|
|
||||||
// ISensorServer interface
|
// ISensorServer interface
|
||||||
virtual Vector<Sensor> getSensorList();
|
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);
|
virtual status_t dump(int fd, const Vector<String16>& args);
|
||||||
|
|
||||||
class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
|
class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
|
||||||
@ -177,6 +191,8 @@ class SensorService :
|
|||||||
// mWakeLockRefCount is reset to zero. needsWakeLock method will always return false, if
|
// mWakeLockRefCount is reset to zero. needsWakeLock method will always return false, if
|
||||||
// this flag is set.
|
// this flag is set.
|
||||||
bool mDead;
|
bool mDead;
|
||||||
|
|
||||||
|
bool mDataInjectionMode;
|
||||||
struct FlushInfo {
|
struct FlushInfo {
|
||||||
// The number of flush complete events dropped for this sensor is stored here.
|
// The number of flush complete events dropped for this sensor is stored here.
|
||||||
// They are sent separately before the next batch of events.
|
// They are sent separately before the next batch of events.
|
||||||
@ -191,14 +207,14 @@ class SensorService :
|
|||||||
sensors_event_t *mEventCache;
|
sensors_event_t *mEventCache;
|
||||||
int mCacheSize, mMaxCacheSize;
|
int mCacheSize, mMaxCacheSize;
|
||||||
String8 mPackageName;
|
String8 mPackageName;
|
||||||
|
|
||||||
#if DEBUG_CONNECTIONS
|
#if DEBUG_CONNECTIONS
|
||||||
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
||||||
int mTotalAcksNeeded, mTotalAcksReceived;
|
int mTotalAcksNeeded, mTotalAcksReceived;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
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,
|
status_t sendEvents(sensors_event_t const* buffer, size_t count,
|
||||||
sensors_event_t* scratch,
|
sensors_event_t* scratch,
|
||||||
@ -257,6 +273,7 @@ class SensorService :
|
|||||||
sensors_event_t const* buffer, const int count);
|
sensors_event_t const* buffer, const int count);
|
||||||
static bool canAccessSensor(const Sensor& sensor);
|
static bool canAccessSensor(const Sensor& sensor);
|
||||||
static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation);
|
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
|
// 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
|
// method checks whether all the events from these wake up sensors have been delivered to the
|
||||||
// corresponding applications, if yes the wakelock is released.
|
// corresponding applications, if yes the wakelock is released.
|
||||||
@ -290,6 +307,10 @@ class SensorService :
|
|||||||
// allowed.
|
// allowed.
|
||||||
bool isWhiteListedPackage(const String8& packageName);
|
bool isWhiteListedPackage(const String8& packageName);
|
||||||
|
|
||||||
|
// Reset the state of SensorService to NORMAL mode.
|
||||||
|
status_t resetToNormalMode();
|
||||||
|
status_t resetToNormalModeLocked();
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
Vector<Sensor> mSensorList;
|
Vector<Sensor> mSensorList;
|
||||||
Vector<Sensor> mUserSensorListDebug;
|
Vector<Sensor> mUserSensorListDebug;
|
||||||
@ -311,7 +332,7 @@ class SensorService :
|
|||||||
bool mWakeLockAcquired;
|
bool mWakeLockAcquired;
|
||||||
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
|
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
|
||||||
SensorEventConnection const **mMapFlushEventsToConnections;
|
SensorEventConnection const **mMapFlushEventsToConnections;
|
||||||
Mode mMode;
|
Mode mCurrentOperatingMode;
|
||||||
|
|
||||||
// The size of this vector is constant, only the items are mutable
|
// The size of this vector is constant, only the items are mutable
|
||||||
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
|
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
|
||||||
|
Loading…
Reference in New Issue
Block a user