Merge "Support restricted mode in SensorService."
This commit is contained in:
commit
d46181da0c
@ -30,6 +30,7 @@ namespace android {
|
|||||||
|
|
||||||
class Sensor;
|
class Sensor;
|
||||||
class ISensorEventConnection;
|
class ISensorEventConnection;
|
||||||
|
class String8;
|
||||||
|
|
||||||
class ISensorServer : public IInterface
|
class ISensorServer : public IInterface
|
||||||
{
|
{
|
||||||
@ -37,7 +38,7 @@ public:
|
|||||||
DECLARE_META_INTERFACE(SensorServer);
|
DECLARE_META_INTERFACE(SensorServer);
|
||||||
|
|
||||||
virtual Vector<Sensor> getSensorList() = 0;
|
virtual Vector<Sensor> getSensorList() = 0;
|
||||||
virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
|
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -40,7 +40,7 @@ namespace android {
|
|||||||
class ISensorServer;
|
class ISensorServer;
|
||||||
class Sensor;
|
class Sensor;
|
||||||
class SensorEventQueue;
|
class SensorEventQueue;
|
||||||
|
class String8;
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class SensorManager :
|
class SensorManager :
|
||||||
@ -53,7 +53,7 @@ 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();
|
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// DeathRecipient interface
|
// DeathRecipient interface
|
||||||
|
@ -63,10 +63,11 @@ public:
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual sp<ISensorEventConnection> createSensorEventConnection()
|
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
||||||
|
data.writeString8(packageName);
|
||||||
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());
|
||||||
}
|
}
|
||||||
@ -96,7 +97,8 @@ status_t BnSensorServer::onTransact(
|
|||||||
}
|
}
|
||||||
case CREATE_SENSOR_EVENT_CONNECTION: {
|
case CREATE_SENSOR_EVENT_CONNECTION: {
|
||||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||||
sp<ISensorEventConnection> connection(createSensorEventConnection());
|
String8 packageName = data.readString8();
|
||||||
|
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName));
|
||||||
reply->writeStrongBinder(IInterface::asBinder(connection));
|
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -139,14 +139,14 @@ Sensor const* SensorManager::getDefaultSensor(int type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<SensorEventQueue> SensorManager::createEventQueue()
|
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
||||||
{
|
{
|
||||||
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();
|
mSensorServer->createSensorEventConnection(packageName);
|
||||||
if (connection == NULL) {
|
if (connection == NULL) {
|
||||||
// SensorService just died.
|
// SensorService just died.
|
||||||
ALOGE("createEventQueue: connection is NULL. SensorService died.");
|
ALOGE("createEventQueue: connection is NULL. SensorService died.");
|
||||||
|
@ -85,6 +85,7 @@ void SensorDevice::dump(String8& result)
|
|||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
for (size_t i=0 ; i<size_t(count) ; i++) {
|
for (size_t i=0 ; i<size_t(count) ; i++) {
|
||||||
const Info& info = mActivationCount.valueFor(list[i].handle);
|
const Info& info = mActivationCount.valueFor(list[i].handle);
|
||||||
|
if (info.batchParams.isEmpty()) continue;
|
||||||
result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
|
result.appendFormat("handle=0x%08x, active-count=%zu, batch_period(ms)={ ", list[i].handle,
|
||||||
info.batchParams.size());
|
info.batchParams.size());
|
||||||
for (size_t j = 0; j < info.batchParams.size(); j++) {
|
for (size_t j = 0; j < info.batchParams.size(); j++) {
|
||||||
@ -147,8 +148,12 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
|
|||||||
if (enabled) {
|
if (enabled) {
|
||||||
ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
|
ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
|
||||||
|
|
||||||
|
if (isClientDisabledLocked(ident)) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
if (info.batchParams.indexOfKey(ident) >= 0) {
|
if (info.batchParams.indexOfKey(ident) >= 0) {
|
||||||
if (info.batchParams.size() == 1) {
|
if (info.numActiveClients() == 1) {
|
||||||
// This is the first connection, we need to activate the underlying h/w sensor.
|
// This is the first connection, we need to activate the underlying h/w sensor.
|
||||||
actuateHardware = true;
|
actuateHardware = true;
|
||||||
}
|
}
|
||||||
@ -160,7 +165,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
|
|||||||
ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
|
ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
|
||||||
|
|
||||||
if (info.removeBatchParamsForIdent(ident) >= 0) {
|
if (info.removeBatchParamsForIdent(ident) >= 0) {
|
||||||
if (info.batchParams.size() == 0) {
|
if (info.numActiveClients() == 0) {
|
||||||
// This is the last connection, we need to de-activate the underlying h/w sensor.
|
// This is the last connection, we need to de-activate the underlying h/w sensor.
|
||||||
actuateHardware = true;
|
actuateHardware = true;
|
||||||
} else {
|
} else {
|
||||||
@ -181,10 +186,15 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
|
|||||||
} else {
|
} else {
|
||||||
// sensor wasn't enabled for this ident
|
// sensor wasn't enabled for this ident
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isClientDisabledLocked(ident)) {
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actuateHardware) {
|
if (actuateHardware) {
|
||||||
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
|
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
|
||||||
|
enabled);
|
||||||
err = mSensorDevice->activate(
|
err = mSensorDevice->activate(
|
||||||
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
|
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
|
||||||
ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
|
ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
|
||||||
@ -197,7 +207,7 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On older devices which do not support batch, call setDelay().
|
// On older devices which do not support batch, call setDelay().
|
||||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
|
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) {
|
||||||
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
|
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
|
||||||
info.bestBatchParams.batchDelay);
|
info.bestBatchParams.batchDelay);
|
||||||
mSensorDevice->setDelay(
|
mSensorDevice->setDelay(
|
||||||
@ -279,6 +289,7 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN
|
|||||||
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
|
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
|
||||||
}
|
}
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
|
if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
|
||||||
Info& info( mActivationCount.editValueFor(handle) );
|
Info& info( mActivationCount.editValueFor(handle) );
|
||||||
// If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
|
// If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
|
||||||
// Calling setDelay() in batch mode is an invalid operation.
|
// Calling setDelay() in batch mode is an invalid operation.
|
||||||
@ -298,7 +309,6 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN
|
|||||||
|
|
||||||
int SensorDevice::getHalDeviceVersion() const {
|
int SensorDevice::getHalDeviceVersion() const {
|
||||||
if (!mSensorDevice) return -1;
|
if (!mSensorDevice) return -1;
|
||||||
|
|
||||||
return mSensorDevice->common.version;
|
return mSensorDevice->common.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,12 +316,89 @@ status_t SensorDevice::flush(void* ident, int handle) {
|
|||||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
|
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
|
||||||
return INVALID_OPERATION;
|
return INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
if (isClientDisabled(ident)) return INVALID_OPERATION;
|
||||||
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
|
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
|
||||||
return mSensorDevice->flush(mSensorDevice, handle);
|
return mSensorDevice->flush(mSensorDevice, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SensorDevice::isClientDisabled(void* ident) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
return isClientDisabledLocked(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SensorDevice::isClientDisabledLocked(void* ident) {
|
||||||
|
return mDisabledClients.indexOf(ident) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SensorDevice::enableAllSensors() {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
mDisabledClients.clear();
|
||||||
|
const int halVersion = getHalDeviceVersion();
|
||||||
|
for (size_t i = 0; i< mActivationCount.size(); ++i) {
|
||||||
|
Info& info = mActivationCount.editValueAt(i);
|
||||||
|
if (info.batchParams.isEmpty()) continue;
|
||||||
|
info.selectBatchParams();
|
||||||
|
const int sensor_handle = mActivationCount.keyAt(i);
|
||||||
|
ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ",
|
||||||
|
sensor_handle);
|
||||||
|
status_t err(NO_ERROR);
|
||||||
|
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) {
|
||||||
|
err = mSensorDevice->batch(mSensorDevice, sensor_handle,
|
||||||
|
info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
|
||||||
|
info.bestBatchParams.batchTimeout);
|
||||||
|
ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == NO_ERROR) {
|
||||||
|
err = mSensorDevice->activate(
|
||||||
|
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
|
||||||
|
sensor_handle, 1);
|
||||||
|
ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) {
|
||||||
|
err = mSensorDevice->setDelay(
|
||||||
|
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
|
||||||
|
sensor_handle, info.bestBatchParams.batchDelay);
|
||||||
|
ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SensorDevice::disableAllSensors() {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
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) {
|
||||||
|
const int sensor_handle = mActivationCount.keyAt(i);
|
||||||
|
ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ",
|
||||||
|
sensor_handle);
|
||||||
|
mSensorDevice->activate(
|
||||||
|
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
|
||||||
|
sensor_handle, 0);
|
||||||
|
// Add all the connections that were registered for this sensor to the disabled
|
||||||
|
// clients list.
|
||||||
|
for (int j = 0; j < info.batchParams.size(); ++j) {
|
||||||
|
mDisabledClients.add(info.batchParams.keyAt(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int SensorDevice::Info::numActiveClients() {
|
||||||
|
SensorDevice& device(SensorDevice::getInstance());
|
||||||
|
int num = 0;
|
||||||
|
for (size_t i = 0; i < batchParams.size(); ++i) {
|
||||||
|
if (!device.isClientDisabledLocked(batchParams.keyAt(i))) {
|
||||||
|
++num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
|
status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
|
||||||
int64_t samplingPeriodNs,
|
int64_t samplingPeriodNs,
|
||||||
int64_t maxBatchReportLatencyNs) {
|
int64_t maxBatchReportLatencyNs) {
|
||||||
@ -329,19 +416,16 @@ status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SensorDevice::Info::selectBatchParams() {
|
void SensorDevice::Info::selectBatchParams() {
|
||||||
BatchParams bestParams(-1, -1, -1);
|
BatchParams bestParams(0, -1, -1);
|
||||||
|
SensorDevice& device(SensorDevice::getInstance());
|
||||||
|
|
||||||
if (batchParams.size() > 0) {
|
for (size_t i = 0; i < batchParams.size(); ++i) {
|
||||||
BatchParams params = batchParams.valueAt(0);
|
if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
|
||||||
bestParams = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 1; i < batchParams.size(); ++i) {
|
|
||||||
BatchParams params = batchParams.valueAt(i);
|
BatchParams params = batchParams.valueAt(i);
|
||||||
if (params.batchDelay < bestParams.batchDelay) {
|
if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
|
||||||
bestParams.batchDelay = params.batchDelay;
|
bestParams.batchDelay = params.batchDelay;
|
||||||
}
|
}
|
||||||
if (params.batchTimeout < bestParams.batchTimeout) {
|
if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) {
|
||||||
bestParams.batchTimeout = params.batchTimeout;
|
bestParams.batchTimeout = params.batchTimeout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ class SensorDevice : public Singleton<SensorDevice> {
|
|||||||
// Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
|
// Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
|
||||||
// batch call. For continous mode clients, maxBatchReportLatency is set to zero.
|
// batch call. For continous mode clients, maxBatchReportLatency is set to zero.
|
||||||
struct BatchParams {
|
struct BatchParams {
|
||||||
|
// TODO: Get rid of flags parameter everywhere.
|
||||||
int flags;
|
int flags;
|
||||||
nsecs_t batchDelay, batchTimeout;
|
nsecs_t batchDelay, batchTimeout;
|
||||||
BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
|
BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
|
||||||
@ -65,7 +66,7 @@ class SensorDevice : public Singleton<SensorDevice> {
|
|||||||
// requested by the client.
|
// requested by the client.
|
||||||
KeyedVector<void*, BatchParams> batchParams;
|
KeyedVector<void*, BatchParams> batchParams;
|
||||||
|
|
||||||
Info() : bestBatchParams(-1, -1, -1) {}
|
Info() : bestBatchParams(0, -1, -1) {}
|
||||||
// Sets batch parameters for this ident. Returns error if this ident is not already present
|
// Sets batch parameters for this ident. Returns error if this ident is not already present
|
||||||
// in the KeyedVector above.
|
// in the KeyedVector above.
|
||||||
status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
|
status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
|
||||||
@ -75,10 +76,17 @@ class SensorDevice : public Singleton<SensorDevice> {
|
|||||||
// Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
|
// Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
|
||||||
// the removed ident. If index >=0, ident is present and successfully removed.
|
// the removed ident. If index >=0, ident is present and successfully removed.
|
||||||
ssize_t removeBatchParamsForIdent(void* ident);
|
ssize_t removeBatchParamsForIdent(void* ident);
|
||||||
|
|
||||||
|
int numActiveClients();
|
||||||
};
|
};
|
||||||
DefaultKeyedVector<int, Info> mActivationCount;
|
DefaultKeyedVector<int, Info> mActivationCount;
|
||||||
|
|
||||||
|
// Use this vector to determine which client is activated or deactivated.
|
||||||
|
SortedVector<void *> mDisabledClients;
|
||||||
SensorDevice();
|
SensorDevice();
|
||||||
|
|
||||||
|
bool isClientDisabled(void* ident);
|
||||||
|
bool isClientDisabledLocked(void* ident);
|
||||||
public:
|
public:
|
||||||
ssize_t getSensorList(sensor_t const** list);
|
ssize_t getSensorList(sensor_t const** list);
|
||||||
status_t initCheck() const;
|
status_t initCheck() const;
|
||||||
@ -90,6 +98,8 @@ 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);
|
||||||
|
void disableAllSensors();
|
||||||
|
void enableAllSensors();
|
||||||
void autoDisable(void *ident, int handle);
|
void autoDisable(void *ident, int handle);
|
||||||
void dump(String8& result);
|
void dump(String8& result);
|
||||||
};
|
};
|
||||||
|
@ -190,6 +190,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;
|
||||||
|
|
||||||
mAckReceiver = new SensorEventAckReceiver(this);
|
mAckReceiver = new SensorEventAckReceiver(this);
|
||||||
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||||
@ -230,7 +231,7 @@ SensorService::~SensorService()
|
|||||||
|
|
||||||
static const String16 sDump("android.permission.DUMP");
|
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;
|
||||||
if (!PermissionCache::checkCallingPermission(sDump)) {
|
if (!PermissionCache::checkCallingPermission(sDump)) {
|
||||||
@ -238,6 +239,26 @@ status_t SensorService::dump(int fd, const Vector<String16>& /*args*/)
|
|||||||
"can't dump SensorService from pid=%d, uid=%d\n",
|
"can't dump SensorService from pid=%d, uid=%d\n",
|
||||||
IPCThreadState::self()->getCallingPid(),
|
IPCThreadState::self()->getCallingPid(),
|
||||||
IPCThreadState::self()->getCallingUid());
|
IPCThreadState::self()->getCallingUid());
|
||||||
|
} else if (args.size() > 0) {
|
||||||
|
if (args.size() > 1) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
SensorDevice& dev(SensorDevice::getInstance());
|
||||||
|
if (args[0] == String16("restrict") && mMode == NORMAL) {
|
||||||
|
mMode = 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
|
||||||
|
// flush complete event is returned, we need to remove the connection from this queue.
|
||||||
|
for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
|
||||||
|
mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
|
||||||
|
}
|
||||||
|
} else if (args[0] == String16("enable") && mMode == RESTRICTED) {
|
||||||
|
mMode = NORMAL;
|
||||||
|
dev.enableAllSensors();
|
||||||
|
}
|
||||||
|
return status_t(NO_ERROR);
|
||||||
} else {
|
} else {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
result.append("Sensor List:\n");
|
result.append("Sensor List:\n");
|
||||||
@ -341,6 +362,17 @@ status_t SensorService::dump(int fd, const Vector<String16>& /*args*/)
|
|||||||
result.appendFormat("Socket Buffer size = %d events\n",
|
result.appendFormat("Socket Buffer size = %d events\n",
|
||||||
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 :");
|
||||||
|
switch(mMode) {
|
||||||
|
case NORMAL:
|
||||||
|
result.appendFormat(" NORMAL\n");
|
||||||
|
break;
|
||||||
|
case RESTRICTED:
|
||||||
|
result.appendFormat(" RESTRICTED\n");
|
||||||
|
break;
|
||||||
|
case DATA_INJECTION:
|
||||||
|
result.appendFormat(" DATA_INJECTION\n");
|
||||||
|
}
|
||||||
result.appendFormat("%zd active connections\n", mActiveConnections.size());
|
result.appendFormat("%zd active connections\n", mActiveConnections.size());
|
||||||
|
|
||||||
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
|
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
|
||||||
@ -554,7 +586,6 @@ void SensorService::setWakeLockAcquiredLocked(bool acquire) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SensorService::isWakeLockAcquired() {
|
bool SensorService::isWakeLockAcquired() {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
return mWakeLockAcquired;
|
return mWakeLockAcquired;
|
||||||
@ -630,7 +661,6 @@ bool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
|
|||||||
return sensor != NULL && sensor->getSensor().isWakeUpSensor();
|
return sensor != NULL && sensor->getSensor().isWakeUpSensor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
|
SensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
|
||||||
return mActiveSensors.valueFor(handle);
|
return mActiveSensors.valueFor(handle);
|
||||||
}
|
}
|
||||||
@ -655,10 +685,10 @@ Vector<Sensor> SensorService::getSensorList()
|
|||||||
return accessibleSensorList;
|
return accessibleSensorList;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
|
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName)
|
||||||
{
|
{
|
||||||
uid_t uid = IPCThreadState::self()->getCallingUid();
|
uid_t uid = IPCThreadState::self()->getCallingUid();
|
||||||
sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
|
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,7 +738,7 @@ Sensor SensorService::getSensorFromHandle(int handle) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
||||||
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
|
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
|
||||||
{
|
{
|
||||||
if (mInitCheck != NO_ERROR)
|
if (mInitCheck != NO_ERROR)
|
||||||
return mInitCheck;
|
return mInitCheck;
|
||||||
@ -723,6 +753,10 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
|
if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
SensorRecord* rec = mActiveSensors.valueFor(handle);
|
SensorRecord* rec = mActiveSensors.valueFor(handle);
|
||||||
if (rec == 0) {
|
if (rec == 0) {
|
||||||
rec = new SensorRecord(connection);
|
rec = new SensorRecord(connection);
|
||||||
@ -773,7 +807,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
|||||||
"rate=%" PRId64 " timeout== %" PRId64"",
|
"rate=%" PRId64 " timeout== %" PRId64"",
|
||||||
handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
|
handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
|
||||||
|
|
||||||
status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
|
status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
|
||||||
maxBatchReportLatencyNs);
|
maxBatchReportLatencyNs);
|
||||||
|
|
||||||
// Call flush() before calling activate() on the sensor. Wait for a first flush complete
|
// Call flush() before calling activate() on the sensor. Wait for a first flush complete
|
||||||
@ -969,6 +1003,11 @@ void SensorService::populateActiveConnections(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SensorService::isWhiteListedPackage(const String8& packageName) {
|
||||||
|
// TODO: Come up with a list of packages.
|
||||||
|
return (packageName.find(".cts.") != -1);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
SensorService::SensorRecord::SensorRecord(
|
SensorService::SensorRecord::SensorRecord(
|
||||||
const sp<SensorEventConnection>& connection)
|
const sp<SensorEventConnection>& connection)
|
||||||
@ -1025,12 +1064,16 @@ SensorService::SensorRecord::getFirstPendingFlushConnection() {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SensorService::SensorRecord::clearAllPendingFlushConnections() {
|
||||||
|
mPendingFlushConnections.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SensorService::SensorEventConnection::SensorEventConnection(
|
SensorService::SensorEventConnection::SensorEventConnection(
|
||||||
const sp<SensorService>& service, uid_t uid)
|
const sp<SensorService>& service, uid_t uid, String8 packageName)
|
||||||
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
|
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
|
||||||
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0) {
|
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName) {
|
||||||
mChannel = new BitTube(mService->mSocketBufferSize);
|
mChannel = new BitTube(mService->mSocketBufferSize);
|
||||||
#if DEBUG_CONNECTIONS
|
#if DEBUG_CONNECTIONS
|
||||||
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
||||||
@ -1062,8 +1105,8 @@ 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("\t 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",
|
||||||
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) {
|
||||||
const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
|
const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
|
||||||
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
|
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
|
||||||
@ -1126,6 +1169,10 @@ bool SensorService::SensorEventConnection::hasOneShotSensors() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String8 SensorService::SensorEventConnection::getPackageName() const {
|
||||||
|
return mPackageName;
|
||||||
|
}
|
||||||
|
|
||||||
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
|
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
|
||||||
bool value) {
|
bool value) {
|
||||||
Mutex::Autolock _l(mConnectionLock);
|
Mutex::Autolock _l(mConnectionLock);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <utils/AndroidThreads.h>
|
#include <utils/AndroidThreads.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
#include <utils/Looper.h>
|
#include <utils/Looper.h>
|
||||||
|
#include <utils/String8.h>
|
||||||
|
|
||||||
#include <binder/BinderService.h>
|
#include <binder/BinderService.h>
|
||||||
|
|
||||||
@ -65,6 +66,27 @@ class SensorService :
|
|||||||
{
|
{
|
||||||
friend class BinderService<SensorService>;
|
friend class BinderService<SensorService>;
|
||||||
|
|
||||||
|
enum Mode {
|
||||||
|
// The regular operating mode where any application can register/unregister/call flush on
|
||||||
|
// sensors.
|
||||||
|
NORMAL = 0,
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
static const char* WAKE_LOCK_NAME;
|
static const char* WAKE_LOCK_NAME;
|
||||||
|
|
||||||
static char const* getServiceName() ANDROID_API { return "sensorservice"; }
|
static char const* getServiceName() ANDROID_API { return "sensorservice"; }
|
||||||
@ -78,7 +100,7 @@ class SensorService :
|
|||||||
|
|
||||||
// ISensorServer interface
|
// ISensorServer interface
|
||||||
virtual Vector<Sensor> getSensorList();
|
virtual Vector<Sensor> getSensorList();
|
||||||
virtual sp<ISensorEventConnection> createSensorEventConnection();
|
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName);
|
||||||
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 {
|
||||||
@ -133,7 +155,6 @@ class SensorService :
|
|||||||
// connection FD may be added to the Looper. The flags to set are determined by the internal
|
// connection FD may be added to the Looper. The flags to set are determined by the internal
|
||||||
// state of the connection. FDs are added to the looper when wake-up sensors are registered
|
// state of the connection. FDs are added to the looper when wake-up sensors are registered
|
||||||
// (to poll for acknowledgements) and when write fails on the socket when there are too many
|
// (to poll for acknowledgements) and when write fails on the socket when there are too many
|
||||||
// events (to poll when the FD is available for writing). FDs are removed when there is an
|
|
||||||
// error and the other end hangs up or when this client unregisters for this connection.
|
// error and the other end hangs up or when this client unregisters for this connection.
|
||||||
void updateLooperRegistration(const sp<Looper>& looper);
|
void updateLooperRegistration(const sp<Looper>& looper);
|
||||||
void updateLooperRegistrationLocked(const sp<Looper>& looper);
|
void updateLooperRegistrationLocked(const sp<Looper>& looper);
|
||||||
@ -169,6 +190,7 @@ class SensorService :
|
|||||||
KeyedVector<int, FlushInfo> mSensorInfo;
|
KeyedVector<int, FlushInfo> mSensorInfo;
|
||||||
sensors_event_t *mEventCache;
|
sensors_event_t *mEventCache;
|
||||||
int mCacheSize, mMaxCacheSize;
|
int mCacheSize, mMaxCacheSize;
|
||||||
|
String8 mPackageName;
|
||||||
|
|
||||||
#if DEBUG_CONNECTIONS
|
#if DEBUG_CONNECTIONS
|
||||||
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
||||||
@ -176,7 +198,7 @@ class SensorService :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SensorEventConnection(const sp<SensorService>& service, uid_t uid);
|
SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName);
|
||||||
|
|
||||||
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,
|
||||||
@ -190,6 +212,7 @@ class SensorService :
|
|||||||
void dump(String8& result);
|
void dump(String8& result);
|
||||||
bool needsWakeLock();
|
bool needsWakeLock();
|
||||||
void resetWakeLockRefCount();
|
void resetWakeLockRefCount();
|
||||||
|
String8 getPackageName() const;
|
||||||
|
|
||||||
uid_t getUid() const { return mUid; }
|
uid_t getUid() const { return mUid; }
|
||||||
};
|
};
|
||||||
@ -208,6 +231,7 @@ class SensorService :
|
|||||||
void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
|
void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
|
||||||
void removeFirstPendingFlushConnection();
|
void removeFirstPendingFlushConnection();
|
||||||
SensorEventConnection * getFirstPendingFlushConnection();
|
SensorEventConnection * getFirstPendingFlushConnection();
|
||||||
|
void clearAllPendingFlushConnections();
|
||||||
};
|
};
|
||||||
|
|
||||||
class SensorEventAckReceiver : public Thread {
|
class SensorEventAckReceiver : public Thread {
|
||||||
@ -261,6 +285,11 @@ class SensorService :
|
|||||||
// to the output vector.
|
// to the output vector.
|
||||||
void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
|
void populateActiveConnections(SortedVector< sp<SensorEventConnection> >* activeConnections);
|
||||||
|
|
||||||
|
// If SensorService is operating in RESTRICTED mode, only select whitelisted packages are
|
||||||
|
// allowed to register for or call flush on sensors. Typically only cts test packages are
|
||||||
|
// allowed.
|
||||||
|
bool isWhiteListedPackage(const String8& packageName);
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
Vector<Sensor> mSensorList;
|
Vector<Sensor> mSensorList;
|
||||||
Vector<Sensor> mUserSensorListDebug;
|
Vector<Sensor> mUserSensorListDebug;
|
||||||
@ -282,6 +311,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;
|
||||||
|
|
||||||
// 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