[DO NOT MERGE ANYWHERE] Fix bodysensor permission
Bug: 26481493
Bug: 26447970
Change-Id: Iaadf64814c03ae8098c8553ac98d19b77c1eabcd
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index 0cff46c..f039caf 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -22,9 +22,11 @@
#include <stdint.h>
#include <sys/types.h>
+#include <binder/BinderService.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <binder/PermissionCache.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
@@ -54,7 +56,8 @@
static SensorManager& getInstanceForPackage(const String16& packageName);
~SensorManager();
- ssize_t getSensorList(Sensor const* const** list) const;
+ ssize_t getSensorList(Sensor const* const** list);
+ ssize_t getAvailableSensorList(Sensor const* const** list);
Sensor const* getDefaultSensor(int type);
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
bool isDataInjectionEnabled();
@@ -64,18 +67,27 @@
void sensorManagerDied();
SensorManager(const String16& opPackageName);
- status_t assertStateLocked() const;
+ status_t assertStateLocked();
+ void updateAvailableSensorList();
private:
static Mutex sLock;
static std::map<String16, SensorManager*> sPackageInstances;
- mutable Mutex mLock;
- mutable sp<ISensorServer> mSensorServer;
- mutable Sensor const** mSensorList;
- mutable Vector<Sensor> mSensors;
- mutable sp<IBinder::DeathRecipient> mDeathObserver;
+ Mutex mLock;
+ sp<ISensorServer> mSensorServer;
+
+ // for Java API
+ Sensor const** mSensorList;
+
+ // for NDK API
+ Sensor const** mAvailableSensorList;
+ ssize_t mNumAvailableSensor;
+
+ Vector<Sensor> mSensors;
+ sp<IBinder::DeathRecipient> mDeathObserver;
const String16 mOpPackageName;
+ bool mBodyPermission;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 33608b5..4277032 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -89,7 +89,8 @@
}
SensorManager::SensorManager(const String16& opPackageName)
- : mSensorList(0), mOpPackageName(opPackageName)
+ : mSensorList(NULL), mAvailableSensorList(NULL), mNumAvailableSensor(0),
+ mOpPackageName(opPackageName), mBodyPermission(false)
{
// okay we're not locked here, but it's not needed during construction
assertStateLocked();
@@ -98,6 +99,9 @@
SensorManager::~SensorManager()
{
free(mSensorList);
+ if (mAvailableSensorList) {
+ free(mAvailableSensorList);
+ }
}
void SensorManager::sensorManagerDied()
@@ -106,10 +110,14 @@
mSensorServer.clear();
free(mSensorList);
mSensorList = NULL;
+ if (mAvailableSensorList) {
+ free(mAvailableSensorList);
+ mAvailableSensorList = NULL;
+ }
mSensors.clear();
}
-status_t SensorManager::assertStateLocked() const {
+status_t SensorManager::assertStateLocked() {
bool initSensorManager = false;
if (mSensorServer == NULL) {
initSensorManager = true;
@@ -159,13 +167,14 @@
for (size_t i=0 ; i<count ; i++) {
mSensorList[i] = mSensors.array() + i;
}
+
+ updateAvailableSensorList();
}
return NO_ERROR;
}
-ssize_t SensorManager::getSensorList(Sensor const* const** list) const
-{
+ssize_t SensorManager::getSensorList(Sensor const* const** list) {
Mutex::Autolock _l(mLock);
status_t err = assertStateLocked();
if (err < 0) {
@@ -175,10 +184,76 @@
return static_cast<ssize_t>(mSensors.size());
}
-Sensor const* SensorManager::getDefaultSensor(int type)
-{
+void SensorManager::updateAvailableSensorList() {
+ const int uid = static_cast<int>(IPCThreadState::self()->getCallingUid());
+ const int pid = static_cast<int>(IPCThreadState::self()->getCallingPid());
+ const String16 BODY_SENSOR_PERMISSION("android.permission.BODY_SENSORS");
+ const String8 BODY_SENSOR_PERMISSION8("android.permission.BODY_SENSORS");
+
+ bool bodySensorPermission = false;
+
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+ if (binder != NULL) {
+ bodySensorPermission = interface_cast<IPermissionController>(binder)->
+ checkPermission(BODY_SENSOR_PERMISSION, pid, uid);
+ }
+
+ // only update if app got BODY_SENSORS permission after last call or the sensor list has not
+ // been populated.
+ //
+ // it is not possible for the reverse transition, as the app will be killed when permission is
+ // revoked.
+ if ( (bodySensorPermission && !mBodyPermission) || mAvailableSensorList == NULL) {
+
+ // allocate only when necessary
+ if (mAvailableSensorList == NULL) {
+ // allocate a list big enough to fit all sensors (including those requires permission
+ // that the app do not have;
+ mAvailableSensorList =
+ static_cast<Sensor const**>(malloc(mSensors.size() * sizeof(Sensor*)));
+
+ // first populate all sensors that do not need body sensor permission
+ ssize_t& n = mNumAvailableSensor;
+ for (size_t i = 0; i < mSensors.size() ; i++) {
+ if (mSensors[i].getRequiredPermission() != BODY_SENSOR_PERMISSION8) {
+ mAvailableSensorList[n++] = mSensors.array() + i;
+ }
+ }
+ }
+
+ if (bodySensorPermission) {
+ // if the app just got the sensor permission back, fill the sensor at the end of list
+ ssize_t& n = mNumAvailableSensor;
+ for (size_t i = 0; i < mSensors.size() ; i++) {
+ if (mSensors[i].getRequiredPermission() == BODY_SENSOR_PERMISSION8) {
+ mAvailableSensorList[n++] = mSensors.array() + i;
+ }
+ }
+ }
+
+ mBodyPermission = bodySensorPermission;
+ }
+}
+
+ssize_t SensorManager::getAvailableSensorList(Sensor const* const** list) {
+ Mutex::Autolock _l(mLock);
+ status_t err = assertStateLocked();
+ if (err < 0) {
+ return static_cast<ssize_t>(err);
+ }
+
+ updateAvailableSensorList();
+
+ *list = mAvailableSensorList;
+ return mNumAvailableSensor;
+}
+
+Sensor const* SensorManager::getDefaultSensor(int type) {
Mutex::Autolock _l(mLock);
if (assertStateLocked() == NO_ERROR) {
+
+ updateAvailableSensorList();
+
bool wakeUpSensor = false;
// For the following sensor types, return a wake-up sensor. These types are by default
// defined as wake-up sensors. For the rest of the sensor types defined in sensors.h return
@@ -192,9 +267,9 @@
// in the future it will make sense to let the SensorService make
// that decision.
for (size_t i=0 ; i<mSensors.size() ; i++) {
- if (mSensorList[i]->getType() == type &&
- mSensorList[i]->isWakeUpSensor() == wakeUpSensor) {
- return mSensorList[i];
+ if (mAvailableSensorList[i]->getType() == type &&
+ mAvailableSensorList[i]->isWakeUpSensor() == wakeUpSensor) {
+ return mAvailableSensorList[i];
}
}
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index fd72b23..956d8e8 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -723,14 +723,7 @@
Vector<Sensor> accessibleSensorList;
for (size_t i = 0; i < initialSensorList.size(); i++) {
Sensor sensor = initialSensorList[i];
- if (canAccessSensor(sensor, "getSensorList", opPackageName)) {
- accessibleSensorList.add(sensor);
- } else {
- ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
- sensor.getName().string(),
- sensor.getRequiredPermission().string(),
- sensor.getRequiredAppOp());
- }
+ accessibleSensorList.add(sensor);
}
return accessibleSensorList;
}