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/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 07122cc..bf8f2ee 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -25,6 +25,7 @@
#include <media/MediaMetricsItem.h>
#include <media/PolicyAidlConversion.h>
#include <utils/Log.h>
+#include <android/media/permission/Identity.h>
#define VALUE_OR_RETURN_BINDER_STATUS(x) \
({ auto _tmp = (x); \
@@ -42,6 +43,7 @@
namespace android {
using binder::Status;
using aidl_utils::binderStatusFromStatusT;
+using media::permission::Identity;
const std::vector<audio_usage_t>& SYSTEM_USAGES = {
AUDIO_USAGE_CALL_ASSISTANT,
@@ -62,15 +64,15 @@
}
status_t AudioPolicyService::validateUsage(audio_usage_t usage) {
- return validateUsage(usage, IPCThreadState::self()->getCallingPid(),
- IPCThreadState::self()->getCallingUid());
+ return validateUsage(usage, getCallingIdentity());
}
-status_t AudioPolicyService::validateUsage(audio_usage_t usage, pid_t pid, uid_t uid) {
+status_t AudioPolicyService::validateUsage(audio_usage_t usage, const Identity& identity) {
if (isSystemUsage(usage)) {
if (isSupportedSystemUsage(usage)) {
- if (!modifyAudioRoutingAllowed(pid, uid)) {
- ALOGE("permission denied: modify audio routing not allowed for uid %d", uid);
+ if (!modifyAudioRoutingAllowed(identity)) {
+ ALOGE(("permission denied: modify audio routing not allowed "
+ "for identity %s"), identity.toString().c_str());
return PERMISSION_DENIED;
}
} else {
@@ -276,8 +278,7 @@
Status AudioPolicyService::getOutputForAttr(const media::AudioAttributesInternal& attrAidl,
int32_t sessionAidl,
- int32_t pidAidl,
- int32_t uidAidl,
+ const Identity& identity,
const media::AudioConfig& configAidl,
int32_t flagsAidl,
int32_t selectedDeviceIdAidl,
@@ -288,8 +289,6 @@
audio_session_t session = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_session_t(sessionAidl));
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
- pid_t pid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_pid_t(pidAidl));
- uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
audio_config_t config = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioConfig_audio_config_t(configAidl));
audio_output_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
@@ -307,22 +306,28 @@
RETURN_IF_BINDER_ERROR(
binderStatusFromStatusT(AudioValidator::validateAudioAttributes(attr, "68953950")));
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr.usage, pid, uid)));
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr.usage, identity)));
ALOGV("%s()", __func__);
Mutex::Autolock _l(mLock);
+ // TODO b/182392553: refactor or remove
+ Identity adjIdentity = identity;
const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- if (!isAudioServerOrMediaServerUid(callingUid) || uid == (uid_t)-1) {
- ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
- "%s uid %d tried to pass itself off as %d", __func__, callingUid, uid);
- uid = callingUid;
+ if (!isAudioServerOrMediaServerUid(callingUid) || identity.uid == -1) {
+ int32_t callingUidAidl = VALUE_OR_RETURN_BINDER_STATUS(
+ legacy2aidl_uid_t_int32_t(callingUid));
+ ALOGW_IF(identity.uid != -1 && identity.uid != callingUidAidl,
+ "%s uid %d tried to pass itself off as %d", __func__,
+ callingUidAidl, identity.uid);
+ adjIdentity.uid = callingUidAidl;
}
- if (!mPackageManager.allowPlaybackCapture(uid)) {
+ if (!mPackageManager.allowPlaybackCapture(VALUE_OR_RETURN_BINDER_STATUS(
+ aidl2legacy_int32_t_uid_t(adjIdentity.uid)))) {
attr.flags = static_cast<audio_flags_mask_t>(attr.flags | AUDIO_FLAG_NO_MEDIA_PROJECTION);
}
if (((attr.flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
- && !bypassInterruptionPolicyAllowed(pid, uid)) {
+ && !bypassInterruptionPolicyAllowed(identity)) {
attr.flags = static_cast<audio_flags_mask_t>(
attr.flags & ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE));
}
@@ -330,7 +335,7 @@
AudioPolicyInterface::output_type_t outputType;
status_t result = mAudioPolicyManager->getOutputForAttr(&attr, &output, session,
&stream,
- uid,
+ adjIdentity,
&config,
&flags, &selectedDeviceId, &portId,
&secondaryOutputs,
@@ -343,16 +348,16 @@
case AudioPolicyInterface::API_OUTPUT_LEGACY:
break;
case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
- if (!modifyPhoneStateAllowed(pid, uid)) {
+ if (!modifyPhoneStateAllowed(adjIdentity)) {
ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
- __func__, uid);
+ __func__, adjIdentity.uid);
result = PERMISSION_DENIED;
}
break;
case AudioPolicyInterface::API_OUT_MIX_PLAYBACK:
- if (!modifyAudioRoutingAllowed(pid, uid)) {
+ if (!modifyAudioRoutingAllowed(adjIdentity)) {
ALOGE("%s() permission denied: modify audio routing not allowed for uid %d",
- __func__, uid);
+ __func__, adjIdentity.uid);
result = PERMISSION_DENIED;
}
break;
@@ -365,8 +370,8 @@
if (result == NO_ERROR) {
sp<AudioPlaybackClient> client =
- new AudioPlaybackClient(attr, output, uid, pid, session, portId, selectedDeviceId,
- stream);
+ new AudioPlaybackClient(attr, output, adjIdentity, session,
+ portId, selectedDeviceId, stream);
mAudioPlaybackClients.add(portId, client);
_aidl_return->output = VALUE_OR_RETURN_BINDER_STATUS(
@@ -502,9 +507,7 @@
int32_t inputAidl,
int32_t riidAidl,
int32_t sessionAidl,
- int32_t pidAidl,
- int32_t uidAidl,
- const std::string& opPackageNameAidl,
+ const Identity& identity,
const media::AudioConfigBase& configAidl,
int32_t flagsAidl,
int32_t selectedDeviceIdAidl,
@@ -517,10 +520,6 @@
aidl2legacy_int32_t_audio_unique_id_t(riidAidl));
audio_session_t session = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_session_t(sessionAidl));
- pid_t pid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_pid_t(pidAidl));
- uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
- String16 opPackageName = VALUE_OR_RETURN_BINDER_STATUS(
- aidl2legacy_string_view_String16(opPackageNameAidl));
audio_config_base_t config = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioConfigBase_audio_config_base_t(configAidl));
audio_input_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
@@ -536,7 +535,6 @@
RETURN_IF_BINDER_ERROR(
binderStatusFromStatusT(AudioValidator::validateAudioAttributes(attr, "68953950")));
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr.usage, pid, uid)));
audio_source_t inputSource = attr.source;
if (inputSource == AUDIO_SOURCE_DEFAULT) {
@@ -552,34 +550,42 @@
return binderStatusFromStatusT(BAD_VALUE);
}
- bool updatePid = (pid == -1);
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+ // Make sure identity represents the current caller
+ Identity adjIdentity = identity;
+ // TODO b/182392553: refactor or remove
+ bool updatePid = (identity.pid == -1);
+ const uid_t callingUid =IPCThreadState::self()->getCallingUid();
+ const uid_t currentUid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(identity.uid));
if (!isAudioServerOrMediaServerUid(callingUid)) {
- ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
- "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
- uid = callingUid;
+ ALOGW_IF(currentUid != (uid_t)-1 && currentUid != callingUid,
+ "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid,
+ currentUid);
+ adjIdentity.uid = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_uid_t_int32_t(callingUid));
updatePid = true;
}
if (updatePid) {
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
- ALOGW_IF(pid != (pid_t)-1 && pid != callingPid,
+ const int32_t callingPid = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_pid_t_int32_t(
+ IPCThreadState::self()->getCallingPid()));
+ ALOGW_IF(identity.pid != -1 && identity.pid != callingPid,
"%s uid %d pid %d tried to pass itself off as pid %d",
- __func__, callingUid, callingPid, pid);
- pid = callingPid;
+ __func__, adjIdentity.uid, callingPid, identity.pid);
+ adjIdentity.pid = callingPid;
}
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(validateUsage(attr.usage, adjIdentity)));
+
// check calling permissions.
// Capturing from FM_TUNER source is controlled by captureTunerAudioInputAllowed() and
// captureAudioOutputAllowed() (deprecated) as this does not affect users privacy
// as does capturing from an actual microphone.
- if (!(recordingAllowed(opPackageName, pid, uid) || attr.source == AUDIO_SOURCE_FM_TUNER)) {
- ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
- __func__, uid, pid);
+ if (!(recordingAllowed(adjIdentity) || attr.source == AUDIO_SOURCE_FM_TUNER)) {
+ ALOGE("%s permission denied: recording not allowed for %s",
+ __func__, adjIdentity.toString().c_str());
return binderStatusFromStatusT(PERMISSION_DENIED);
}
- bool canCaptureOutput = captureAudioOutputAllowed(pid, uid);
+ bool canCaptureOutput = captureAudioOutputAllowed(adjIdentity);
if ((inputSource == AUDIO_SOURCE_VOICE_UPLINK ||
inputSource == AUDIO_SOURCE_VOICE_DOWNLINK ||
inputSource == AUDIO_SOURCE_VOICE_CALL ||
@@ -589,12 +595,12 @@
}
if (inputSource == AUDIO_SOURCE_FM_TUNER
- && !captureTunerAudioInputAllowed(pid, uid)
+ && !captureTunerAudioInputAllowed(adjIdentity)
&& !canCaptureOutput) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
- bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
+ bool canCaptureHotword = captureHotwordAllowed(adjIdentity);
if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -602,7 +608,7 @@
if (((flags & AUDIO_INPUT_FLAG_HW_HOTWORD) != 0)
&& !canCaptureHotword) {
ALOGE("%s: permission denied: hotword mode not allowed"
- " for uid %d pid %d", __func__, uid, pid);
+ " for uid %d pid %d", __func__, adjIdentity.uid, adjIdentity.pid);
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -615,10 +621,11 @@
{
AutoCallerClear acc;
// the audio_in_acoustics_t parameter is ignored by get_input()
- status = mAudioPolicyManager->getInputForAttr(&attr, &input, riid, session, uid,
- &config,
+ status = mAudioPolicyManager->getInputForAttr(&attr, &input, riid, session,
+ adjIdentity, &config,
flags, &selectedDeviceId,
&inputType, &portId);
+
}
audioPolicyEffects = mAudioPolicyEffects;
@@ -639,7 +646,7 @@
}
break;
case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
- if (!modifyAudioRoutingAllowed(pid, uid)) {
+ if (!modifyAudioRoutingAllowed(adjIdentity)) {
ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
status = PERMISSION_DENIED;
}
@@ -659,8 +666,8 @@
return binderStatusFromStatusT(status);
}
- sp<AudioRecordClient> client = new AudioRecordClient(attr, input, uid, pid, session, portId,
- selectedDeviceId, opPackageName,
+ sp<AudioRecordClient> client = new AudioRecordClient(attr, input, session, portId,
+ selectedDeviceId, adjIdentity,
canCaptureOutput, canCaptureHotword);
mAudioRecordClients.add(portId, client);
}
@@ -711,12 +718,15 @@
client = mAudioRecordClients.valueAt(index);
}
+ std::stringstream msg;
+ msg << "Audio recording on session " << client->session;
+
// check calling permissions
- if (!(startRecording(client->opPackageName, client->pid, client->uid,
- client->attributes.source)
+ if (!(startRecording(client->identity, String16(msg.str().c_str()),
+ client->attributes.source)
|| client->attributes.source == AUDIO_SOURCE_FM_TUNER)) {
- ALOGE("%s permission denied: recording not allowed for uid %d pid %d",
- __func__, client->uid, client->pid);
+ ALOGE("%s permission denied: recording not allowed for identity %s",
+ __func__, client->identity.toString().c_str());
return binderStatusFromStatusT(PERMISSION_DENIED);
}
@@ -760,11 +770,13 @@
item->setCString(kAudioPolicyRqstSrc,
toString(client->attributes.source).c_str());
item->setInt32(kAudioPolicyRqstSession, client->session);
- if (client->opPackageName.size() != 0) {
+ if (client->identity.packageName.has_value() &&
+ client->identity.packageName.value().size() != 0) {
item->setCString(kAudioPolicyRqstPkg,
- std::string(String8(client->opPackageName).string()).c_str());
+ client->identity.packageName.value().c_str());
} else {
- item->setCString(kAudioPolicyRqstPkg, std::to_string(client->uid).c_str());
+ item->setCString(kAudioPolicyRqstPkg,
+ std::to_string(client->identity.uid).c_str());
}
item->setCString(
kAudioPolicyRqstDevice, getDeviceTypeStrForPortId(client->deviceId).c_str());
@@ -780,12 +792,13 @@
item->setCString(kAudioPolicyActiveSrc,
toString(other->attributes.source).c_str());
item->setInt32(kAudioPolicyActiveSession, other->session);
- if (other->opPackageName.size() != 0) {
+ if (other->identity.packageName.has_value() &&
+ other->identity.packageName.value().size() != 0) {
item->setCString(kAudioPolicyActivePkg,
- std::string(String8(other->opPackageName).string()).c_str());
+ other->identity.packageName.value().c_str());
} else {
- item->setCString(kAudioPolicyRqstPkg,
- std::to_string(other->uid).c_str());
+ item->setCString(kAudioPolicyRqstPkg, std::to_string(
+ other->identity.uid).c_str());
}
item->setCString(kAudioPolicyActiveDevice,
getDeviceTypeStrForPortId(other->deviceId).c_str());
@@ -801,8 +814,7 @@
client->active = false;
client->startTimeNs = 0;
updateUidStates_l();
- finishRecording(client->opPackageName, client->uid,
- client->attributes.source);
+ finishRecording(client->identity, client->attributes.source);
}
return binderStatusFromStatusT(status);
@@ -831,8 +843,7 @@
updateUidStates_l();
// finish the recording app op
- finishRecording(client->opPackageName, client->uid,
- client->attributes.source);
+ finishRecording(client->identity, client->attributes.source);
AutoCallerClear acc;
return binderStatusFromStatusT(mAudioPolicyManager->stopInput(portId));
}
@@ -1629,15 +1640,15 @@
bool needCaptureMediaOutput = std::any_of(mixes.begin(), mixes.end(), [](auto& mix) {
return mix.mAllowPrivilegedMediaPlaybackCapture; });
- const uid_t callingUid = IPCThreadState::self()->getCallingUid();
- const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+ const Identity identity = getCallingIdentity();
- if (needCaptureMediaOutput && !captureMediaOutputAllowed(callingPid, callingUid)) {
+
+ if (needCaptureMediaOutput && !captureMediaOutputAllowed(identity)) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}
if (needCaptureVoiceCommunicationOutput &&
- !captureVoiceCommunicationOutputAllowed(callingPid, callingUid)) {
+ !captureVoiceCommunicationOutputAllowed(identity)) {
return binderStatusFromStatusT(PERMISSION_DENIED);
}