Add body sensors app op - framework native

Change-Id: I727a2bb1e28ae9158f2df9c74dd0aee977dfd47f
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index c562c30..e4d8201 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -104,4 +104,13 @@
     }
 }
 
+int32_t AppOpsManager::permissionToOpCode(const String16& permission) {
+    sp<IAppOpsService> service = getService();
+    if (service != NULL) {
+        return service->permissionToOpCode(permission);
+    }
+    return -1;
+}
+
+
 }; // namespace android
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index 86abdc0..9558376 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -111,6 +111,17 @@
         if (reply.readExceptionCode() != 0) return NULL;
         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");
@@ -187,6 +198,14 @@
             reply->writeStrongBinder(token);
             return NO_ERROR;
         } 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:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index 67dac27..6bba996 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -67,6 +67,17 @@
             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");
@@ -102,6 +113,15 @@
             return NO_ERROR;
         } 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:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 140712e..5dde9f9 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -48,10 +48,11 @@
 
     virtual ~BpSensorServer();
 
-    virtual Vector<Sensor> getSensorList()
+    virtual Vector<Sensor> getSensorList(const String16& opPackageName)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
         remote()->transact(GET_SENSOR_LIST, data, &reply);
         Sensor s;
         Vector<Sensor> v;
@@ -65,12 +66,13 @@
     }
 
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
-             int mode)
+             int mode, const String16& opPackageName)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
         data.writeString8(packageName);
         data.writeInt32(mode);
+        data.writeString16(opPackageName);
         remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
         return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
     }
@@ -98,7 +100,8 @@
     switch(code) {
         case GET_SENSOR_LIST: {
             CHECK_INTERFACE(ISensorServer, data, reply);
-            Vector<Sensor> v(getSensorList());
+            const String16& opPackageName = data.readString16();
+            Vector<Sensor> v(getSensorList(opPackageName));
             size_t n = v.size();
             reply->writeUint32(static_cast<uint32_t>(n));
             for (size_t i = 0; i < n; i++) {
@@ -110,7 +113,9 @@
             CHECK_INTERFACE(ISensorServer, data, reply);
             String8 packageName = data.readString8();
             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));
             return NO_ERROR;
         }
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 35661f2..2545eec 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -25,6 +25,9 @@
 
 #include <hardware/sensors.h>
 
+#include <binder/AppOpsManager.h>
+#include <binder/IServiceManager.h>
+
 #include <gui/Sensor.h>
 #include <log/log.h>
 
@@ -113,11 +116,13 @@
         mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
         mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
         break;
-    case SENSOR_TYPE_HEART_RATE:
+    case SENSOR_TYPE_HEART_RATE: {
         mStringType = SENSOR_STRING_TYPE_HEART_RATE;
         mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
+        AppOpsManager appOps;
+        mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS));
         mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
-        break;
+        } break;
     case SENSOR_TYPE_LIGHT:
         mStringType = SENSOR_STRING_TYPE_LIGHT;
         mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
@@ -252,6 +257,17 @@
 
         }
     }
+
+    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()
@@ -318,6 +334,14 @@
     return mRequiredPermission;
 }
 
+bool Sensor::isRequiredPermissionRuntime() const {
+    return mRequiredPermissionRuntime;
+}
+
+int32_t Sensor::getRequiredAppOp() const {
+    return mRequiredAppOp;
+}
+
 int32_t Sensor::getMaxDelay() const {
     return mMaxDelay;
 }
@@ -339,7 +363,8 @@
     size_t fixedSize =
             sizeof(int32_t) * 3 +
             sizeof(float) * 4 +
-            sizeof(int32_t) * 5;
+            sizeof(int32_t) * 6 +
+            sizeof(bool);
 
     size_t variableSize =
             sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
@@ -369,6 +394,8 @@
     FlattenableUtils::write(buffer, size, mFifoMaxEventCount);
     flattenString8(buffer, size, mStringType);
     flattenString8(buffer, size, mRequiredPermission);
+    FlattenableUtils::write(buffer, size, mRequiredPermissionRuntime);
+    FlattenableUtils::write(buffer, size, mRequiredAppOp);
     FlattenableUtils::write(buffer, size, mMaxDelay);
     FlattenableUtils::write(buffer, size, mFlags);
     return NO_ERROR;
@@ -407,6 +434,8 @@
     if (!unflattenString8(buffer, size, mRequiredPermission)) {
         return NO_MEMORY;
     }
+    FlattenableUtils::read(buffer, size, mRequiredPermissionRuntime);
+    FlattenableUtils::read(buffer, size, mRequiredAppOp);
     FlattenableUtils::read(buffer, size, mMaxDelay);
     FlattenableUtils::read(buffer, size, mFlags);
     return NO_ERROR;
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index cedcf56..8c9f95b 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -36,10 +36,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
-
-SensorManager::SensorManager()
-    : mSensorList(0)
+SensorManager::SensorManager(const String16& opPackageName)
+    : mSensorList(0), mOpPackageName(opPackageName)
 {
     // okay we're not locked here, but it's not needed during construction
     assertStateLocked();
@@ -88,7 +86,7 @@
         mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
         IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
 
-        mSensors = mSensorServer->getSensorList();
+        mSensors = mSensorServer->getSensorList(mOpPackageName);
         size_t count = mSensors.size();
         mSensorList =
                 static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
@@ -143,7 +141,7 @@
     Mutex::Autolock _l(mLock);
     while (assertStateLocked() == NO_ERROR) {
         sp<ISensorEventConnection> connection =
-                mSensorServer->createSensorEventConnection(packageName, mode);
+                mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName);
         if (connection == NULL) {
             // SensorService just died or the app doesn't have required permissions.
             ALOGE("createEventQueue: connection is NULL.");