Switch media fw permissions checks to AttributionSource (voip)

Attribution source is the abstraction to capture the data
flows for private data across apps. Checking permissions
for an attribution source does this for all apps in the
chain that would receive the data as well as the relevant
app ops are checked/noted/started as needed.

bug: 158792096

Test: atest CtsMediaTestCases
      atest CtsPermissionTestCases
      atest CtsPermission2TestCases
      atest CtsPermission3TestCases
      atest CtsPermission4

Merged-In: Iec62f7afa8ca128886a85f425f7a92122ed2155c

Change-Id: Iec62f7afa8ca128886a85f425f7a92122ed2155c
diff --git a/src/java/android/net/rtp/AudioGroup.java b/src/java/android/net/rtp/AudioGroup.java
index c186125..3a85bbc 100644
--- a/src/java/android/net/rtp/AudioGroup.java
+++ b/src/java/android/net/rtp/AudioGroup.java
@@ -16,12 +16,11 @@
 
 package android.net.rtp;
 
-import static android.media.permission.PermissionUtil.myIdentity;
-
 import android.annotation.NonNull;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.media.AudioManager;
-import android.media.permission.Identity;
+import android.os.Parcel;
 
 import java.util.HashMap;
 import java.util.Locale;
@@ -170,10 +169,14 @@
                 String codecSpec = String.format(Locale.US, "%d %s %s", codec.type,
                         codec.rtpmap, codec.fmtp);
 
-                long id = nativeAdd(stream.getMode(), stream.getSocket(),
-                        stream.getRemoteAddress().getHostAddress(),
-                        stream.getRemotePort(), codecSpec, stream.getDtmfType(),
-                        myIdentity(mContext));
+                final long id;
+                try (AttributionSource.ScopedParcelState attributionSourceState = mContext
+                        .getAttributionSource().asScopedParcelState()) {
+                    id = nativeAdd(stream.getMode(), stream.getSocket(),
+                            stream.getRemoteAddress().getHostAddress(),
+                            stream.getRemotePort(), codecSpec, stream.getDtmfType(),
+                            attributionSourceState.getParcel());
+                }
                 mStreams.put(stream, id);
             } catch (NullPointerException e) {
                 throw new IllegalStateException(e);
@@ -181,8 +184,8 @@
         }
     }
 
-    private native long nativeAdd(int mode, int socket, String remoteAddress,
-            int remotePort, String codecSpec, int dtmfType, Identity identity);
+    private native long nativeAdd(int mode, int socket, String remoteAddress, int remotePort,
+            String codecSpec, int dtmfType, Parcel attributionSource);
 
     // Package-private method used by AudioStream.join().
     synchronized void remove(AudioStream stream) {
diff --git a/src/jni/rtp/Android.bp b/src/jni/rtp/Android.bp
index 3469960..325d6b9 100644
--- a/src/jni/rtp/Android.bp
+++ b/src/jni/rtp/Android.bp
@@ -36,17 +36,20 @@
     ],
 
     shared_libs: [
+        "framework-permission-aidl-cpp",
+        "libandroid_runtime",
         "libaudioclient",
         "libaudiofoundation",
+        "libbinder",
         "libcutils",
         "liblog",
         "libnativehelper",
         "libstagefright_amrnb_common",
         "libutils",
-        "media_permission-aidl-cpp",
     ],
     static_libs: [
         "libgsm",
+        "framework-permission-aidl-cpp",
         "libstagefright_amrnbdec",
         "libstagefright_amrnbenc",
     ],
diff --git a/src/jni/rtp/AudioGroup.cpp b/src/jni/rtp/AudioGroup.cpp
index 644b414..e92e799 100644
--- a/src/jni/rtp/AudioGroup.cpp
+++ b/src/jni/rtp/AudioGroup.cpp
@@ -44,6 +44,8 @@
 #include <system/audio.h>
 
 #include <nativehelper/ScopedUtfChars.h>
+#include <android/content/AttributionSourceState.h>
+#include <android_os_Parcel.h>
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
@@ -57,17 +59,10 @@
 
 using namespace android;
 
-using media::permission::Identity;
+using android::content::AttributionSourceState;
 
 int gRandom = -1;
 
-static struct {
-    jfieldID  fieldUid;            // Identity.uid
-    jfieldID  fieldPid;            // Identity.pid
-    jfieldID  fieldPackageName;    // Identity.packageName
-    jfieldID  fieldAttributionTag; // Identity.attributionTag
-} javaIdentityFields;
-
 // We use a circular array to implement jitter buffer. The simplest way is doing
 // a modulo operation on the index while accessing the array. However modulo can
 // be expensive on some platforms, such as ARM. Thus we round up the size of the
@@ -489,7 +484,7 @@
 class AudioGroup
 {
 public:
-    explicit AudioGroup(const Identity &identity);
+    explicit AudioGroup(const AttributionSourceState &attributionSource);
     ~AudioGroup();
     bool set(int sampleRate, int sampleCount);
 
@@ -514,7 +509,7 @@
     int mEventQueue;
     volatile int mDtmfEvent;
 
-    Identity mIdentity;
+    const AttributionSourceState mAttributionSource;
 
     int mMode;
     int mSampleRate;
@@ -563,9 +558,9 @@
     sp<DeviceThread> mDeviceThread;
 };
 
-AudioGroup::AudioGroup(const Identity &identity)
+AudioGroup::AudioGroup(const AttributionSourceState &attributionSource)
+        : mAttributionSource(attributionSource)
 {
-    mIdentity = identity;
     mMode = ON_HOLD;
     mChain = NULL;
     mEventQueue = -1;
@@ -827,7 +822,7 @@
 
     // Initialize AudioTrack and AudioRecord.
     sp<AudioTrack> track = new AudioTrack();
-    sp<AudioRecord> record = new AudioRecord(mGroup->mIdentity);
+    sp<AudioRecord> record = new AudioRecord(mGroup->mAttributionSource);
     // Set caller name so it can be logged in destructor.
     // MediaMetricsConstants.h: AMEDIAMETRICS_PROP_CALLERNAME_VALUE_RTP
     track->setCallerName("rtp");
@@ -860,7 +855,7 @@
     sp<AudioEffect> aec;
     if (mode == ECHO_SUPPRESSION) {
         if (mGroup->platformHasAec()) {
-            aec = new AudioEffect(mGroup->mIdentity);
+            aec = new AudioEffect(mGroup->mAttributionSource);
             aec->set(FX_IID_AEC,
                      NULL,
                      0,
@@ -962,7 +957,7 @@
 
 jlong add(JNIEnv *env, jobject thiz, jint mode,
     jint socket, jstring jRemoteAddress, jint remotePort,
-    jstring jCodecSpec, jint dtmfType, jobject jIdentity)
+    jstring jCodecSpec, jint dtmfType, jobject jAttributionSource)
 {
     AudioCodec *codec = NULL;
     AudioStream *stream = NULL;
@@ -990,25 +985,9 @@
         return 0;
     }
 
-    Identity identity;
-    identity.uid = env->GetIntField(jIdentity, javaIdentityFields.fieldUid);
-    identity.pid = env->GetIntField(jIdentity, javaIdentityFields.fieldPid);
-    jstring packageNameStr = static_cast<jstring>(
-            env->GetObjectField(jIdentity, javaIdentityFields.fieldPackageName));
-    if (packageNameStr == NULL) {
-        identity.packageName = std::nullopt;
-    } else {
-        identity.packageName = std::optional<std::string>(
-                std::string(ScopedUtfChars(env, packageNameStr).c_str()));
-    }
-    jstring attributionTagStr = static_cast<jstring>(
-            env->GetObjectField(jIdentity, javaIdentityFields.fieldAttributionTag));
-    if (attributionTagStr == NULL) {
-        identity.attributionTag = std::nullopt;
-    } else {
-        identity.attributionTag = std::optional<std::string>(
-                std::string(ScopedUtfChars(env, attributionTagStr).c_str()));
-    }
+    Parcel* parcel = parcelForJavaObject(env, jAttributionSource);
+    AttributionSourceState attributionSource;
+    attributionSource.readFromParcel(parcel);
 
     // Create audio codec.
     int codecType = -1;
@@ -1039,7 +1018,7 @@
     group = (AudioGroup *)env->GetLongField(thiz, gNative);
     if (!group) {
         int mode = env->GetIntField(thiz, gMode);
-        group = new AudioGroup(identity);
+        group = new AudioGroup(attributionSource);
         if (!group->set(8000, 256) || !group->setMode(mode)) {
             jniThrowException(env, "java/lang/IllegalStateException",
                 "cannot initialize audio group");
@@ -1095,7 +1074,7 @@
 }
 
 JNINativeMethod gMethods[] = {
-    {"nativeAdd", "(IILjava/lang/String;ILjava/lang/String;ILandroid/media/permission/Identity;)J", (void *)add},
+    {"nativeAdd", "(IILjava/lang/String;ILjava/lang/String;ILandroid/os/Parcel;)J", (void *)add},
     {"nativeRemove", "(J)V", (void *)remove},
     {"nativeSetMode", "(I)V", (void *)setMode},
     {"nativeSendDtmf", "(I)V", (void *)sendDtmf},
@@ -1120,16 +1099,5 @@
         return -1;
     }
 
-    // Get the Identity class and fields
-    jclass identityClass = env->FindClass("android/media/permission/Identity");
-    javaIdentityFields.fieldUid =
-            env->GetFieldID(identityClass, "uid", "I");
-    javaIdentityFields.fieldPid =
-            env->GetFieldID(identityClass, "pid", "I");
-    javaIdentityFields.fieldPackageName =
-            env->GetFieldID(identityClass, "packageName", "Ljava/lang/String;");
-    javaIdentityFields.fieldAttributionTag =
-            env->GetFieldID(identityClass, "attributionTag", "Ljava/lang/String;");
-
     return 0;
 }