Add body sensors app op - framework native

Change-Id: I727a2bb1e28ae9158f2df9c74dd0aee977dfd47f
This commit is contained in:
Svetoslav 2015-04-29 16:50:41 -07:00
parent 61a3c8dec9
commit b412f6e203
18 changed files with 195 additions and 78 deletions

View File

@ -192,17 +192,6 @@ typedef ASensorRef const* ASensorList;
/*****************************************************************************/ /*****************************************************************************/
/*
* Get a reference to the sensor manager. ASensorManager is a singleton.
*
* Example:
*
* ASensorManager* sensorManager = ASensorManager_getInstance();
*
*/
ASensorManager* ASensorManager_getInstance();
/* /*
* Returns the list of available sensors. * Returns the list of available sensors.
*/ */

View File

@ -87,7 +87,11 @@ public:
OP_ASSIST_STRUCTURE = 49, OP_ASSIST_STRUCTURE = 49,
OP_ASSIST_SCREENSHOT = 50, OP_ASSIST_SCREENSHOT = 50,
OP_READ_PHONE_STATE = 51, OP_READ_PHONE_STATE = 51,
OP_ADD_VOICEMAIL = 52 OP_ADD_VOICEMAIL = 52,
OP_USE_SIP = 53,
OP_PROCESS_OUTGOING_CALLS = 54,
OP_USE_FINGERPRINT = 55,
OP_BODY_SENSORS = 56
}; };
AppOpsManager(); AppOpsManager();
@ -99,6 +103,7 @@ public:
void startWatchingMode(int32_t op, const String16& packageName, void startWatchingMode(int32_t op, const String16& packageName,
const sp<IAppOpsCallback>& callback); const sp<IAppOpsCallback>& callback);
void stopWatchingMode(const sp<IAppOpsCallback>& callback); void stopWatchingMode(const sp<IAppOpsCallback>& callback);
int32_t permissionToOpCode(const String16& permission);
private: private:
Mutex mLock; Mutex mLock;

View File

@ -40,6 +40,7 @@ public:
const sp<IAppOpsCallback>& callback) = 0; const sp<IAppOpsCallback>& callback) = 0;
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0; virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) = 0; virtual sp<IBinder> getToken(const sp<IBinder>& clientToken) = 0;
virtual int32_t permissionToOpCode(const String16& permission) = 0;
enum { enum {
CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, CHECK_OPERATION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
@ -49,6 +50,7 @@ public:
START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4, START_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+4,
STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5, STOP_WATCHING_MODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+5,
GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6, GET_TOKEN_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+6,
PERMISSION_TO_OP_CODE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION+7,
}; };
enum { enum {

View File

@ -34,9 +34,12 @@ public:
virtual void getPackagesForUid(const uid_t uid, Vector<String16> &packages) = 0; virtual void getPackagesForUid(const uid_t uid, Vector<String16> &packages) = 0;
virtual bool isRuntimePermission(const String16& permission) = 0;
enum { enum {
CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
GET_PACKAGES_FOR_UID_TRANSACTION = CHECK_PERMISSION_TRANSACTION + 1 GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2
}; };
}; };

View File

@ -37,9 +37,9 @@ class ISensorServer : public IInterface
public: public:
DECLARE_META_INTERFACE(SensorServer); DECLARE_META_INTERFACE(SensorServer);
virtual Vector<Sensor> getSensorList() = 0; virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
int mode) = 0; int mode, const String16& opPackageName) = 0;
virtual status_t enableDataInjection(int enable) = 0; virtual status_t enableDataInjection(int enable) = 0;
}; };

View File

@ -71,6 +71,8 @@ public:
uint32_t getFifoMaxEventCount() const; uint32_t getFifoMaxEventCount() const;
const String8& getStringType() const; const String8& getStringType() const;
const String8& getRequiredPermission() const; const String8& getRequiredPermission() const;
bool isRequiredPermissionRuntime() const;
int32_t getRequiredAppOp() const;
int32_t getMaxDelay() const; int32_t getMaxDelay() const;
uint32_t getFlags() const; uint32_t getFlags() const;
bool isWakeUpSensor() const; bool isWakeUpSensor() const;
@ -97,6 +99,8 @@ private:
uint32_t mFifoMaxEventCount; uint32_t mFifoMaxEventCount;
String8 mStringType; String8 mStringType;
String8 mRequiredPermission; String8 mRequiredPermission;
bool mRequiredPermissionRuntime = false;
int32_t mRequiredAppOp;
int32_t mMaxDelay; int32_t mMaxDelay;
uint32_t mFlags; uint32_t mFlags;
static void flattenString8(void*& buffer, size_t& size, const String8& string8); static void flattenString8(void*& buffer, size_t& size, const String8& string8);

View File

@ -23,6 +23,7 @@
#include <utils/Errors.h> #include <utils/Errors.h>
#include <utils/RefBase.h> #include <utils/RefBase.h>
#include <utils/Timers.h> #include <utils/Timers.h>
#include <utils/String16.h>
#include <gui/BitTube.h> #include <gui/BitTube.h>
@ -52,7 +53,7 @@ public:
enum { MAX_RECEIVE_BUFFER_EVENT_COUNT = 256 }; enum { MAX_RECEIVE_BUFFER_EVENT_COUNT = 256 };
SensorEventQueue(const sp<ISensorEventConnection>& connection); SensorEventQueue(const sp<ISensorEventConnection>& connection);
virtual ~SensorEventQueue(); virtual ~SensorEventQueue();
virtual void onFirstRef(); virtual void onFirstRef();

View File

@ -44,11 +44,10 @@ class SensorEventQueue;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class SensorManager : class SensorManager :
public ASensorManager, public ASensorManager
public Singleton<SensorManager>
{ {
public: public:
SensorManager(); SensorManager(const String16& opPackageName);
~SensorManager(); ~SensorManager();
ssize_t getSensorList(Sensor const* const** list) const; ssize_t getSensorList(Sensor const* const** list) const;
@ -68,6 +67,7 @@ private:
mutable Sensor const** mSensorList; mutable Sensor const** mSensorList;
mutable Vector<Sensor> mSensors; mutable Vector<Sensor> mSensors;
mutable sp<IBinder::DeathRecipient> mDeathObserver; mutable sp<IBinder::DeathRecipient> mDeathObserver;
const String16 mOpPackageName;
}; };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -104,4 +104,13 @@ void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) {
} }
} }
int32_t AppOpsManager::permissionToOpCode(const String16& permission) {
sp<IAppOpsService> service = getService();
if (service != NULL) {
return service->permissionToOpCode(permission);
}
return -1;
}
}; // namespace android }; // namespace android

View File

@ -111,6 +111,17 @@ public:
if (reply.readExceptionCode() != 0) return NULL; if (reply.readExceptionCode() != 0) return NULL;
return reply.readStrongBinder(); return reply.readStrongBinder();
} }
virtual int32_t permissionToOpCode(const String16& permission) {
Parcel data, reply;
data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
data.writeString16(permission);
remote()->transact(PERMISSION_TO_OP_CODE_TRANSACTION, data, &reply);
// fail on exception
if (reply.readExceptionCode() != 0) return -1;
return reply.readInt32();
}
}; };
IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService"); IMPLEMENT_META_INTERFACE(AppOpsService, "com.android.internal.app.IAppOpsService");
@ -187,6 +198,14 @@ status_t BnAppOpsService::onTransact(
reply->writeStrongBinder(token); reply->writeStrongBinder(token);
return NO_ERROR; return NO_ERROR;
} break; } break;
case PERMISSION_TO_OP_CODE_TRANSACTION: {
CHECK_INTERFACE(IAppOpsService, data, reply);
String16 permission = data.readString16();
const int32_t opCode = permissionToOpCode(permission);
reply->writeNoException();
reply->writeInt32(opCode);
return NO_ERROR;
} break;
default: default:
return BBinder::onTransact(code, data, reply, flags); return BBinder::onTransact(code, data, reply, flags);
} }

View File

@ -67,6 +67,17 @@ public:
packages.push(reply.readString16()); packages.push(reply.readString16());
} }
} }
virtual bool isRuntimePermission(const String16& permission)
{
Parcel data, reply;
data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
data.writeString16(permission);
remote()->transact(IS_RUNTIME_PERMISSION_TRANSACTION, data, &reply);
// fail on exception
if (reply.readExceptionCode() != 0) return false;
return reply.readInt32() != 0;
}
}; };
IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController"); IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController");
@ -102,6 +113,15 @@ status_t BnPermissionController::onTransact(
return NO_ERROR; return NO_ERROR;
} break; } break;
case IS_RUNTIME_PERMISSION_TRANSACTION: {
CHECK_INTERFACE(IPermissionController, data, reply);
String16 permission = data.readString16();
const bool res = isRuntimePermission(permission);
reply->writeNoException();
reply->writeInt32(res ? 1 : 0);
return NO_ERROR;
} break;
default: default:
return BBinder::onTransact(code, data, reply, flags); return BBinder::onTransact(code, data, reply, flags);
} }

View File

@ -48,10 +48,11 @@ public:
virtual ~BpSensorServer(); virtual ~BpSensorServer();
virtual Vector<Sensor> getSensorList() virtual Vector<Sensor> getSensorList(const String16& opPackageName)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
data.writeString16(opPackageName);
remote()->transact(GET_SENSOR_LIST, data, &reply); remote()->transact(GET_SENSOR_LIST, data, &reply);
Sensor s; Sensor s;
Vector<Sensor> v; Vector<Sensor> v;
@ -65,12 +66,13 @@ public:
} }
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
int mode) int mode, const String16& opPackageName)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
data.writeString8(packageName); data.writeString8(packageName);
data.writeInt32(mode); data.writeInt32(mode);
data.writeString16(opPackageName);
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());
} }
@ -98,7 +100,8 @@ status_t BnSensorServer::onTransact(
switch(code) { switch(code) {
case GET_SENSOR_LIST: { case GET_SENSOR_LIST: {
CHECK_INTERFACE(ISensorServer, data, reply); CHECK_INTERFACE(ISensorServer, data, reply);
Vector<Sensor> v(getSensorList()); const String16& opPackageName = data.readString16();
Vector<Sensor> v(getSensorList(opPackageName));
size_t n = v.size(); size_t n = v.size();
reply->writeUint32(static_cast<uint32_t>(n)); reply->writeUint32(static_cast<uint32_t>(n));
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
@ -110,7 +113,9 @@ status_t BnSensorServer::onTransact(
CHECK_INTERFACE(ISensorServer, data, reply); CHECK_INTERFACE(ISensorServer, data, reply);
String8 packageName = data.readString8(); String8 packageName = data.readString8();
int32_t mode = data.readInt32(); int32_t mode = data.readInt32();
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode)); const String16& opPackageName = data.readString16();
sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode,
opPackageName));
reply->writeStrongBinder(IInterface::asBinder(connection)); reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR; return NO_ERROR;
} }

View File

@ -25,6 +25,9 @@
#include <hardware/sensors.h> #include <hardware/sensors.h>
#include <binder/AppOpsManager.h>
#include <binder/IServiceManager.h>
#include <gui/Sensor.h> #include <gui/Sensor.h>
#include <log/log.h> #include <log/log.h>
@ -113,11 +116,13 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED; mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
mFlags |= SENSOR_FLAG_CONTINUOUS_MODE; mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break; break;
case SENSOR_TYPE_HEART_RATE: case SENSOR_TYPE_HEART_RATE: {
mStringType = SENSOR_STRING_TYPE_HEART_RATE; mStringType = SENSOR_STRING_TYPE_HEART_RATE;
mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS; mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
AppOpsManager appOps;
mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break; } break;
case SENSOR_TYPE_LIGHT: case SENSOR_TYPE_LIGHT:
mStringType = SENSOR_STRING_TYPE_LIGHT; mStringType = SENSOR_STRING_TYPE_LIGHT;
mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
@ -252,6 +257,17 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
} }
} }
if (mRequiredPermission.length() > 0) {
// If the sensor is protected by a permission we need to know if it is
// a runtime one to determine whether we can use the permission cache.
sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
if (binder != 0) {
sp<IPermissionController> permCtrl = interface_cast<IPermissionController>(binder);
mRequiredPermissionRuntime = permCtrl->isRuntimePermission(
String16(mRequiredPermission));
}
}
} }
Sensor::~Sensor() Sensor::~Sensor()
@ -318,6 +334,14 @@ const String8& Sensor::getRequiredPermission() const {
return mRequiredPermission; return mRequiredPermission;
} }
bool Sensor::isRequiredPermissionRuntime() const {
return mRequiredPermissionRuntime;
}
int32_t Sensor::getRequiredAppOp() const {
return mRequiredAppOp;
}
int32_t Sensor::getMaxDelay() const { int32_t Sensor::getMaxDelay() const {
return mMaxDelay; return mMaxDelay;
} }
@ -339,7 +363,8 @@ size_t Sensor::getFlattenedSize() const
size_t fixedSize = size_t fixedSize =
sizeof(int32_t) * 3 + sizeof(int32_t) * 3 +
sizeof(float) * 4 + sizeof(float) * 4 +
sizeof(int32_t) * 5; sizeof(int32_t) * 6 +
sizeof(bool);
size_t variableSize = size_t variableSize =
sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) + sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
@ -369,6 +394,8 @@ status_t Sensor::flatten(void* buffer, size_t size) const {
FlattenableUtils::write(buffer, size, mFifoMaxEventCount); FlattenableUtils::write(buffer, size, mFifoMaxEventCount);
flattenString8(buffer, size, mStringType); flattenString8(buffer, size, mStringType);
flattenString8(buffer, size, mRequiredPermission); flattenString8(buffer, size, mRequiredPermission);
FlattenableUtils::write(buffer, size, mRequiredPermissionRuntime);
FlattenableUtils::write(buffer, size, mRequiredAppOp);
FlattenableUtils::write(buffer, size, mMaxDelay); FlattenableUtils::write(buffer, size, mMaxDelay);
FlattenableUtils::write(buffer, size, mFlags); FlattenableUtils::write(buffer, size, mFlags);
return NO_ERROR; return NO_ERROR;
@ -407,6 +434,8 @@ status_t Sensor::unflatten(void const* buffer, size_t size) {
if (!unflattenString8(buffer, size, mRequiredPermission)) { if (!unflattenString8(buffer, size, mRequiredPermission)) {
return NO_MEMORY; return NO_MEMORY;
} }
FlattenableUtils::read(buffer, size, mRequiredPermissionRuntime);
FlattenableUtils::read(buffer, size, mRequiredAppOp);
FlattenableUtils::read(buffer, size, mMaxDelay); FlattenableUtils::read(buffer, size, mMaxDelay);
FlattenableUtils::read(buffer, size, mFlags); FlattenableUtils::read(buffer, size, mFlags);
return NO_ERROR; return NO_ERROR;

View File

@ -36,10 +36,8 @@
namespace android { namespace android {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager) SensorManager::SensorManager(const String16& opPackageName)
: mSensorList(0), mOpPackageName(opPackageName)
SensorManager::SensorManager()
: mSensorList(0)
{ {
// okay we're not locked here, but it's not needed during construction // okay we're not locked here, but it's not needed during construction
assertStateLocked(); assertStateLocked();
@ -88,7 +86,7 @@ status_t SensorManager::assertStateLocked() const {
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this)); mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver); IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
mSensors = mSensorServer->getSensorList(); mSensors = mSensorServer->getSensorList(mOpPackageName);
size_t count = mSensors.size(); size_t count = mSensors.size();
mSensorList = mSensorList =
static_cast<Sensor const**>(malloc(count * sizeof(Sensor*))); static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
@ -143,7 +141,7 @@ sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mo
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, mode); mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
if (connection == NULL) { if (connection == NULL) {
// SensorService just died or the app doesn't have required permissions. // SensorService just died or the app doesn't have required permissions.
ALOGE("createEventQueue: connection is NULL."); ALOGE("createEventQueue: connection is NULL.");

View File

@ -379,14 +379,14 @@ void SensorDevice::disableAllSensors() {
sensor_handle, 0); sensor_handle, 0);
// Add all the connections that were registered for this sensor to the disabled // Add all the connections that were registered for this sensor to the disabled
// clients list. // clients list.
for (int j = 0; j < info.batchParams.size(); ++j) { for (size_t j = 0; j < info.batchParams.size(); ++j) {
mDisabledClients.add(info.batchParams.keyAt(j)); mDisabledClients.add(info.batchParams.keyAt(j));
} }
} }
} }
} }
status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event, size_t count) { status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) {
ALOGD_IF(DEBUG_CONNECTIONS, ALOGD_IF(DEBUG_CONNECTIONS,
"sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f", "sensor_event handle=%d ts=%lld data=%.2f, %.2f, %.2f %.2f %.2f %.2f",
injected_sensor_event->sensor, injected_sensor_event->sensor,

View File

@ -102,7 +102,7 @@ public:
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); status_t injectSensorData(const sensors_event_t *event);
void dump(String8& result); void dump(String8& result);
}; };

View File

@ -31,6 +31,7 @@
#include <utils/Singleton.h> #include <utils/Singleton.h>
#include <utils/String16.h> #include <utils/String16.h>
#include <binder/AppOpsManager.h>
#include <binder/BinderService.h> #include <binder/BinderService.h>
#include <binder/IServiceManager.h> #include <binder/IServiceManager.h>
#include <binder/PermissionCache.h> #include <binder/PermissionCache.h>
@ -156,7 +157,7 @@ void SensorService::onFirstRef()
// Check if the device really supports batching by looking at the FIFO event // Check if the device really supports batching by looking at the FIFO event
// counts for each sensor. // counts for each sensor.
bool batchingSupported = false; bool batchingSupported = false;
for (int i = 0; i < mSensorList.size(); ++i) { for (size_t i = 0; i < mSensorList.size(); ++i) {
if (mSensorList[i].getFifoMaxEventCount() > 0) { if (mSensorList[i].getFifoMaxEventCount() > 0) {
batchingSupported = true; batchingSupported = true;
break; break;
@ -666,7 +667,7 @@ SensorService::SensorRecord * SensorService::getSensorRecord(int handle) {
return mActiveSensors.valueFor(handle); return mActiveSensors.valueFor(handle);
} }
Vector<Sensor> SensorService::getSensorList() Vector<Sensor> SensorService::getSensorList(const String16& opPackageName)
{ {
char value[PROPERTY_VALUE_MAX]; char value[PROPERTY_VALUE_MAX];
property_get("debug.sensors", value, "0"); property_get("debug.sensors", value, "0");
@ -675,19 +676,20 @@ Vector<Sensor> SensorService::getSensorList()
Vector<Sensor> accessibleSensorList; Vector<Sensor> accessibleSensorList;
for (size_t i = 0; i < initialSensorList.size(); i++) { for (size_t i = 0; i < initialSensorList.size(); i++) {
Sensor sensor = initialSensorList[i]; Sensor sensor = initialSensorList[i];
if (canAccessSensor(sensor)) { if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
accessibleSensorList.add(sensor); accessibleSensorList.add(sensor);
} else { } else {
ALOGI("Skipped sensor %s because it requires permission %s", ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
sensor.getName().string(), sensor.getName().string(),
sensor.getRequiredPermission().string()); sensor.getRequiredPermission().string(),
sensor.getRequiredAppOp());
} }
} }
return accessibleSensorList; return accessibleSensorList;
} }
sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName, sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
int requestedMode) { int requestedMode, const String16& opPackageName) {
// Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION. // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) { if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
return NULL; return NULL;
@ -700,7 +702,7 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri
Mutex::Autolock _l(mLock); 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)); requestedMode == DATA_INJECTION, opPackageName));
if (requestedMode == DATA_INJECTION) { if (requestedMode == DATA_INJECTION) {
if (mActiveConnections.indexOf(result) < 0) { if (mActiveConnections.indexOf(result) < 0) {
mActiveConnections.add(result); mActiveConnections.add(result);
@ -802,7 +804,8 @@ 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,
const String16& opPackageName)
{ {
if (mInitCheck != NO_ERROR) if (mInitCheck != NO_ERROR)
return mInitCheck; return mInitCheck;
@ -812,7 +815,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
return BAD_VALUE; return BAD_VALUE;
} }
if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) { if (!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
return BAD_VALUE; return BAD_VALUE;
} }
@ -950,7 +953,7 @@ status_t SensorService::cleanupWithoutDisableLocked(
} }
status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection, status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
int handle, nsecs_t ns) int handle, nsecs_t ns, const String16& opPackageName)
{ {
if (mInitCheck != NO_ERROR) if (mInitCheck != NO_ERROR)
return mInitCheck; return mInitCheck;
@ -959,7 +962,7 @@ status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection
if (!sensor) if (!sensor)
return BAD_VALUE; return BAD_VALUE;
if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) { if (!canAccessSensor(sensor->getSensor(), "Tried configuring", opPackageName)) {
return BAD_VALUE; return BAD_VALUE;
} }
@ -974,7 +977,8 @@ status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection
return sensor->setDelay(connection.get(), handle, ns); return sensor->setDelay(connection.get(), handle, ns);
} }
status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection) { status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
const String16& opPackageName) {
if (mInitCheck != NO_ERROR) return mInitCheck; if (mInitCheck != NO_ERROR) return mInitCheck;
SensorDevice& dev(SensorDevice::getInstance()); SensorDevice& dev(SensorDevice::getInstance());
const int halVersion = dev.getHalDeviceVersion(); const int halVersion = dev.getHalDeviceVersion();
@ -994,6 +998,10 @@ status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection)
// flush complete event. // flush complete event.
connection->incrementPendingFlushCount(handle); connection->incrementPendingFlushCount(handle);
} else { } else {
if (!canAccessSensor(sensor->getSensor(), "Tried flushing", opPackageName)) {
err = INVALID_OPERATION;
continue;
}
status_t err_flush = sensor->flush(connection.get(), handle); status_t err_flush = sensor->flush(connection.get(), handle);
if (err_flush == NO_ERROR) { if (err_flush == NO_ERROR) {
SensorRecord* rec = mActiveSensors.valueFor(handle); SensorRecord* rec = mActiveSensors.valueFor(handle);
@ -1005,23 +1013,42 @@ status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection)
return err; return err;
} }
bool SensorService::canAccessSensor(const Sensor& sensor) { bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
return (sensor.getRequiredPermission().isEmpty()) || const String16& opPackageName) {
PermissionCache::checkCallingPermission(String16(sensor.getRequiredPermission())); const String8& requiredPermission = sensor.getRequiredPermission();
}
bool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) { if (requiredPermission.length() <= 0) {
if (canAccessSensor(sensor)) {
return true; return true;
}
bool hasPermission = false;
// Runtime permissions can't use the cache as they may change.
if (sensor.isRequiredPermissionRuntime()) {
hasPermission = checkPermission(String16(requiredPermission),
IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid());
} else { } else {
String8 errorMessage; hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission));
errorMessage.appendFormat( }
"%s a sensor (%s) without holding its required permission: %s",
operation, if (!hasPermission) {
sensor.getName().string(), ALOGE("%s a sensor (%s) without holding its required permission: %s",
sensor.getRequiredPermission().string()); operation, sensor.getName().string(), sensor.getRequiredPermission().string());
return false; return false;
} }
const int32_t opCode = sensor.getRequiredAppOp();
if (opCode >= 0) {
AppOpsManager appOps;
if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName)
!= AppOpsManager::MODE_ALLOWED) {
ALOGE("%s a sensor (%s) without enabled required app op: %D",
operation, sensor.getName().string(), opCode);
return false;
}
}
return true;
} }
bool SensorService::hasDataInjectionPermissions() { bool SensorService::hasDataInjectionPermissions() {
@ -1144,10 +1171,11 @@ void SensorService::SensorRecord::clearAllPendingFlushConnections() {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
SensorService::SensorEventConnection::SensorEventConnection( SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode) const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
const String16& opPackageName)
: 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), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
mDataInjectionMode(isDataInjectionMode) { mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
mChannel = new BitTube(mService->mSocketBufferSize); mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS #if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0; mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@ -1205,7 +1233,8 @@ void SensorService::SensorEventConnection::dump(String8& result) {
bool SensorService::SensorEventConnection::addSensor(int32_t handle) { bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
Mutex::Autolock _l(mConnectionLock); Mutex::Autolock _l(mConnectionLock);
if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) { if (!canAccessSensor(mService->getSensorFromHandle(handle),
"Tried adding", mOpPackageName)) {
return false; return false;
} }
if (mSensorInfo.indexOfKey(handle) < 0) { if (mSensorInfo.indexOfKey(handle) < 0) {
@ -1324,7 +1353,7 @@ status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t* scratch, sensors_event_t* scratch,
SensorEventConnection const * const * mapFlushEventsToConnections) { SensorEventConnection const * const * mapFlushEventsToConnections) {
// filter out events not for this connection // filter out events not for this connection
size_t count = 0; int count = 0;
Mutex::Autolock _l(mConnectionLock); Mutex::Autolock _l(mConnectionLock);
if (scratch) { if (scratch) {
size_t i=0; size_t i=0;
@ -1616,7 +1645,7 @@ status_t SensorService::SensorEventConnection::enableDisable(
status_t err; status_t err;
if (enabled) { if (enabled) {
err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs, err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
reservedFlags); reservedFlags, mOpPackageName);
} else { } else {
err = mService->disable(this, handle); err = mService->disable(this, handle);
@ -1627,11 +1656,11 @@ status_t SensorService::SensorEventConnection::enableDisable(
status_t SensorService::SensorEventConnection::setEventRate( status_t SensorService::SensorEventConnection::setEventRate(
int handle, nsecs_t samplingPeriodNs) int handle, nsecs_t samplingPeriodNs)
{ {
return mService->setEventRate(this, handle, samplingPeriodNs); return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
} }
status_t SensorService::SensorEventConnection::flush() { status_t SensorService::SensorEventConnection::flush() {
return mService->flushSensor(this); return mService->flushSensor(this, mOpPackageName);
} }
int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) { int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
@ -1674,7 +1703,7 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
memcpy(&sensor_event, buf, sizeof(sensors_event_t)); memcpy(&sensor_event, buf, sizeof(sensors_event_t));
Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor); Sensor sensor = mService->getSensorFromHandle(sensor_event.sensor);
sensor_event.type = sensor.getType(); sensor_event.type = sensor.getType();
dev.injectSensorData(&sensor_event, 1); dev.injectSensorData(&sensor_event);
#if DEBUG_CONNECTIONS #if DEBUG_CONNECTIONS
++mEventsReceived; ++mEventsReceived;
#endif #endif
@ -1714,8 +1743,8 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void*
} }
int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const { int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
int fifoWakeUpSensors = 0; size_t fifoWakeUpSensors = 0;
int fifoNonWakeUpSensors = 0; size_t fifoNonWakeUpSensors = 0;
for (size_t i = 0; i < mSensorInfo.size(); ++i) { for (size_t i = 0; i < mSensorInfo.size(); ++i) {
const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i)); const Sensor& sensor = mService->getSensorFromHandle(mSensorInfo.keyAt(i));
if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) { if (sensor.getFifoReservedEventCount() == sensor.getFifoMaxEventCount()) {

View File

@ -111,9 +111,9 @@ class SensorService :
virtual bool threadLoop(); virtual bool threadLoop();
// ISensorServer interface // ISensorServer interface
virtual Vector<Sensor> getSensorList(); virtual Vector<Sensor> getSensorList(const String16& opPackageName);
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
int requestedMode); int requestedMode, const String16& opPackageName);
virtual status_t enableDataInjection(int enable); 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);
@ -207,6 +207,7 @@ class SensorService :
sensors_event_t *mEventCache; sensors_event_t *mEventCache;
int mCacheSize, mMaxCacheSize; int mCacheSize, mMaxCacheSize;
String8 mPackageName; String8 mPackageName;
const String16 mOpPackageName;
#if DEBUG_CONNECTIONS #if DEBUG_CONNECTIONS
int mEventsReceived, mEventsSent, mEventsSentFromCache; int mEventsReceived, mEventsSent, mEventsSentFromCache;
int mTotalAcksNeeded, mTotalAcksReceived; int mTotalAcksNeeded, mTotalAcksReceived;
@ -214,7 +215,7 @@ class SensorService :
public: public:
SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName, SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName,
bool isDataInjectionMode); bool isDataInjectionMode, const String16& opPackageName);
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,
@ -271,8 +272,8 @@ class SensorService :
const sp<SensorEventConnection>& connection, int handle); const sp<SensorEventConnection>& connection, int handle);
void cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection, void cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
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, const char* operation,
static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation); const String16& opPackageName);
static bool hasDataInjectionPermissions(); 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
@ -340,10 +341,13 @@ class SensorService :
public: public:
void cleanupConnection(SensorEventConnection* connection); void cleanupConnection(SensorEventConnection* connection);
status_t enable(const sp<SensorEventConnection>& connection, int handle, status_t enable(const sp<SensorEventConnection>& connection, int handle,
nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags); nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName);
status_t disable(const sp<SensorEventConnection>& connection, int handle); status_t disable(const sp<SensorEventConnection>& connection, int handle);
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns); status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns,
status_t flushSensor(const sp<SensorEventConnection>& connection); const String16& opPackageName);
status_t flushSensor(const sp<SensorEventConnection>& connection,
const String16& opPackageName);
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------