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,
pid_t pid,
uid_t uid,
const String16& opPackageName,
const audio_config_t *config,
audio_output_flags_t flags,
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();
if (aps == 0) return NO_INIT;
return aps->getOutputForAttr(attr, output, session, stream, pid, uid,
config,
opPackageName, config,
flags, selectedDeviceId, portId, secondaryOutputs);
}

@ -214,6 +214,7 @@ public:
audio_stream_type_t *stream,
pid_t pid,
uid_t uid,
const String16& opPackageName,
const audio_config_t *config,
audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId,
@ -252,6 +253,7 @@ public:
}
data.writeInt32(pid);
data.writeInt32(uid);
data.writeString16(opPackageName);
data.write(config, sizeof(audio_config_t));
data.writeInt32(static_cast <uint32_t>(flags));
data.writeInt32(*selectedDeviceId);
@ -1645,6 +1647,11 @@ status_t BnAudioPolicyService::onTransact(
}
pid_t pid = (pid_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;
memset(&config, 0, 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;
status = getOutputForAttr(&attr,
&output, session, &stream, pid, uid,
&config,
opPackageName, &config,
flags, &selectedDeviceId, &portId, &secondaryOutputs);
reply->writeInt32(status);
status = reply->write(&attr, sizeof(audio_attributes_t));

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

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

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

@ -223,6 +223,25 @@ bool modifyPhoneStateAllowed(pid_t pid, uid_t uid) {
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
bool bypassInterruptionPolicyAllowed(pid_t pid, uid_t uid) {
static const String16 sWriteSecureSettings("android.permission.WRITE_SECURE_SETTINGS");
@ -259,28 +278,29 @@ status_t checkIMemory(const sp<IMemory>& iMemory)
return NO_ERROR;
}
sp<content::pm::IPackageManagerNative> MediaPackageManager::retreivePackageManager() {
void MediaPackageManager::loadPackageManager() {
if (mPackageManager != nullptr) {
return;
}
const sp<IServiceManager> sm = defaultServiceManager();
if (sm == nullptr) {
ALOGW("%s: failed to retrieve defaultServiceManager", __func__);
return nullptr;
return;
}
sp<IBinder> packageManager = sm->checkService(String16(nativePackageManagerName));
if (packageManager == nullptr) {
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) {
/** Can not fetch package manager at construction it may not yet be registered. */
loadPackageManager();
if (mPackageManager == nullptr) {
/** Can not fetch package manager at construction it may not yet be registered. */
mPackageManager = retreivePackageManager();
if (mPackageManager == nullptr) {
ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
return std::nullopt;
}
ALOGW("%s: Playback capture is denied as package manager is not reachable", __func__);
return std::nullopt;
}
std::vector<std::string> packageNames;

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

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

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

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

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

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

Loading…
Cancel
Save