Allow call audio access for default dialer application

The access to call audio (record and play) will be granted only to the app associated with Dialer role, who also includes a new system permission.

Test: Compilation and manual tests
Bug: 135197853

Change-Id: I65ca823c235d4d3420630837427103783ad1d1b0
gugelfrei
Ricardo Correa 5 years ago
parent 0f97ee5a52
commit ac26cf749f

@ -879,6 +879,7 @@ status_t AudioSystem::getOutputForAttr(audio_attributes_t *attr,
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,
@ -888,7 +889,7 @@ status_t AudioSystem::getOutputForAttr(audio_attributes_t *attr,
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT; if (aps == 0) return NO_INIT;
return aps->getOutputForAttr(attr, output, session, stream, pid, uid, return aps->getOutputForAttr(attr, output, session, stream, pid, uid,
config, opPackageName, config,
flags, selectedDeviceId, portId, secondaryOutputs); flags, selectedDeviceId, portId, secondaryOutputs);
} }

@ -214,6 +214,7 @@ public:
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,
@ -252,6 +253,7 @@ public:
} }
data.writeInt32(pid); data.writeInt32(pid);
data.writeInt32(uid); data.writeInt32(uid);
data.writeString16(opPackageName);
data.write(config, sizeof(audio_config_t)); data.write(config, sizeof(audio_config_t));
data.writeInt32(static_cast <uint32_t>(flags)); data.writeInt32(static_cast <uint32_t>(flags));
data.writeInt32(*selectedDeviceId); data.writeInt32(*selectedDeviceId);
@ -1645,6 +1647,11 @@ status_t BnAudioPolicyService::onTransact(
} }
pid_t pid = (pid_t)data.readInt32(); pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32(); uid_t uid = (uid_t)data.readInt32();
String16 opPackageName;
status = data.readString16(&opPackageName);
if (status != NO_ERROR) {
return status;
}
audio_config_t config; audio_config_t config;
memset(&config, 0, sizeof(audio_config_t)); memset(&config, 0, sizeof(audio_config_t));
data.read(&config, sizeof(audio_config_t)); data.read(&config, sizeof(audio_config_t));
@ -1656,7 +1663,7 @@ status_t BnAudioPolicyService::onTransact(
std::vector<audio_io_handle_t> secondaryOutputs; std::vector<audio_io_handle_t> secondaryOutputs;
status = getOutputForAttr(&attr, status = getOutputForAttr(&attr,
&output, session, &stream, pid, uid, &output, session, &stream, pid, uid,
&config, opPackageName, &config,
flags, &selectedDeviceId, &portId, &secondaryOutputs); flags, &selectedDeviceId, &portId, &secondaryOutputs);
reply->writeInt32(status); reply->writeInt32(status);
status = reply->write(&attr, sizeof(audio_attributes_t)); status = reply->write(&attr, sizeof(audio_attributes_t));

@ -240,6 +240,7 @@ public:
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,

@ -70,6 +70,7 @@ public:
if (clientInfo.readFromParcel(parcel) != NO_ERROR) { if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
return DEAD_OBJECT; return DEAD_OBJECT;
} }
opPackageName = parcel->readString16();
if (parcel->readInt32() != 0) { if (parcel->readInt32() != 0) {
// TODO: Using unsecurePointer() has some associated security // TODO: Using unsecurePointer() has some associated security
// pitfalls (see declaration for details). // pitfalls (see declaration for details).
@ -97,6 +98,7 @@ public:
(void)parcel->write(&attr, sizeof(audio_attributes_t)); (void)parcel->write(&attr, sizeof(audio_attributes_t));
(void)parcel->write(&config, sizeof(audio_config_t)); (void)parcel->write(&config, sizeof(audio_config_t));
(void)clientInfo.writeToParcel(parcel); (void)clientInfo.writeToParcel(parcel);
(void)parcel->writeString16(opPackageName);
if (sharedBuffer != 0) { if (sharedBuffer != 0) {
(void)parcel->writeInt32(1); (void)parcel->writeInt32(1);
(void)parcel->writeStrongBinder(IInterface::asBinder(sharedBuffer)); (void)parcel->writeStrongBinder(IInterface::asBinder(sharedBuffer));
@ -119,6 +121,7 @@ public:
audio_attributes_t attr; audio_attributes_t attr;
audio_config_t config; audio_config_t config;
AudioClient clientInfo; AudioClient clientInfo;
String16 opPackageName;
sp<IMemory> sharedBuffer; sp<IMemory> sharedBuffer;
uint32_t notificationsPerBuffer; uint32_t notificationsPerBuffer;
float speed; float speed;

@ -64,6 +64,7 @@ public:
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,

@ -223,6 +223,25 @@ bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
return ok; return ok;
} }
bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid) {
static const String16 sAccessCallAudio("android.permission.ACCESS_CALL_AUDIO");
PermissionController permissionController;
const String16 resolvedOpPackageName = resolveCallingPackage(
permissionController, opPackageName, uid);
if (resolvedOpPackageName.size() == 0) {
ALOGE("accessCallAudioAllowed - FAIL - package not found.");
return false;
}
AppOpsManager appOps;
const int32_t op = appOps.permissionToOpCode(sAccessCallAudio);
const int32_t opResult = appOps.noteOp(op, uid, resolvedOpPackageName);
if (opResult == PermissionController::MODE_DEFAULT) {
// Only allow in case this is a system app with the proper privilege permission
return PermissionCache::checkPermission(sAccessCallAudio, pid, uid);
}
return opResult == PermissionController::MODE_ALLOWED;
}
// privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver // privileged behavior needed by Dialer, Settings, SetupWizard and CellBroadcastReceiver
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) { bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS"); static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
@ -259,28 +278,29 @@ status_t checkIMemory(const sp<IMemory>& iMemory)
return NO_ERROR; return NO_ERROR;
} }
sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() { void MediaPackageManager::loadPackageManager() {
if (mPackageManager != nullptr) {
return;
}
const sp<IServiceManager> sm = defaultServiceManager(); const sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) { if (sm == nullptr) {
ALOGW("%s: failed to retrieve defaultServiceManager", __func__); ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
return nullptr; return;
} }
sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName)); sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
if (packageManager == nullptr) { if (packageManager == nullptr) {
ALOGW("%s: failed to retrieve native package manager", __func__); ALOGW("%s: failed to retrieve native package manager", __func__);
return nullptr; return;
} }
return interface_cast<content::pm::IPackageManagerNative>(packageManager); mPackageManager = interface_cast<content::pm::IPackageManagerNative>(packageManager);
} }
std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) { std::optional<bool> MediaPackageManager::doIsAllowed(uid_t uid) {
/** Can not fetch package manager at construction it may not yet be registered. */
loadPackageManager();
if (mPackageManager == nullptr) { if (mPackageManager == nullptr) {
/** Can not fetch package manager at construction it may not yet be registered. */ ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
mPackageManager = retreivePackageManager(); return std::nullopt;
if (mPackageManager == nullptr) {
ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
return std::nullopt;
}
} }
std::vector<std::string> packageNames; std::vector<std::string> packageNames;

@ -93,6 +93,7 @@ bool modifyDefaultAudioEffectsAllowed(pid_t pid, uid_t uid);
bool dumpAllowed(); bool dumpAllowed();
bool modifyPhoneStateAllowed(pid_t pid, uid_t uid); bool modifyPhoneStateAllowed(pid_t pid, uid_t uid);
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid); bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid);
bool accessCallAudioAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
status_t checkIMemory(const sp<IMemory>& iMemory); status_t checkIMemory(const sp<IMemory>& iMemory);
@ -110,7 +111,7 @@ public:
private: private:
static constexpr const char* nativePackageManagerName = "package_native"; static constexpr const char* nativePackageManagerName = "package_native";
std::optional<bool> doIsAllowed(uid_t uid); std::optional<bool> doIsAllowed(uid_t uid);
sp<content::pm::IPackageManagerNative> retreivePackageManager(); void loadPackageManager();
sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest sp<content::pm::IPackageManagerNative> mPackageManager; // To check apps manifest
uint_t mPackageManagerErrors = 0; uint_t mPackageManagerErrors = 0;
struct Package { struct Package {

@ -326,7 +326,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
ret = AudioSystem::getOutputForAttr(&localAttr, &io, ret = AudioSystem::getOutputForAttr(&localAttr, &io,
actualSessionId, actualSessionId,
&streamType, client.clientPid, client.clientUid, &streamType, client.clientPid, client.clientUid,
&fullConfig, client.packageName, &fullConfig,
(audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
AUDIO_OUTPUT_FLAG_DIRECT), AUDIO_OUTPUT_FLAG_DIRECT),
deviceId, &portId, &secondaryOutputs); deviceId, &portId, &secondaryOutputs);
@ -766,8 +766,9 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
output.outputId = AUDIO_IO_HANDLE_NONE; output.outputId = AUDIO_IO_HANDLE_NONE;
output.selectedDeviceId = input.selectedDeviceId; output.selectedDeviceId = input.selectedDeviceId;
lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType, lStatus = AudioSystem::getOutputForAttr(&localAttr, &output.outputId, sessionId, &streamType,
clientPid, clientUid, &input.config, input.flags, clientPid, clientUid, input.opPackageName,
&output.selectedDeviceId, &portId, &secondaryOutputs); &input.config, input.flags, &output.selectedDeviceId,
&portId, &secondaryOutputs);
if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) { if (lStatus != NO_ERROR || output.outputId == AUDIO_IO_HANDLE_NONE) {
ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus); ALOGE("createTrack() getOutputForAttr() return error %d or invalid output handle", lStatus);

@ -8731,6 +8731,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
&stream, &stream,
client.clientPid, client.clientPid,
client.clientUid, client.clientUid,
client.packageName,
&config, &config,
flags, flags,
&deviceId, &deviceId,

@ -211,6 +211,7 @@ status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,
@ -257,7 +258,8 @@ status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
case AudioPolicyInterface::API_OUTPUT_LEGACY: case AudioPolicyInterface::API_OUTPUT_LEGACY:
break; break;
case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX: case AudioPolicyInterface::API_OUTPUT_TELEPHONY_TX:
if (!modifyPhoneStateAllowed(pid, uid)) { if (!modifyPhoneStateAllowed(pid, uid) &&
!accessCallAudioAllowed(opPackageName, pid, uid)) {
ALOGE("%s() permission denied: modify phone state not allowed for uid %d", ALOGE("%s() permission denied: modify phone state not allowed for uid %d",
__func__, uid); __func__, uid);
result = PERMISSION_DENIED; result = PERMISSION_DENIED;
@ -454,15 +456,22 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
} }
bool canCaptureOutput = captureAudioOutputAllowed(pid, uid); bool canCaptureOutput = captureAudioOutputAllowed(pid, uid);
if ((inputSource == AUDIO_SOURCE_VOICE_UPLINK || bool canCaptureTelephonyOutput = canCaptureOutput
inputSource == AUDIO_SOURCE_VOICE_DOWNLINK || || accessCallAudioAllowed(opPackageName, pid, uid);
inputSource == AUDIO_SOURCE_VOICE_CALL ||
inputSource == AUDIO_SOURCE_ECHO_REFERENCE|| if ((attr->source == AUDIO_SOURCE_ECHO_REFERENCE ||
inputSource == AUDIO_SOURCE_FM_TUNER) && attr->source == AUDIO_SOURCE_FM_TUNER) &&
!canCaptureOutput) { !canCaptureOutput) {
return PERMISSION_DENIED; return PERMISSION_DENIED;
} }
if ((attr->source == AUDIO_SOURCE_VOICE_UPLINK ||
attr->source == AUDIO_SOURCE_VOICE_DOWNLINK ||
attr->source == AUDIO_SOURCE_VOICE_CALL) &&
!canCaptureTelephonyOutput) {
return PERMISSION_DENIED;
}
bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid); bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) { if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
return BAD_VALUE; return BAD_VALUE;
@ -494,6 +503,11 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
break; break;
case AudioPolicyInterface::API_INPUT_TELEPHONY_RX: case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
// FIXME: use the same permission as for remote submix for now. // FIXME: use the same permission as for remote submix for now.
if (!canCaptureTelephonyOutput) {
ALOGE("getInputForAttr() permission denied: call capture not allowed");
status = PERMISSION_DENIED;
}
break;
case AudioPolicyInterface::API_INPUT_MIX_CAPTURE: case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
if (!canCaptureOutput) { if (!canCaptureOutput) {
ALOGE("getInputForAttr() permission denied: capture not allowed"); ALOGE("getInputForAttr() permission denied: capture not allowed");
@ -521,9 +535,13 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
return status; return status;
} }
bool allowAudioCapture = canCaptureOutput ||
(inputType == AudioPolicyInterface::API_INPUT_TELEPHONY_RX &&
canCaptureTelephonyOutput);
sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, *portId, sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, *portId,
*selectedDeviceId, opPackageName, *selectedDeviceId, opPackageName,
canCaptureOutput, canCaptureHotword); allowAudioCapture, canCaptureHotword);
mAudioRecordClients.add(*portId, client); mAudioRecordClients.add(*portId, client);
} }

@ -534,8 +534,8 @@ void AudioPolicyService::updateUidStates_l()
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
bool allowCapture = !isAssistantOnTop bool allowCapture = !isAssistantOnTop
&& ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive) && ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive)
&& !(isSensitiveActive && !(isLatestSensitive || current->canCaptureOutput)) && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureCallOrOutput))
&& !(isInCall && !current->canCaptureOutput); && !(isInCall && !current->canCaptureCallOrOutput);
if (isVirtualSource(source)) { if (isVirtualSource(source)) {
// Allow capture for virtual (remote submix, call audio TX or RX...) sources // Allow capture for virtual (remote submix, call audio TX or RX...) sources
@ -555,7 +555,7 @@ void AudioPolicyService::updateUidStates_l()
} else { } else {
if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) || if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
source == AUDIO_SOURCE_HOTWORD) && source == AUDIO_SOURCE_HOTWORD) &&
(!(isSensitiveActive || isInCall) || current->canCaptureOutput)) { (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) {
allowCapture = true; allowCapture = true;
} }
} }
@ -567,7 +567,7 @@ void AudioPolicyService::updateUidStates_l()
// OR // OR
// Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
if (!isAssistantOnTop if (!isAssistantOnTop
&& (!(isSensitiveActive || isInCall) || current->canCaptureOutput)) { && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) {
allowCapture = true; allowCapture = true;
} }
if (isA11yOnTop) { if (isA11yOnTop) {
@ -580,7 +580,7 @@ void AudioPolicyService::updateUidStates_l()
// All active clients are using HOTWORD source // All active clients are using HOTWORD source
// AND no call is active // AND no call is active
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
if (onlyHotwordActive && !(isInCall && !current->canCaptureOutput)) { if (onlyHotwordActive && !(isInCall && !current->canCaptureCallOrOutput)) {
allowCapture = true; allowCapture = true;
} }
} }

@ -82,6 +82,7 @@ public:
audio_stream_type_t *stream, audio_stream_type_t *stream,
pid_t pid, pid_t pid,
uid_t uid, uid_t uid,
const String16& opPackageName,
const audio_config_t *config, const audio_config_t *config,
audio_output_flags_t flags, audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId, audio_port_handle_t *selectedDeviceId,
@ -807,15 +808,16 @@ private:
const audio_io_handle_t io, uid_t uid, pid_t pid, const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, audio_port_handle_t portId, const audio_session_t session, audio_port_handle_t portId,
const audio_port_handle_t deviceId, const String16& opPackageName, const audio_port_handle_t deviceId, const String16& opPackageName,
bool canCaptureOutput, bool canCaptureHotword) : bool canCaptureCallOrOutput, bool canCaptureHotword) :
AudioClient(attributes, io, uid, pid, session, portId, deviceId), AudioClient(attributes, io, uid, pid, session, portId, deviceId),
opPackageName(opPackageName), startTimeNs(0), opPackageName(opPackageName), startTimeNs(0),
canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {} canCaptureCallOrOutput(canCaptureCallOrOutput),
canCaptureHotword(canCaptureHotword) {}
~AudioRecordClient() override = default; ~AudioRecordClient() override = default;
const String16 opPackageName; // client package name const String16 opPackageName; // client package name
nsecs_t startTimeNs; nsecs_t startTimeNs;
const bool canCaptureOutput; const bool canCaptureCallOrOutput;
const bool canCaptureHotword; const bool canCaptureHotword;
}; };

Loading…
Cancel
Save