Camera and MediaRecorder: Support AppOps

- Allow media processes to update AppOps state
- Pass package name to media services

Bug: 8181262
Change-Id: I115d39f0b306cb9eb7cd3d3e663c680b7322fd3f
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 483e9de..4e51080 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -16,6 +16,7 @@
 
 package android.hardware;
 
+import android.app.ActivityThread;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
@@ -337,7 +338,9 @@
             mEventHandler = null;
         }
 
-        native_setup(new WeakReference<Camera>(this), cameraId);
+        String packageName = ActivityThread.currentPackageName();
+
+        native_setup(new WeakReference<Camera>(this), cameraId, packageName);
     }
 
     /**
@@ -350,7 +353,9 @@
         release();
     }
 
-    private native final void native_setup(Object camera_this, int cameraId);
+    private native final void native_setup(Object camera_this, int cameraId,
+                                           String packageName);
+
     private native final void native_release();
 
 
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index c0e12da..362d9a4 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -465,9 +465,16 @@
 
 // connect to camera service
 static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
-    jobject weak_this, jint cameraId)
+    jobject weak_this, jint cameraId, jstring clientPackageName)
 {
-    sp<Camera> camera = Camera::connect(cameraId);
+    // Convert jstring to String16
+    const char16_t *rawClientName = env->GetStringChars(clientPackageName, NULL);
+    jsize rawClientNameLen = env->GetStringLength(clientPackageName);
+    String16 clientName(rawClientName, rawClientNameLen);
+    env->ReleaseStringChars(clientPackageName, rawClientName);
+
+    sp<Camera> camera = Camera::connect(cameraId, clientName,
+            Camera::USE_CALLING_UID);
 
     if (camera == NULL) {
         jniThrowRuntimeException(env, "Fail to connect to camera service");
@@ -859,7 +866,7 @@
     "(ILandroid/hardware/Camera$CameraInfo;)V",
     (void*)android_hardware_Camera_getCameraInfo },
   { "native_setup",
-    "(Ljava/lang/Object;I)V",
+    "(Ljava/lang/Object;ILjava/lang/String;)V",
     (void*)android_hardware_Camera_native_setup },
   { "native_release",
     "()V",
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index d986c1e..1289971 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -126,6 +126,7 @@
     <assign-permission name="android.permission.ACCESS_DRM" uid="media" />
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
     <assign-permission name="android.permission.WAKE_LOCK" uid="media" />
+    <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" />
 
     <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index e0430b4..3e688db 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,6 +16,7 @@
 
 package android.media;
 
+import android.app.ActivityThread;
 import android.hardware.Camera;
 import android.os.Handler;
 import android.os.Looper;
@@ -105,10 +106,11 @@
             mEventHandler = null;
         }
 
+        String packageName = ActivityThread.currentPackageName();
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
          */
-        native_setup(new WeakReference<MediaRecorder>(this));
+        native_setup(new WeakReference<MediaRecorder>(this), packageName);
     }
 
     /**
@@ -977,7 +979,8 @@
 
     private static native final void native_init();
 
-    private native final void native_setup(Object mediarecorder_this) throws IllegalStateException;
+    private native final void native_setup(Object mediarecorder_this,
+            String clientName) throws IllegalStateException;
 
     private native final void native_finalize();
 
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 5bf16cc..4ebbbde 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -416,9 +416,11 @@
 
 
 static void
-android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
+android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+                                         jstring packageName)
 {
     ALOGV("setup");
+
     sp<MediaRecorder> mr = new MediaRecorder();
     if (mr == NULL) {
         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
@@ -433,6 +435,15 @@
     sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this);
     mr->setListener(listener);
 
+   // Convert client name jstring to String16
+    const char16_t *rawClientName = env->GetStringChars(packageName, NULL);
+    jsize rawClientNameLen = env->GetStringLength(packageName);
+    String16 clientName(rawClientName, rawClientNameLen);
+    env->ReleaseStringChars(packageName, rawClientName);
+
+    // pass client package name for permissions tracking
+    mr->setClientName(clientName);
+
     setMediaRecorder(env, thiz, mr);
 }
 
@@ -465,7 +476,7 @@
     {"native_reset",         "()V",                             (void *)android_media_MediaRecorder_native_reset},
     {"release",              "()V",                             (void *)android_media_MediaRecorder_release},
     {"native_init",          "()V",                             (void *)android_media_MediaRecorder_native_init},
-    {"native_setup",         "(Ljava/lang/Object;)V",           (void *)android_media_MediaRecorder_native_setup},
+    {"native_setup",         "(Ljava/lang/Object;Ljava/lang/String;)V", (void *)android_media_MediaRecorder_native_setup},
     {"native_finalize",      "()V",                             (void *)android_media_MediaRecorder_native_finalize},
 };