Add attributionTag to audio-recordings
... by replacing packageName/uid/pid by the Identity class.
This allows us to track which parts of the app trigger audio-recordings.
90% of the code is just sending around the additional parameters.
This adds it for the Java and native API.
Test: atest CtsAppOpsTestCases
CtsNativeMediaAAudioTestCases
Fixes: 160150145
Change-Id: Ibd7b884f7fcd4668a4e27f997e59cfc3217a9e89
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 9072886..22cf254 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -580,6 +580,37 @@
AAUDIO_API void AAudioStreamBuilder_setDeviceId(AAudioStreamBuilder* builder,
int32_t deviceId) __INTRODUCED_IN(26);
+// TODO b/182392769: reexamine if Identity can be used
+/**
+ * Declare the name of the package creating the stream.
+ *
+ * This is usually {@code Context#getPackageName()}.
+ *
+ * The default, if you do not call this function, is a random package in the calling uid.
+ *
+ * Available since API level 31.
+ *
+ * @param builder reference provided by AAudio_createStreamBuilder()
+ * @param packageName packageName of the calling app.
+ */
+AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* builder,
+ const char * packageName) __INTRODUCED_IN(31);
+
+/**
+ * Declare the attribution tag of the context creating the stream.
+ *
+ * This is usually {@code Context#getAttributionTag()}.
+ *
+ * The default, if you do not call this function, is the default attribution tag.
+ *
+ * Available since API level 31.
+ *
+ * @param builder reference provided by AAudio_createStreamBuilder()
+ * @param attributionTag attributionTag of the calling context.
+ */
+AAUDIO_API void AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder* builder,
+ const char * attributionTag) __INTRODUCED_IN(31);
+
/**
* Request a sample rate in Hertz.
*
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 47cbbb1..fe2d98e 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -85,6 +85,10 @@
],
export_header_lib_headers: ["libaaudio_headers"],
+ export_shared_lib_headers: [
+ "media_permission-aidl-cpp",
+ ],
+
shared_libs: [
"libaudioclient",
"libaudioutils",
@@ -96,6 +100,12 @@
"libutils",
"libbinder",
"aaudio-aidl-cpp",
+ "media_permission-aidl-cpp",
+ "libaudioclient_aidl_conversion",
+ ],
+
+ static_libs: [
+ "media_permission-aidl-cpp",
],
cflags: [
@@ -167,6 +177,7 @@
imports: [
"audio_common-aidl",
"shared-file-region-aidl",
+ "media_permission-aidl",
],
backend:
{
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.cpp b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
index 536395a..5e0a4bb 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
@@ -31,19 +31,15 @@
AAudioStreamRequest::AAudioStreamRequest(const StreamRequest& parcelable) :
mConfiguration(std::move(parcelable.params)),
- mUserId(parcelable.userId),
- mProcessId(parcelable.processId),
+ mIdentity(parcelable.identity),
mSharingModeMatchRequired(parcelable.sharingModeMatchRequired),
mInService(parcelable.inService) {
- static_assert(sizeof(mUserId) == sizeof(parcelable.userId));
- static_assert(sizeof(mProcessId) == sizeof(parcelable.processId));
}
StreamRequest AAudioStreamRequest::parcelable() const {
StreamRequest result;
result.params = std::move(mConfiguration).parcelable();
- result.userId = mUserId;
- result.processId = mProcessId;
+ result.identity = mIdentity;
result.sharingModeMatchRequired = mSharingModeMatchRequired;
result.inService = mInService;
return result;
@@ -54,8 +50,7 @@
}
void AAudioStreamRequest::dump() const {
- ALOGD("mUserId = %d", mUserId);
- ALOGD("mProcessId = %d", mProcessId);
+ ALOGD("mIdentity = %s", mIdentity.toString().c_str());
ALOGD("mSharingModeMatchRequired = %d", mSharingModeMatchRequired);
ALOGD("mInService = %d", mInService);
mConfiguration.dump();
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.h b/media/libaaudio/src/binding/AAudioStreamRequest.h
index 31d3ea1..02341c8 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.h
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.h
@@ -23,6 +23,7 @@
#include <aaudio/StreamRequest.h>
#include "binding/AAudioStreamConfiguration.h"
+#include <android/media/permission/Identity.h>
namespace aaudio {
@@ -33,20 +34,12 @@
// Construct based on a parcelable representation.
explicit AAudioStreamRequest(const StreamRequest& parcelable);
- uid_t getUserId() const {
- return mUserId;
+ const android::media::permission::Identity &getIdentity() const {
+ return mIdentity;
}
- void setUserId(uid_t userId) {
- mUserId = userId;
- }
-
- pid_t getProcessId() const {
- return mProcessId;
- }
-
- void setProcessId(pid_t processId) {
- mProcessId = processId;
+ void setIdentity(const android::media::permission::Identity &identity) {
+ mIdentity = identity;
}
bool isSharingModeMatchRequired() const {
@@ -82,8 +75,7 @@
private:
AAudioStreamConfiguration mConfiguration;
- uid_t mUserId = (uid_t) -1;
- pid_t mProcessId = (pid_t) -1;
+ android::media::permission::Identity mIdentity;
bool mSharingModeMatchRequired = false;
bool mInService = false; // Stream opened by AAudioservice
};
diff --git a/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl b/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl
index 9bf4077..12802e6 100644
--- a/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl
+++ b/media/libaaudio/src/binding/aidl/aaudio/StreamRequest.aidl
@@ -17,11 +17,11 @@
package aaudio;
import aaudio.StreamParameters;
+import android.media.permission.Identity;
parcelable StreamRequest {
StreamParameters params;
- int userId; // = (uid_t) -1;
- int processId; // = (pid_t) -1;
+ Identity identity;
boolean sharingModeMatchRequired; // = false;
boolean inService; // = false; // Stream opened by AAudioservice
}
\ No newline at end of file
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 2815c6a..dc961ad 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -28,7 +28,6 @@
#include <cutils/properties.h>
#include <media/MediaMetricsItem.h>
-#include <utils/String16.h>
#include <utils/Trace.h>
#include "AudioEndpointParcelable.h"
@@ -39,6 +38,7 @@
#include "core/AudioStreamBuilder.h"
#include "fifo/FifoBuffer.h"
#include "utility/AudioClock.h"
+#include <media/AidlConversion.h>
#include "AudioStreamInternal.h"
@@ -49,9 +49,9 @@
// This is needed to make sense of the logs more easily.
#define LOG_TAG (mInService ? "AudioStreamInternal_Service" : "AudioStreamInternal_Client")
-using android::String16;
using android::Mutex;
using android::WrappingBuffer;
+using android::media::permission::Identity;
using namespace aaudio;
@@ -107,9 +107,15 @@
// Request FLOAT for the shared mixer or the device.
request.getConfiguration().setFormat(AUDIO_FORMAT_PCM_FLOAT);
+ // TODO b/182392769: use identity util
+ Identity identity;
+ identity.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
+ identity.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
+ identity.packageName = builder.getOpPackageName();
+ identity.attributionTag = builder.getAttributionTag();
+
// Build the request to send to the server.
- request.setUserId(getuid());
- request.setProcessId(getpid());
+ request.setIdentity(identity);
request.setSharingModeMatchRequired(isSharingModeMatchRequired());
request.setInService(isInService());
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 7c16321..5d49759 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -87,6 +87,22 @@
streamBuilder->setDeviceId(deviceId);
}
+AAUDIO_API void AAudioStreamBuilder_setPackageName(AAudioStreamBuilder* builder,
+ const char* packageName)
+{
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ // Only system apps can read the op package name. For regular apps the regular package name
+ // is a sufficient replacement
+ streamBuilder->setOpPackageName(packageName);
+}
+
+AAUDIO_API void AAudioStreamBuilder_setAttributionTag(AAudioStreamBuilder* builder,
+ const char* attributionTag)
+{
+ AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+ streamBuilder->setAttributionTag(attributionTag);
+}
+
AAUDIO_API void AAudioStreamBuilder_setSampleRate(AAudioStreamBuilder* builder,
int32_t sampleRate)
{
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 2c81c91..0d60120 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -48,6 +48,8 @@
mInputPreset = other.mInputPreset;
mAllowedCapturePolicy = other.mAllowedCapturePolicy;
mIsPrivacySensitive = other.mIsPrivacySensitive;
+ mOpPackageName = other.mOpPackageName;
+ mAttributionTag = other.mAttributionTag;
}
static aaudio_result_t isFormatValid(audio_format_t format) {
@@ -203,4 +205,8 @@
ALOGD("mInputPreset = %6d", mInputPreset);
ALOGD("mAllowedCapturePolicy = %6d", mAllowedCapturePolicy);
ALOGD("mIsPrivacySensitive = %s", mIsPrivacySensitive ? "true" : "false");
+ ALOGD("mOpPackageName = %s", !mOpPackageName.has_value() ?
+ "(null)" : mOpPackageName.value().c_str());
+ ALOGD("mAttributionTag = %s", !mAttributionTag.has_value() ?
+ "(null)" : mAttributionTag.value().c_str());
}
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 3e65b37..bb39d8b 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -136,6 +136,23 @@
mIsPrivacySensitive = privacySensitive;
}
+ const std::optional<std::string> getOpPackageName() const {
+ return mOpPackageName;
+ }
+
+ // TODO b/182392769: reexamine if Identity can be used
+ void setOpPackageName(const std::string opPackageName) {
+ mOpPackageName = opPackageName;
+ }
+
+ const std::optional<std::string> getAttributionTag() const {
+ return mAttributionTag;
+ }
+
+ void setAttributionTag(const std::string attributionTag) {
+ mAttributionTag = attributionTag;
+ }
+
/**
* @return bytes per frame of getFormat()
*/
@@ -167,6 +184,8 @@
aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_UNSPECIFIED;
aaudio_session_id_t mSessionId = AAUDIO_SESSION_ID_NONE;
bool mIsPrivacySensitive = false;
+ std::optional<std::string> mOpPackageName = {};
+ std::optional<std::string> mAttributionTag = {};
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 50a3b38..207a8e3 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -282,4 +282,8 @@
ALOGI("usage = %6d, contentType = %d, inputPreset = %d, allowedCapturePolicy = %d",
getUsage(), getContentType(), getInputPreset(), getAllowedCapturePolicy());
ALOGI("privacy sensitive = %s", isPrivacySensitive() ? "true" : "false");
+ ALOGI("opPackageName = %s", !getOpPackageName().has_value() ?
+ "(null)" : getOpPackageName().value().c_str());
+ ALOGI("attributionTag = %s", !getAttributionTag().has_value() ?
+ "(null)" : getAttributionTag().value().c_str());
}
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 45b2258..7733a04 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -22,6 +22,7 @@
#include <aaudio/AAudio.h>
#include <audio_utils/primitives.h>
+#include <media/AidlConversion.h>
#include <media/AudioRecord.h>
#include <utils/String16.h>
@@ -30,6 +31,8 @@
#include "utility/AudioClock.h"
#include "utility/FixedBlockWriter.h"
+using android::media::permission::Identity;
+
using namespace android;
using namespace aaudio;
@@ -152,13 +155,20 @@
.tags = ""
};
+ // TODO b/182392769: use identity util
+ Identity identity;
+ identity.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
+ identity.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
+ identity.packageName = builder.getOpPackageName();
+ identity.attributionTag = builder.getAttributionTag();
+
// ----------- open the AudioRecord ---------------------
// Might retry, but never more than once.
for (int i = 0; i < 2; i ++) {
const audio_format_t requestedInternalFormat = getDeviceFormat();
mAudioRecord = new AudioRecord(
- mOpPackageName // const String16& opPackageName TODO does not compile
+ identity
);
mAudioRecord->set(
AUDIO_SOURCE_DEFAULT, // ignored because we pass attributes below
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.h b/media/libaaudio/src/legacy/AudioStreamRecord.h
index b2f8ba5..7d0a197 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.h
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.h
@@ -25,6 +25,7 @@
#include "AAudioLegacy.h"
#include "legacy/AudioStreamLegacy.h"
#include "utility/FixedBlockWriter.h"
+#include <android/media/permission/Identity.h>
namespace aaudio {
@@ -86,7 +87,7 @@
FixedBlockWriter mFixedBlockWriter;
// TODO add 64-bit position reporting to AudioRecord and use it.
- android::String16 mOpPackageName;
+ android::media::permission::Identity mIdentity;
// Only one type of conversion buffer is used.
std::unique_ptr<float[]> mFormatConversionBufferFloat;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index af8ff19..142a85c 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -31,6 +31,8 @@
using namespace android;
using namespace aaudio;
+using media::permission::Identity;
+
// Arbitrary and somewhat generous number of bursts.
#define DEFAULT_BURSTS_PER_BUFFER_CAPACITY 8
@@ -147,6 +149,7 @@
};
mAudioTrack = new AudioTrack();
+ // TODO b/182392769: use identity util
mAudioTrack->set(
AUDIO_STREAM_DEFAULT, // ignored because we pass attributes below
getSampleRate(),
@@ -162,8 +165,7 @@
sessionId,
streamTransferType,
NULL, // DEFAULT audio_offload_info_t
- AUDIO_UID_INVALID, // DEFAULT uid
- -1, // DEFAULT pid
+ Identity(), // DEFAULT uid and pid
&attributes,
// WARNING - If doNotReconnect set true then audio stops after plugging and unplugging
// headphones a few times.
diff --git a/media/libaaudio/src/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
index 2e00aa5..1dd44d1 100644
--- a/media/libaaudio/src/libaaudio.map.txt
+++ b/media/libaaudio/src/libaaudio.map.txt
@@ -23,6 +23,8 @@
AAudioStreamBuilder_setAllowedCapturePolicy; # introduced=29
AAudioStreamBuilder_setSessionId; # introduced=28
AAudioStreamBuilder_setPrivacySensitive; # introduced=30
+ AAudioStreamBuilder_setPackageName; # introduced=31
+ AAudioStreamBuilder_setAttributionTag; # introduced=31
AAudioStreamBuilder_openStream;
AAudioStreamBuilder_delete;
AAudioStream_close;