Add camera app op - camera

Change-Id: I26570cc0a23fdea740b416a26838d40cac296c85
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 3a9fb4c..84e0d1c 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -71,14 +71,13 @@
     // deadlock if we call any method of ICamera here.
 }
 
-sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
-        int clientUid)
+sp<Camera> Camera::connect(int cameraId, const String16& opPackageName, int clientUid)
 {
-    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
+    return CameraBaseT::connect(cameraId, opPackageName, clientUid);
 }
 
 status_t Camera::connectLegacy(int cameraId, int halVersion,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int clientUid,
         sp<Camera>& camera)
 {
@@ -89,7 +88,7 @@
     const sp<ICameraService>& cs = CameraBaseT::getCameraService();
 
     if (cs != 0) {
-        status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName,
+        status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName,
                                         clientUid, /*out*/c->mCamera);
     }
     if (status == OK && c->mCamera != 0) {
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 5d50aa8..0dc0276 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -91,7 +91,7 @@
 
 template <typename TCam, typename TCamTraits>
 sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
-                                               const String16& clientPackageName,
+                                               const String16& opPackageName,
                                                int clientUid)
 {
     ALOGV("%s: connect", __FUNCTION__);
@@ -102,7 +102,7 @@
 
     if (cs != 0) {
         TCamConnectService fnConnectService = TCamTraits::fnConnectService;
-        status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
+        status = (cs.get()->*fnConnectService)(cl, cameraId, opPackageName, clientUid,
                                              /*out*/ c->mCamera);
     }
     if (status == OK && c->mCamera != 0) {
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index 51a775b..192e40d 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -164,7 +164,7 @@
 
     // connect to camera service (android.hardware.Camera)
     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
-                             const String16 &clientPackageName, int clientUid,
+                             const String16& opPackageName, int clientUid,
                              /*out*/
                              sp<ICamera>& device)
     {
@@ -172,7 +172,7 @@
         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
         data.writeStrongBinder(IInterface::asBinder(cameraClient));
         data.writeInt32(cameraId);
-        data.writeString16(clientPackageName);
+        data.writeString16(opPackageName);
         data.writeInt32(clientUid);
         remote()->transact(BnCameraService::CONNECT, data, &reply);
 
@@ -187,7 +187,7 @@
     // connect to camera service (android.hardware.Camera)
     virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
                              int halVersion,
-                             const String16 &clientPackageName, int clientUid,
+                             const String16& opPackageName, int clientUid,
                              /*out*/sp<ICamera>& device)
     {
         Parcel data, reply;
@@ -195,7 +195,7 @@
         data.writeStrongBinder(IInterface::asBinder(cameraClient));
         data.writeInt32(cameraId);
         data.writeInt32(halVersion);
-        data.writeString16(clientPackageName);
+        data.writeString16(opPackageName);
         data.writeInt32(clientUid);
         remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply);
 
@@ -225,7 +225,7 @@
     virtual status_t connectDevice(
             const sp<ICameraDeviceCallbacks>& cameraCb,
             int cameraId,
-            const String16& clientPackageName,
+            const String16& opPackageName,
             int clientUid,
             /*out*/
             sp<ICameraDeviceUser>& device)
@@ -234,7 +234,7 @@
         data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
         data.writeStrongBinder(IInterface::asBinder(cameraCb));
         data.writeInt32(cameraId);
-        data.writeString16(clientPackageName);
+        data.writeString16(opPackageName);
         data.writeInt32(clientUid);
         remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply);
 
@@ -374,11 +374,11 @@
             sp<ICameraClient> cameraClient =
                     interface_cast<ICameraClient>(data.readStrongBinder());
             int32_t cameraId = data.readInt32();
-            const String16 clientName = data.readString16();
+            const String16 opPackageName = data.readString16();
             int32_t clientUid = data.readInt32();
             sp<ICamera> camera;
             status_t status = connect(cameraClient, cameraId,
-                    clientName, clientUid, /*out*/camera);
+                    opPackageName, clientUid, /*out*/camera);
             reply->writeNoException();
             reply->writeInt32(status);
             if (camera != NULL) {
@@ -394,11 +394,11 @@
             sp<ICameraDeviceCallbacks> cameraClient =
                 interface_cast<ICameraDeviceCallbacks>(data.readStrongBinder());
             int32_t cameraId = data.readInt32();
-            const String16 clientName = data.readString16();
+            const String16 opPackageName = data.readString16();
             int32_t clientUid = data.readInt32();
             sp<ICameraDeviceUser> camera;
             status_t status = connectDevice(cameraClient, cameraId,
-                    clientName, clientUid, /*out*/camera);
+                    opPackageName, clientUid, /*out*/camera);
             reply->writeNoException();
             reply->writeInt32(status);
             if (camera != NULL) {
@@ -454,11 +454,11 @@
                     interface_cast<ICameraClient>(data.readStrongBinder());
             int32_t cameraId = data.readInt32();
             int32_t halVersion = data.readInt32();
-            const String16 clientName = data.readString16();
+            const String16 opPackageName = data.readString16();
             int32_t clientUid = data.readInt32();
             sp<ICamera> camera;
             status_t status = connectLegacy(cameraClient, cameraId, halVersion,
-                    clientName, clientUid, /*out*/camera);
+                    opPackageName, clientUid, /*out*/camera);
             reply->writeNoException();
             reply->writeInt32(status);
             if (camera != NULL) {
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 2b60842..25d75f7 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -71,11 +71,11 @@
             // construct a camera client from an existing remote
     static  sp<Camera>  create(const sp<ICamera>& camera);
     static  sp<Camera>  connect(int cameraId,
-                                const String16& clientPackageName,
+                                const String16& opPackageName,
                                 int clientUid);
 
     static  status_t  connectLegacy(int cameraId, int halVersion,
-                                     const String16& clientPackageName,
+                                     const String16& opPackageName,
                                      int clientUid, sp<Camera>& camera);
 
             virtual     ~Camera();
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index cad275e..38bff3e 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -109,7 +109,7 @@
      */
     virtual status_t connect(const sp<ICameraClient>& cameraClient,
             int cameraId,
-            const String16& clientPackageName,
+            const String16& opPackageName,
             int clientUid,
             /*out*/
             sp<ICamera>& device) = 0;
@@ -117,7 +117,7 @@
     virtual status_t connectDevice(
             const sp<ICameraDeviceCallbacks>& cameraCb,
             int cameraId,
-            const String16& clientPackageName,
+            const String16& opPackageName,
             int clientUid,
             /*out*/
             sp<ICameraDeviceUser>& device) = 0;
@@ -141,7 +141,7 @@
      */
     virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient,
             int cameraId, int halVersion,
-            const String16& clientPackageName,
+            const String16& opPackageName,
             int clientUid,
             /*out*/
             sp<ICamera>& device) = 0;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index e28464d..3f80faf 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1057,19 +1057,24 @@
 status_t CameraService::connect(
         const sp<ICameraClient>& cameraClient,
         int cameraId,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int clientUid,
         /*out*/
         sp<ICamera>& device) {
 
+    const status_t result = checkCameraAccess(opPackageName);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
     status_t ret = NO_ERROR;
     String8 id = String8::format("%d", cameraId);
     sp<Client> client = nullptr;
     ret = connectHelper<ICameraClient,Client>(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED,
-            clientPackageName, clientUid, API_1, false, false, /*out*/client);
+            opPackageName, clientUid, API_1, false, false, /*out*/client);
 
     if(ret != NO_ERROR) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, getCallingPid(), String8(opPackageName),
                 String8::format("%s (%d)", strerror(-ret), ret));
         return ret;
     }
@@ -1081,11 +1086,16 @@
 status_t CameraService::connectLegacy(
         const sp<ICameraClient>& cameraClient,
         int cameraId, int halVersion,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int clientUid,
         /*out*/
         sp<ICamera>& device) {
 
+    const status_t result = checkCameraAccess(opPackageName);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
     String8 id = String8::format("%d", cameraId);
     int apiVersion = mModule->getModuleApiVersion();
     if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED &&
@@ -1098,18 +1108,18 @@
          */
         ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!",
                 __FUNCTION__, apiVersion);
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, getCallingPid(), String8(opPackageName),
                 String8("HAL module version doesn't support legacy HAL connections"));
         return INVALID_OPERATION;
     }
 
     status_t ret = NO_ERROR;
     sp<Client> client = nullptr;
-    ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, clientPackageName,
+    ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion, opPackageName,
             clientUid, API_1, true, false, /*out*/client);
 
     if(ret != NO_ERROR) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, getCallingPid(), String8(opPackageName),
                 String8::format("%s (%d)", strerror(-ret), ret));
         return ret;
     }
@@ -1121,20 +1131,25 @@
 status_t CameraService::connectDevice(
         const sp<ICameraDeviceCallbacks>& cameraCb,
         int cameraId,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int clientUid,
         /*out*/
         sp<ICameraDeviceUser>& device) {
 
+    const status_t result = checkCameraAccess(opPackageName);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
     status_t ret = NO_ERROR;
     String8 id = String8::format("%d", cameraId);
     sp<CameraDeviceClient> client = nullptr;
     ret = connectHelper<ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
-            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false,
+            CAMERA_HAL_API_VERSION_UNSPECIFIED, opPackageName, clientUid, API_2, false, false,
             /*out*/client);
 
     if(ret != NO_ERROR) {
-        logRejected(id, getCallingPid(), String8(clientPackageName),
+        logRejected(id, getCallingPid(), String8(opPackageName),
                 String8::format("%s (%d)", strerror(-ret), ret));
         return ret;
     }
@@ -1529,24 +1544,24 @@
 }
 
 void CameraService::logDisconnected(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+        const char* opPackageName) {
     // Log the clients evicted
     logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId,
-            clientPackage, clientPid));
+            opPackageName, clientPid));
 }
 
 void CameraService::logConnected(const char* cameraId, int clientPid,
-        const char* clientPackage) {
+        const char* opPackageName) {
     // Log the clients evicted
     logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId,
-            clientPackage, clientPid));
+            opPackageName, clientPid));
 }
 
 void CameraService::logRejected(const char* cameraId, int clientPid,
-        const char* clientPackage, const char* reason) {
+        const char* opPackageName, const char* reason) {
     // Log the client rejected
     logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)",
-            cameraId, clientPackage, clientPid, reason));
+            cameraId, opPackageName, clientPid, reason));
 }
 
 void CameraService::logUserSwitch(int oldUserId, int newUserId) {
@@ -1583,21 +1598,6 @@
 
     // Permission checks
     switch (code) {
-        case BnCameraService::CONNECT:
-        case BnCameraService::CONNECT_DEVICE:
-        case BnCameraService::CONNECT_LEGACY: {
-            if (pid != selfPid) {
-                // we're called from a different process, do the real check
-                if (!checkCallingPermission(
-                        String16("android.permission.CAMERA"))) {
-                    const int uid = getCallingUid();
-                    ALOGE("Permission Denial: "
-                         "can't use the camera pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-            break;
-        }
         case BnCameraService::NOTIFY_SYSTEM_EVENT: {
             if (pid != selfPid) {
                 // Ensure we're being called by system_server, or similar process with
@@ -1617,6 +1617,38 @@
     return BnCameraService::onTransact(code, data, reply, flags);
 }
 
+status_t CameraService::checkCameraAccess(const String16& opPackageName) {
+    const int pid = getCallingPid();
+
+    if (pid == getpid()) {
+        return NO_ERROR;
+    }
+
+    const int uid = getCallingUid();
+
+    if (!checkCallingPermission(String16("android.permission.CAMERA"))) {
+        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", pid, uid);
+        return PERMISSION_DENIED;
+    }
+
+    AppOpsManager appOps;
+    const int32_t result = appOps.noteOp(AppOpsManager::OP_CAMERA, uid, opPackageName);
+
+    switch (result) {
+        case AppOpsManager::MODE_ERRORED: {
+            ALOGE("App op OP_CAMERA errored: can't use the camera pid=%d, uid=%d", pid, uid);
+            return PERMISSION_DENIED;
+        } break;
+
+        case AppOpsManager::MODE_IGNORED: {
+             ALOGE("App op OP_CAMERA ignored: can't use the camera pid=%d, uid=%d", pid, uid);
+             return INVALID_OPERATION;
+        } break;
+    }
+
+    return NO_ERROR;
+}
+
 // We share the media players for shutter and recording sound for all clients.
 // A reference count is kept to determine when we will actually release the
 // media players.
@@ -1669,13 +1701,13 @@
 
 CameraService::Client::Client(const sp<CameraService>& cameraService,
         const sp<ICameraClient>& cameraClient,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int cameraId, int cameraFacing,
         int clientPid, uid_t clientUid,
         int servicePid) :
         CameraService::BasicClient(cameraService,
                 IInterface::asBinder(cameraClient),
-                clientPackageName,
+                opPackageName,
                 cameraId, cameraFacing,
                 clientPid, clientUid,
                 servicePid)
@@ -1702,11 +1734,11 @@
 
 CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
         const sp<IBinder>& remoteCallback,
-        const String16& clientPackageName,
+        const String16& opPackageName,
         int cameraId, int cameraFacing,
         int clientPid, uid_t clientUid,
         int servicePid):
-        mClientPackageName(clientPackageName), mDisconnected(false)
+        mOpPackageName(opPackageName), mDisconnected(false)
 {
     mCameraService = cameraService;
     mRemoteBinder = remoteCallback;
@@ -1734,7 +1766,7 @@
 
     mCameraService->removeByClient(this);
     mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid,
-            String8(mClientPackageName));
+            String8(mOpPackageName));
 
     sp<IBinder> remote = getRemote();
     if (remote != nullptr) {
@@ -1749,7 +1781,7 @@
 }
 
 String16 CameraService::BasicClient::getPackageName() const {
-    return mClientPackageName;
+    return mOpPackageName;
 }
 
 
@@ -1769,17 +1801,17 @@
 
     {
         ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
-              __FUNCTION__, String8(mClientPackageName).string(), mClientUid);
+              __FUNCTION__, String8(mOpPackageName).string(), mClientUid);
     }
 
     mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
-            mClientPackageName, mOpsCallback);
+            mOpPackageName, mOpsCallback);
     res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
-            mClientUid, mClientPackageName);
+            mClientUid, mOpPackageName);
 
     if (res != AppOpsManager::MODE_ALLOWED) {
         ALOGI("Camera %d: Access for \"%s\" has been revoked",
-                mCameraId, String8(mClientPackageName).string());
+                mCameraId, String8(mOpPackageName).string());
         return PERMISSION_DENIED;
     }
 
@@ -1797,7 +1829,7 @@
     if (mOpsActive) {
         // Notify app ops that the camera is available again
         mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
-                mClientPackageName);
+                mOpPackageName);
         mOpsActive = false;
 
         auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT,
@@ -1822,7 +1854,7 @@
 
 void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
     String8 name(packageName);
-    String8 myName(mClientPackageName);
+    String8 myName(mOpPackageName);
 
     if (op != AppOpsManager::OP_CAMERA) {
         ALOGW("Unexpected app ops notification received: %d", op);
@@ -1831,7 +1863,7 @@
 
     int32_t res;
     res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
-            mClientUid, mClientPackageName);
+            mClientUid, mOpPackageName);
     ALOGV("checkOp returns: %d, %s ", res,
             res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
             res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a8b4c4a..502fcfa 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -126,19 +126,19 @@
     virtual status_t    getCameraVendorTagDescriptor(/*out*/ sp<VendorTagDescriptor>& desc);
 
     virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId,
-            const String16& clientPackageName, int clientUid,
+            const String16& opPackageName, int clientUid,
             /*out*/
             sp<ICamera>& device);
 
     virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId,
-            int halVersion, const String16& clientPackageName, int clientUid,
+            int halVersion, const String16& opPackageName, int clientUid,
             /*out*/
             sp<ICamera>& device);
 
     virtual status_t connectDevice(
             const sp<ICameraDeviceCallbacks>& cameraCb,
             int cameraId,
-            const String16& clientPackageName,
+            const String16& opPackageName,
             int clientUid,
             /*out*/
             sp<ICameraDeviceUser>& device);
@@ -223,7 +223,7 @@
     protected:
         BasicClient(const sp<CameraService>& cameraService,
                 const sp<IBinder>& remoteCallback,
-                const String16& clientPackageName,
+                const String16& opPackageName,
                 int cameraId,
                 int cameraFacing,
                 int clientPid,
@@ -242,7 +242,7 @@
         sp<CameraService>               mCameraService;  // immutable after constructor
         int                             mCameraId;       // immutable after constructor
         int                             mCameraFacing;   // immutable after constructor
-        const String16                  mClientPackageName;
+        const String16                  mOpPackageName;
         pid_t                           mClientPid;
         uid_t                           mClientUid;      // immutable after constructor
         pid_t                           mServicePid;     // immutable after constructor
@@ -309,7 +309,7 @@
         // Interface used by CameraService
         Client(const sp<CameraService>& cameraService,
                 const sp<ICameraClient>& cameraClient,
-                const String16& clientPackageName,
+                const String16& opPackageName,
                 int cameraId,
                 int cameraFacing,
                 int clientPid,
@@ -480,7 +480,7 @@
     // Single implementation shared between the various connect calls
     template<class CALLBACK, class CLIENT>
     status_t connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion,
-            const String16& clientPackageName, int clientUid, apiLevel effectiveApiLevel,
+            const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel,
             bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
 
 
@@ -713,6 +713,8 @@
             int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
             int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
             /*out*/sp<BasicClient>* client);
+
+    status_t checkCameraAccess(const String16& opPackageName);
 };
 
 template<class Func>
@@ -761,11 +763,11 @@
 
 template<class CALLBACK, class CLIENT>
 status_t CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
-        int halVersion, const String16& clientPackageName, int clientUid,
+        int halVersion, const String16& opPackageName, int clientUid,
         apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
         /*out*/sp<CLIENT>& device) {
     status_t ret = NO_ERROR;
-    String8 clientName8(clientPackageName);
+    String8 clientName8(opPackageName);
     int clientPid = getCallingPid();
 
     ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
@@ -836,7 +838,7 @@
         int facing = -1;
         int deviceVersion = getDeviceVersion(id, /*out*/&facing);
         sp<BasicClient> tmp = nullptr;
-        if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
+        if((ret = makeClient(this, cameraCb, opPackageName, cameraId, facing, clientPid,
                 clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                 /*out*/&tmp)) != NO_ERROR) {
             return ret;
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index ba0b264..9b2e143 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -118,7 +118,7 @@
 
     ALOGI("Closed Camera %d. Client was: %s (PID %d, UID %u)",
             TClientBase::mCameraId,
-            String8(TClientBase::mClientPackageName).string(),
+            String8(TClientBase::mOpPackageName).string(),
             mInitialClientPid, TClientBase::mClientUid);
 }