summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/audioflinger/AudioFlinger.cpp7
-rw-r--r--services/audiopolicy/AudioPolicyClientImplLegacy.cpp7
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h13
-rw-r--r--services/audiopolicy/AudioPolicyInterfaceImpl.cpp38
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp20
-rw-r--r--services/audiopolicy/AudioPolicyManager.h3
6 files changed, 74 insertions, 14 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 8acfc07..ccc05a1 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1433,13 +1433,6 @@ sp<IAudioRecord> AudioFlinger::openRecord(
goto Exit;
}
- if (deviceRequiresCaptureAudioOutputPermission(thread->inDevice())
- && !captureAudioOutputAllowed()) {
- ALOGE("openRecord() permission denied: capture not allowed");
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
pid_t pid = IPCThreadState::self()->getCallingPid();
client = registerPid(pid);
diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
index 97719da..a79f8ae 100644
--- a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
@@ -188,6 +188,13 @@ static audio_io_handle_t open_input(audio_module_handle_t module,
if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || pDevices == NULL) {
return AUDIO_IO_HANDLE_NONE;
}
+
+ if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX)
+ && !captureAudioOutputAllowed()) {
+ ALOGE("open_input() permission denied: capture not allowed");
+ return AUDIO_IO_HANDLE_NONE;
+ }
+
audio_config_t config = AUDIO_CONFIG_INITIALIZER;;
config.sample_rate = *pSamplingRate;
config.format = *pFormat;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 2826cad..4508fa7 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -57,6 +57,16 @@ class AudioPolicyInterface
{
public:
+ typedef enum {
+ API_INPUT_INVALID = -1,
+ API_INPUT_LEGACY = 0,// e.g. audio recording from a microphone
+ API_INPUT_MIX_CAPTURE,// used for "remote submix", capture of the media to play it remotely
+ API_INPUT_MIX_EXT_POLICY_REROUTE,// used for platform audio rerouting, where mixes are
+ // handled by external and dynamically installed
+ // policies which reroute audio mixes
+ } input_type_t;
+
+public:
virtual ~AudioPolicyInterface() {}
//
// configuration functions
@@ -120,7 +130,8 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags) = 0;
+ audio_input_flags_t flags,
+ input_type_t *inputType) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session) = 0;
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index d3c9013..a45dbb3 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -266,17 +266,47 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
}
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status;
+ AudioPolicyInterface::input_type_t inputType;
{
Mutex::Autolock _l(mLock);
// the audio_in_acoustics_t parameter is ignored by get_input()
status = mAudioPolicyManager->getInputForAttr(attr, input, session,
samplingRate, format, channelMask,
- flags);
+ flags, &inputType);
audioPolicyEffects = mAudioPolicyEffects;
+
+ if (status == NO_ERROR) {
+ // enforce permission (if any) required for each type of input
+ switch (inputType) {
+ case AudioPolicyInterface::API_INPUT_LEGACY:
+ break;
+ case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
+ if (!captureAudioOutputAllowed()) {
+ ALOGE("getInputForAttr() permission denied: capture not allowed");
+ status = PERMISSION_DENIED;
+ }
+ break;
+ case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
+ if (!modifyAudioRoutingAllowed()) {
+ ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
+ status = PERMISSION_DENIED;
+ }
+ break;
+ case AudioPolicyInterface::API_INPUT_INVALID:
+ default:
+ LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",
+ (int)inputType);
+ }
+ }
+
+ if (status != NO_ERROR) {
+ if (status == PERMISSION_DENIED) {
+ mAudioPolicyManager->releaseInput(*input, session);
+ }
+ return status;
+ }
}
- if (status != NO_ERROR) {
- return status;
- }
+
if (audioPolicyEffects != 0) {
// create audio pre processors according to input source
status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 744556d..a71aa53 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -1419,13 +1419,15 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags)
+ audio_input_flags_t flags,
+ input_type_t *inputType)
{
ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
"session %d, flags %#x",
attr->source, samplingRate, format, channelMask, session, flags);
*input = AUDIO_IO_HANDLE_NONE;
+ *inputType = API_INPUT_INVALID;
audio_devices_t device;
// handle legacy remote submix case where the address was not always specified
String8 address = String8("");
@@ -1447,6 +1449,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
return BAD_VALUE;
}
policyMix = &mPolicyMixes[index]->mMix;
+ *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
} else {
device = getDeviceAndMixForInputSource(attr->source, &policyMix);
if (device == AUDIO_DEVICE_NONE) {
@@ -1455,8 +1458,21 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
}
if (policyMix != NULL) {
address = policyMix->mRegistrationId;
+ if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
+ // there is an external policy, but this input is attached to a mix of recorders,
+ // meaning it receives audio injected into the framework, so the recorder doesn't
+ // know about it and is therefore considered "legacy"
+ *inputType = API_INPUT_LEGACY;
+ } else {
+ // recording a mix of players defined by an external policy, we're rerouting for
+ // an external policy
+ *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
+ }
} else if (audio_is_remote_submix_device(device)) {
address = String8("0");
+ *inputType = API_INPUT_MIX_CAPTURE;
+ } else {
+ *inputType = API_INPUT_LEGACY;
}
// adapt channel selection to input source
switch (attr->source) {
@@ -1546,6 +1562,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
inputDesc->mIsSoundTrigger = isSoundTrigger;
inputDesc->mPolicyMix = policyMix;
+ ALOGV("getInputForAttr() returns input type = %d", inputType);
+
addInput(*input, inputDesc);
mpClientInterface->onAudioPortListUpdate();
return NO_ERROR;
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index ff3afab..4c976a3 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -112,7 +112,8 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags);
+ audio_input_flags_t flags,
+ input_type_t *inputType);
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,