From c57a019e117117c5a76c772970b26cd0f5db8c6a Mon Sep 17 00:00:00 2001 From: Etienne Le Grand Date: Mon, 24 Mar 2014 21:28:23 -0700 Subject: [PATCH] Add stringType and requiredPermission to sensors, effectively adding permission checking for sensors Change-Id: If0f3dbdb5d2e9378e1fed4614baee4e750d0c850 --- include/android/sensor.h | 22 ++++ include/gui/Sensor.h | 6 + libs/gui/Sensor.cpp | 158 ++++++++++++++++++----- services/sensorservice/SensorService.cpp | 95 +++++++++++--- services/sensorservice/SensorService.h | 4 +- 5 files changed, 234 insertions(+), 51 deletions(-) diff --git a/include/android/sensor.h b/include/android/sensor.h index 129ea3ebd..b4e7ebee9 100644 --- a/include/android/sensor.h +++ b/include/android/sensor.h @@ -281,6 +281,28 @@ float ASensor_getResolution(ASensor const* sensor); */ int ASensor_getMinDelay(ASensor const* sensor); +/* + * Returns the maximum size of batches for this sensor. Batches will often be + * smaller, as the hardware fifo might be used for other sensors. + */ +int ASensor_getFifoMaxEventCount(ASensor const* sensor); + +/* + * Returns the hardware batch fifo size reserved to this sensor. + */ +int ASensor_getFifoReservedEventCount(ASensor const* sensor); + +/* + * Returns this sensor's string type. + */ +const char* ASensor_getStringType(ASensor const* sensor); + +/* + * Returns the permission required to see or access this sensor, or the + * empty string if none is required. + */ +const char* ASensor_getRequiredPermission(ASensor const* sensor); + #ifdef __cplusplus }; diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h index 0c8142681..033b26296 100644 --- a/include/gui/Sensor.h +++ b/include/gui/Sensor.h @@ -69,6 +69,8 @@ public: int32_t getVersion() const; int32_t getFifoReservedEventCount() const; int32_t getFifoMaxEventCount() const; + const String8& getStringType() const; + const String8& getRequiredPermission() const; // LightFlattenable protocol inline bool isFixedSize() const { return false; } @@ -89,6 +91,10 @@ private: int32_t mVersion; int32_t mFifoReservedEventCount; int32_t mFifoMaxEventCount; + String8 mStringType; + String8 mRequiredPermission; + static void flattenString8(void*& buffer, size_t& size, const String8& string8); + static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8); }; // ---------------------------------------------------------------------------- diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp index da6b0f97f..6f1a3f206 100644 --- a/libs/gui/Sensor.cpp +++ b/libs/gui/Sensor.cpp @@ -48,14 +48,90 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) mResolution = hwSensor->resolution; mPower = hwSensor->power; mMinDelay = hwSensor->minDelay; + // Set fifo event count zero for older devices which do not support batching. Fused // sensors also have their fifo counts set to zero. if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { mFifoReservedEventCount = hwSensor->fifoReservedEventCount; mFifoMaxEventCount = hwSensor->fifoMaxEventCount; - } else { - mFifoReservedEventCount = 0; - mFifoMaxEventCount = 0; + } + + // Ensure existing sensors have correct string type and required + // permissions. + switch (mType) { + case SENSOR_TYPE_ACCELEROMETER: + mStringType = SENSOR_STRING_TYPE_ACCELEROMETER; + break; + case SENSOR_TYPE_AMBIENT_TEMPERATURE: + mStringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE; + break; + case SENSOR_TYPE_GAME_ROTATION_VECTOR: + mStringType = SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR; + break; + case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR: + mStringType = SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR; + break; + case SENSOR_TYPE_GRAVITY: + mStringType = SENSOR_STRING_TYPE_GRAVITY; + break; + case SENSOR_TYPE_GYROSCOPE: + mStringType = SENSOR_STRING_TYPE_GYROSCOPE; + break; + case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED: + mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED; + break; + case SENSOR_TYPE_HEART_RATE: + mStringType = SENSOR_STRING_TYPE_HEART_RATE; + mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS; + break; + case SENSOR_TYPE_LIGHT: + mStringType = SENSOR_STRING_TYPE_LIGHT; + break; + case SENSOR_TYPE_LINEAR_ACCELERATION: + mStringType = SENSOR_STRING_TYPE_LINEAR_ACCELERATION; + break; + case SENSOR_TYPE_MAGNETIC_FIELD: + mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD; + break; + case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED: + mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED; + break; + case SENSOR_TYPE_ORIENTATION: + mStringType = SENSOR_STRING_TYPE_ORIENTATION; + break; + case SENSOR_TYPE_PRESSURE: + mStringType = SENSOR_STRING_TYPE_PRESSURE; + break; + case SENSOR_TYPE_PROXIMITY: + mStringType = SENSOR_STRING_TYPE_PROXIMITY; + break; + case SENSOR_TYPE_RELATIVE_HUMIDITY: + mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY; + break; + case SENSOR_TYPE_ROTATION_VECTOR: + mStringType = SENSOR_STRING_TYPE_ROTATION_VECTOR; + break; + case SENSOR_TYPE_SIGNIFICANT_MOTION: + mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION; + break; + case SENSOR_TYPE_STEP_COUNTER: + mStringType = SENSOR_STRING_TYPE_STEP_COUNTER; + break; + case SENSOR_TYPE_STEP_DETECTOR: + mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR; + break; + case SENSOR_TYPE_TEMPERATURE: + mStringType = SENSOR_STRING_TYPE_TEMPERATURE; + break; + default: + // Only pipe the stringType and requiredPermission for custom sensors. + if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->stringType) { + mStringType = hwSensor->stringType; + } + if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->requiredPermission) { + mRequiredPermission = hwSensor->requiredPermission; + } + break; } } @@ -115,6 +191,14 @@ int32_t Sensor::getFifoMaxEventCount() const { return mFifoMaxEventCount; } +const String8& Sensor::getStringType() const { + return mStringType; +} + +const String8& Sensor::getRequiredPermission() const { + return mRequiredPermission; +} + size_t Sensor::getFlattenedSize() const { size_t fixedSize = @@ -123,8 +207,10 @@ size_t Sensor::getFlattenedSize() const sizeof(int32_t) * 3; size_t variableSize = - sizeof(int32_t) + FlattenableUtils::align<4>(mName.length()) + - sizeof(int32_t) + FlattenableUtils::align<4>(mVendor.length()); + sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) + + sizeof(uint32_t) + FlattenableUtils::align<4>(mVendor.length()) + + sizeof(uint32_t) + FlattenableUtils::align<4>(mStringType.length()) + + sizeof(uint32_t) + FlattenableUtils::align<4>(mRequiredPermission.length()); return fixedSize + variableSize; } @@ -134,14 +220,8 @@ status_t Sensor::flatten(void* buffer, size_t size) const { return NO_MEMORY; } - FlattenableUtils::write(buffer, size, mName.length()); - memcpy(static_cast(buffer), mName.string(), mName.length()); - FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mName.length())); - - FlattenableUtils::write(buffer, size, mVendor.length()); - memcpy(static_cast(buffer), mVendor.string(), mVendor.length()); - FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(mVendor.length())); - + flattenString8(buffer, size, mName); + flattenString8(buffer, size, mVendor); FlattenableUtils::write(buffer, size, mVersion); FlattenableUtils::write(buffer, size, mHandle); FlattenableUtils::write(buffer, size, mType); @@ -152,38 +232,23 @@ status_t Sensor::flatten(void* buffer, size_t size) const { FlattenableUtils::write(buffer, size, mMinDelay); FlattenableUtils::write(buffer, size, mFifoReservedEventCount); FlattenableUtils::write(buffer, size, mFifoMaxEventCount); + flattenString8(buffer, size, mStringType); + flattenString8(buffer, size, mRequiredPermission); return NO_ERROR; } status_t Sensor::unflatten(void const* buffer, size_t size) { - size_t len; - - if (size < sizeof(size_t)) { + if (!unflattenString8(buffer, size, mName)) { return NO_MEMORY; } - FlattenableUtils::read(buffer, size, len); - if (size < len) { + if (!unflattenString8(buffer, size, mVendor)) { return NO_MEMORY; } - mName.setTo(static_cast(buffer), len); - FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); - - - if (size < sizeof(size_t)) { - return NO_MEMORY; - } - FlattenableUtils::read(buffer, size, len); - if (size < len) { - return NO_MEMORY; - } - mVendor.setTo(static_cast(buffer), len); - FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); size_t fixedSize = sizeof(int32_t) * 3 + sizeof(float) * 4 + sizeof(int32_t) * 3; - if (size < fixedSize) { return NO_MEMORY; } @@ -198,8 +263,37 @@ status_t Sensor::unflatten(void const* buffer, size_t size) { FlattenableUtils::read(buffer, size, mMinDelay); FlattenableUtils::read(buffer, size, mFifoReservedEventCount); FlattenableUtils::read(buffer, size, mFifoMaxEventCount); + + if (!unflattenString8(buffer, size, mStringType)) { + return NO_MEMORY; + } + if (!unflattenString8(buffer, size, mRequiredPermission)) { + return NO_MEMORY; + } return NO_ERROR; } +void Sensor::flattenString8(void*& buffer, size_t& size, + const String8& string8) { + uint32_t len = string8.length(); + FlattenableUtils::write(buffer, size, len); + memcpy(static_cast(buffer), string8.string(), len); + FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); +} + +bool Sensor::unflattenString8(void const*& buffer, size_t& size, String8& outputString8) { + uint32_t len; + if (size < sizeof(len)) { + return false; + } + FlattenableUtils::read(buffer, size, len); + if (size < len) { + return false; + } + outputString8.setTo(static_cast(buffer), len); + FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len)); + return true; +} + // ---------------------------------------------------------------------------- }; // namespace android diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index f6705f6be..ca2fdf66d 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -205,7 +205,7 @@ status_t SensorService::dump(int fd, const Vector& args) String8 result; if (!PermissionCache::checkCallingPermission(sDump)) { result.appendFormat("Permission Denial: " - "can't dump SurfaceFlinger from pid=%d, uid=%d\n", + "can't dump SensorService from pid=%d, uid=%d\n", IPCThreadState::self()->getCallingPid(), IPCThreadState::self()->getCallingUid()); } else { @@ -215,21 +215,24 @@ status_t SensorService::dump(int fd, const Vector& args) const Sensor& s(mSensorList[i]); const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle())); result.appendFormat( - "%-48s| %-32s | 0x%08x | ", + "%-48s| %-32s| %-48s| 0x%08x | \"%s\"\n\t", s.getName().string(), s.getVendor().string(), - s.getHandle()); + s.getStringType().string(), + s.getHandle(), + s.getRequiredPermission().string()); if (s.getMinDelay() > 0) { result.appendFormat( - "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay()); + "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay()); } else { result.append(s.getMinDelay() == 0 ? "on-demand | " : "one-shot | "); } if (s.getFifoMaxEventCount() > 0) { - result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount()); + result.appendFormat("FifoMax=%d events | ", + s.getFifoMaxEventCount()); } else { result.append("no batching support | "); } @@ -490,10 +493,23 @@ Vector SensorService::getSensorList() { char value[PROPERTY_VALUE_MAX]; property_get("debug.sensors", value, "0"); - if (atoi(value)) { - return mUserSensorListDebug; + const Vector& initialSensorList = (atoi(value)) ? + mUserSensorListDebug : mUserSensorList; + Vector accessibleSensorList; + for (size_t i = 0; i < initialSensorList.size(); i++) { + Sensor sensor = initialSensorList[i]; + if (canAccessSensor(sensor)) { + accessibleSensorList.add(sensor); + } else { + String8 infoMessage; + infoMessage.appendFormat( + "Skipped sensor %s because it requires permission %s", + sensor.getName().string(), + sensor.getRequiredPermission().string()); + ALOGI(infoMessage.string()); + } } - return mUserSensorList; + return accessibleSensorList; } sp SensorService::createSensorEventConnection() @@ -539,6 +555,10 @@ void SensorService::cleanupConnection(SensorEventConnection* c) BatteryService::cleanup(c->getUid()); } +Sensor SensorService::getSensorFromHandle(int handle) const { + return mSensorMap.valueFor(handle)->getSensor(); +} + status_t SensorService::enable(const sp& connection, int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags) { @@ -549,6 +569,11 @@ status_t SensorService::enable(const sp& connection, if (sensor == NULL) { return BAD_VALUE; } + + if (!verifyCanAccessSensor(sensor->getSensor(), "Tried enabling")) { + return BAD_VALUE; + } + Mutex::Autolock _l(mLock); SensorRecord* rec = mActiveSensors.valueFor(handle); if (rec == 0) { @@ -670,6 +695,10 @@ status_t SensorService::setEventRate(const sp& connection if (!sensor) return BAD_VALUE; + if (!verifyCanAccessSensor(sensor->getSensor(), "Tried configuring")) { + return BAD_VALUE; + } + if (ns < 0) return BAD_VALUE; @@ -683,17 +712,44 @@ status_t SensorService::setEventRate(const sp& connection status_t SensorService::flushSensor(const sp& connection, int handle) { - if (mInitCheck != NO_ERROR) return mInitCheck; - SensorInterface* sensor = mSensorMap.valueFor(handle); - if (sensor == NULL) { - return BAD_VALUE; - } - if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) { - ALOGE("flush called on Significant Motion sensor"); - return INVALID_OPERATION; - } - return sensor->flush(connection.get(), handle); + if (mInitCheck != NO_ERROR) return mInitCheck; + SensorInterface* sensor = mSensorMap.valueFor(handle); + if (sensor == NULL) { + return BAD_VALUE; + } + + if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) { + return BAD_VALUE; + } + + if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) { + ALOGE("flush called on Significant Motion sensor"); + return INVALID_OPERATION; + } + return sensor->flush(connection.get(), handle); } + + +bool SensorService::canAccessSensor(const Sensor& sensor) { + String16 permissionString(sensor.getRequiredPermission()); + return permissionString.size() == 0 || + PermissionCache::checkCallingPermission(permissionString); +} + +bool SensorService::verifyCanAccessSensor(const Sensor& sensor, const char* operation) { + if (canAccessSensor(sensor)) { + return true; + } else { + String8 errorMessage; + errorMessage.appendFormat( + "%s a sensor (%s) without holding its required permission: %s", + operation, + sensor.getName().string(), + sensor.getRequiredPermission().string()); + return false; + } +} + // --------------------------------------------------------------------------- SensorService::SensorRecord::SensorRecord( @@ -761,6 +817,9 @@ void SensorService::SensorEventConnection::dump(String8& result) { bool SensorService::SensorEventConnection::addSensor(int32_t handle) { Mutex::Autolock _l(mConnectionLock); + if (!verifyCanAccessSensor(mService->getSensorFromHandle(handle), "Tried adding")) { + return false; + } if (mSensorInfo.indexOfKey(handle) < 0) { mSensorInfo.add(handle, FlushInfo()); return true; diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 1dc2dd36a..e88ffc875 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -131,6 +131,7 @@ class SensorService : String8 getSensorName(int handle) const; bool isVirtualSensor(int handle) const; + Sensor getSensorFromHandle(int handle) const; void recordLastValue(const sensors_event_t* buffer, size_t count); static void sortEventBuffer(sensors_event_t* buffer, size_t count); Sensor registerSensor(SensorInterface* sensor); @@ -141,7 +142,8 @@ class SensorService : const sp& connection, int handle); void cleanupAutoDisabledSensor(const sp& connection, sensors_event_t const* buffer, const int count); - + static bool canAccessSensor(const Sensor& sensor); + static bool verifyCanAccessSensor(const Sensor& sensor, const char* operation); // constants Vector mSensorList; Vector mUserSensorListDebug;