Support restricted mode in SensorService.
In restricted mode, only CTS tests can register for sensors or call flush() on them. The requests from other applications will be ignored. Change-Id: Ieb923df3e0cfe3390fe2d052af776da79589744b
This commit is contained in:
parent
5b20fd0882
commit
4949c50372
@ -30,6 +30,7 @@ namespace android {
|
||||
|
||||
class Sensor;
|
||||
class ISensorEventConnection;
|
||||
class String8;
|
||||
|
||||
class ISensorServer : public IInterface
|
||||
{
|
||||
@ -37,7 +38,7 @@ public:
|
||||
DECLARE_META_INTERFACE(SensorServer);
|
||||
|
||||
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 Sensor;
|
||||
class SensorEventQueue;
|
||||
|
||||
class String8;
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class SensorManager :
|
||||
@ -53,7 +53,7 @@ public:
|
||||
|
||||
ssize_t getSensorList(Sensor const* const** list) const;
|
||||
Sensor const* getDefaultSensor(int type);
|
||||
sp<SensorEventQueue> createEventQueue();
|
||||
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""));
|
||||
|
||||
private:
|
||||
// DeathRecipient interface
|
||||
|
@ -63,10 +63,11 @@ public:
|
||||
return v;
|
||||
}
|
||||
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection()
|
||||
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
|
||||
data.writeString8(packageName);
|
||||
remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
|
||||
return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
|
||||
}
|
||||
@ -96,7 +97,8 @@ status_t BnSensorServer::onTransact(
|
||||
}
|
||||
case CREATE_SENSOR_EVENT_CONNECTION: {
|
||||
CHECK_INTERFACE(ISensorServer, data, reply);
|
||||
sp<ISensorEventConnection> connection(createSensorEventConnection());
|
||||
String8 packageName = data.readString8();
|
||||
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName));
|
||||
reply->writeStrongBinder(IInterface::asBinder(connection));
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
@ -139,14 +139,14 @@ Sensor const* SensorManager::getDefaultSensor(int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sp<SensorEventQueue> SensorManager::createEventQueue()
|
||||
sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName)
|
||||
{
|
||||
sp<SensorEventQueue> queue;
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
while (assertStateLocked() == NO_ERROR) {
|
||||
sp<ISensorEventConnection> connection =
|
||||
mSensorServer->createSensorEventConnection();
|
||||
mSensorServer->createSensorEventConnection(packageName);
|
||||
if (connection == NULL) {
|
||||
// SensorService just died.
|
||||
ALOGE("createEventQueue: connection is NULL. SensorService died.");
|
||||
|
@ -85,6 +85,7 @@ void SensorDevice::dump(String8& result)
|
||||
Mutex::Autolock _l(mLock);
|
||||
for (size_t i=0 ; i<size_t(count) ; i++) {
|
||||
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,
|
||||
info.batchParams.size());
|
||||
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) {
|
||||
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.size() == 1) {
|
||||
if (info.numActiveClients() == 1) {
|
||||
// This is the first connection, we need to activate the underlying h/w sensor.
|
||||
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));
|
||||
|
||||
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.
|
||||
actuateHardware = true;
|
||||
} else {
|
||||
@ -181,10 +186,15 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
|
||||
} else {
|
||||
// sensor wasn't enabled for this ident
|
||||
}
|
||||
|
||||
if (isClientDisabledLocked(ident)) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
|
||||
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().
|
||||
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,
|
||||
info.bestBatchParams.batchDelay);
|
||||
mSensorDevice->setDelay(
|
||||
@ -279,6 +289,7 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodN
|
||||
samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
if (isClientDisabledLocked(ident)) return INVALID_OPERATION;
|
||||
Info& info( mActivationCount.editValueFor(handle) );
|
||||
// If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
|
||||
// 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 {
|
||||
if (!mSensorDevice) return -1;
|
||||
|
||||
return mSensorDevice->common.version;
|
||||
}
|
||||
|
||||
@ -306,12 +316,89 @@ status_t SensorDevice::flush(void* ident, int handle) {
|
||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
if (isClientDisabled(ident)) return INVALID_OPERATION;
|
||||
ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", 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,
|
||||
int64_t samplingPeriodNs,
|
||||
int64_t maxBatchReportLatencyNs) {
|
||||
@ -329,19 +416,16 @@ status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
|
||||
}
|
||||
|
||||
void SensorDevice::Info::selectBatchParams() {
|
||||
BatchParams bestParams(-1, -1, -1);
|
||||
BatchParams bestParams(0, -1, -1);
|
||||
SensorDevice& device(SensorDevice::getInstance());
|
||||
|
||||
if (batchParams.size() > 0) {
|
||||
BatchParams params = batchParams.valueAt(0);
|
||||
bestParams = params;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < batchParams.size(); ++i) {
|
||||
for (size_t i = 0; i < batchParams.size(); ++i) {
|
||||
if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue;
|
||||
BatchParams params = batchParams.valueAt(i);
|
||||
if (params.batchDelay < bestParams.batchDelay) {
|
||||
if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) {
|
||||
bestParams.batchDelay = params.batchDelay;
|
||||
}
|
||||
if (params.batchTimeout < bestParams.batchTimeout) {
|
||||
if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.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
|
||||
// batch call. For continous mode clients, maxBatchReportLatency is set to zero.
|
||||
struct BatchParams {
|
||||
// TODO: Get rid of flags parameter everywhere.
|
||||
int flags;
|
||||
nsecs_t batchDelay, batchTimeout;
|
||||
BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
|
||||
@ -65,7 +66,7 @@ class SensorDevice : public Singleton<SensorDevice> {
|
||||
// requested by the client.
|
||||
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
|
||||
// in the KeyedVector above.
|
||||
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
|
||||
// the removed ident. If index >=0, ident is present and successfully removed.
|
||||
ssize_t removeBatchParamsForIdent(void* ident);
|
||||
|
||||
int numActiveClients();
|
||||
};
|
||||
DefaultKeyedVector<int, Info> mActivationCount;
|
||||
|
||||
// Use this vector to determine which client is activated or deactivated.
|
||||
SortedVector<void *> mDisabledClients;
|
||||
SensorDevice();
|
||||
|
||||
bool isClientDisabled(void* ident);
|
||||
bool isClientDisabledLocked(void* ident);
|
||||
public:
|
||||
ssize_t getSensorList(sensor_t const** list);
|
||||
status_t initCheck() const;
|
||||
@ -90,6 +98,8 @@ 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);
|
||||
void disableAllSensors();
|
||||
void enableAllSensors();
|
||||
void autoDisable(void *ident, int handle);
|
||||
void dump(String8& result);
|
||||
};
|
||||
|
@ -190,6 +190,7 @@ void SensorService::onFirstRef()
|
||||
mSensorEventBuffer = new sensors_event_t[minBufferSize];
|
||||
mSensorEventScratch = new sensors_event_t[minBufferSize];
|
||||
mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
|
||||
mMode = NORMAL;
|
||||
|
||||
mAckReceiver = new SensorEventAckReceiver(this);
|
||||
mAckReceiver->run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
|
||||
@ -230,7 +231,7 @@ SensorService::~SensorService()
|
||||
|
||||
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;
|
||||
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",
|
||||
IPCThreadState::self()->getCallingPid(),
|
||||
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 {
|
||||
Mutex::Autolock _l(mLock);
|
||||
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",
|
||||
mSocketBufferSize/sizeof(sensors_event_t));
|
||||
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());
|
||||
|
||||
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
|
||||
@ -554,7 +586,6 @@ void SensorService::setWakeLockAcquiredLocked(bool acquire) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SensorService::isWakeLockAcquired() {
|
||||
Mutex::Autolock _l(mLock);
|
||||
return mWakeLockAcquired;
|
||||
@ -630,7 +661,6 @@ bool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
|
||||
return sensor != NULL && sensor->getSensor().isWakeUpSensor();
|
||||
}
|
||||
|
||||
|
||||
SensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
|
||||
return mActiveSensors.valueFor(handle);
|
||||
}
|
||||
@ -655,10 +685,10 @@ Vector<Sensor> SensorService::getSensorList()
|
||||
return accessibleSensorList;
|
||||
}
|
||||
|
||||
sp<ISensorEventConnection> SensorService::createSensorEventConnection()
|
||||
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName)
|
||||
{
|
||||
uid_t uid = IPCThreadState::self()->getCallingUid();
|
||||
sp<SensorEventConnection> result(new SensorEventConnection(this, uid));
|
||||
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -708,7 +738,7 @@ Sensor SensorService::getSensorFromHandle(int handle) const {
|
||||
}
|
||||
|
||||
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)
|
||||
return mInitCheck;
|
||||
@ -723,6 +753,10 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
||||
}
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
if (mMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
SensorRecord* rec = mActiveSensors.valueFor(handle);
|
||||
if (rec == 0) {
|
||||
rec = new SensorRecord(connection);
|
||||
@ -773,7 +807,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
|
||||
"rate=%" PRId64 " timeout== %" PRId64"",
|
||||
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);
|
||||
|
||||
// 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(
|
||||
const sp<SensorEventConnection>& connection)
|
||||
@ -1025,12 +1064,16 @@ SensorService::SensorRecord::getFirstPendingFlushConnection() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SensorService::SensorRecord::clearAllPendingFlushConnections() {
|
||||
mPendingFlushConnections.clear();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
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),
|
||||
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0) {
|
||||
mDead(false), mEventCache(NULL), mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName) {
|
||||
mChannel = new BitTube(mService->mSocketBufferSize);
|
||||
#if DEBUG_CONNECTIONS
|
||||
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
|
||||
@ -1062,8 +1105,8 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() {
|
||||
|
||||
void SensorService::SensorEventConnection::dump(String8& result) {
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
result.appendFormat("\t WakeLockRefCount %d | uid %d | cache size %d | max cache size %d\n",
|
||||
mWakeLockRefCount, mUid, mCacheSize, mMaxCacheSize);
|
||||
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) {
|
||||
const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
|
||||
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
|
||||
@ -1126,6 +1169,10 @@ bool SensorService::SensorEventConnection::hasOneShotSensors() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
String8 SensorService::SensorEventConnection::getPackageName() const {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
|
||||
bool value) {
|
||||
Mutex::Autolock _l(mConnectionLock);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <utils/AndroidThreads.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <binder/BinderService.h>
|
||||
|
||||
@ -65,6 +66,27 @@ class 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 char const* getServiceName() ANDROID_API { return "sensorservice"; }
|
||||
@ -78,7 +100,7 @@ class SensorService :
|
||||
|
||||
// ISensorServer interface
|
||||
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);
|
||||
|
||||
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
|
||||
// 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
|
||||
// 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.
|
||||
void updateLooperRegistration(const sp<Looper>& looper);
|
||||
void updateLooperRegistrationLocked(const sp<Looper>& looper);
|
||||
@ -169,6 +190,7 @@ class SensorService :
|
||||
KeyedVector<int, FlushInfo> mSensorInfo;
|
||||
sensors_event_t *mEventCache;
|
||||
int mCacheSize, mMaxCacheSize;
|
||||
String8 mPackageName;
|
||||
|
||||
#if DEBUG_CONNECTIONS
|
||||
int mEventsReceived, mEventsSent, mEventsSentFromCache;
|
||||
@ -176,7 +198,7 @@ class SensorService :
|
||||
#endif
|
||||
|
||||
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,
|
||||
sensors_event_t* scratch,
|
||||
@ -190,6 +212,7 @@ class SensorService :
|
||||
void dump(String8& result);
|
||||
bool needsWakeLock();
|
||||
void resetWakeLockRefCount();
|
||||
String8 getPackageName() const;
|
||||
|
||||
uid_t getUid() const { return mUid; }
|
||||
};
|
||||
@ -208,6 +231,7 @@ class SensorService :
|
||||
void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
|
||||
void removeFirstPendingFlushConnection();
|
||||
SensorEventConnection * getFirstPendingFlushConnection();
|
||||
void clearAllPendingFlushConnections();
|
||||
};
|
||||
|
||||
class SensorEventAckReceiver : public Thread {
|
||||
@ -261,6 +285,11 @@ class SensorService :
|
||||
// to the output vector.
|
||||
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
|
||||
Vector<Sensor> mSensorList;
|
||||
Vector<Sensor> mUserSensorListDebug;
|
||||
@ -282,6 +311,7 @@ class SensorService :
|
||||
bool mWakeLockAcquired;
|
||||
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
|
||||
SensorEventConnection const **mMapFlushEventsToConnections;
|
||||
Mode mMode;
|
||||
|
||||
// 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