Add setMasterMono and getMasterMono
Bug: 15283594
Bug: 22700363
Change-Id: I32dc1fcecf285967a61bd508af3bb299595db57d
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 11dabae..3040833 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -842,15 +842,15 @@
goto non_direct_output;
}
- // Do not allow offloading if one non offloadable effect is enabled. This prevents from
- // creating an offloaded track and tearing it down immediately after start when audioflinger
- // detects there is an active non offloadable effect.
+ // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
+ // This prevents creating an offloaded track and tearing it down immediately after start
+ // when audioflinger detects there is an active non offloadable effect.
// FIXME: We should check the audio session here but we do not have it in this context.
// This may prevent offloading in rare situations where effects are left active by apps
// in the background.
if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
- !mEffects.isNonOffloadableEffectEnabled()) {
+ !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
profile = getProfileForDirectOutput(device,
samplingRate,
format,
@@ -2088,6 +2088,8 @@
result.append(buffer);
snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
result.append(buffer);
+ snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
+ result.append(buffer);
write(fd, result.string(), result.size());
@@ -2115,6 +2117,10 @@
offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
offloadInfo.has_video);
+ if (mMasterMono) {
+ return false; // no offloading if mono is set.
+ }
+
// Check if offload has been disabled
char propValue[PROPERTY_VALUE_MAX];
if (property_get("audio.offload.disable", propValue, "0")) {
@@ -2878,6 +2884,44 @@
return status;
}
+status_t AudioPolicyManager::setMasterMono(bool mono)
+{
+ if (mMasterMono == mono) {
+ return NO_ERROR;
+ }
+ mMasterMono = mono;
+ // if enabling mono we close all offloaded devices, which will invalidate the
+ // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
+ // for recreating the new AudioTrack as non-offloaded PCM.
+ //
+ // If disabling mono, we leave all tracks as is: we don't know which clients
+ // and tracks are able to be recreated as offloaded. The next "song" should
+ // play back offloaded.
+ if (mMasterMono) {
+ Vector<audio_io_handle_t> offloaded;
+ for (size_t i = 0; i < mOutputs.size(); ++i) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
+ if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ offloaded.push(desc->mIoHandle);
+ }
+ }
+ for (size_t i = 0; i < offloaded.size(); ++i) {
+ closeOutput(offloaded[i]);
+ }
+ }
+ // update master mono for all remaining outputs
+ for (size_t i = 0; i < mOutputs.size(); ++i) {
+ updateMono(mOutputs.keyAt(i));
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getMasterMono(bool *mono)
+{
+ *mono = mMasterMono;
+ return NO_ERROR;
+}
+
status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
@@ -2944,7 +2988,8 @@
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
- mTtsOutputAvailable(false)
+ mTtsOutputAvailable(false),
+ mMasterMono(false)
{
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
@@ -3368,6 +3413,7 @@
{
outputDesc->setIoHandle(output);
mOutputs.add(output, outputDesc);
+ updateMono(output); // update mono status when adding to output list
nextAudioPortGeneration();
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 59163ca..37faac2 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -24,6 +24,7 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/SortedVector.h>
+#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>
#include "AudioPolicyInterface.h"
@@ -231,6 +232,9 @@
uid_t uid);
virtual status_t stopAudioSource(audio_io_handle_t handle);
+ virtual status_t setMasterMono(bool mono);
+ virtual status_t getMasterMono(bool *mono);
+
// Audio policy configuration file parsing (audio_policy.conf)
// TODO candidates to be moved to ConfigParsingUtils
void defaultAudioPolicyConfig(void);
@@ -565,6 +569,7 @@
bool mBeaconMuted; // has STREAM_TTS been muted
bool mTtsOutputAvailable; // true if a dedicated output for TTS stream is available
+ bool mMasterMono; // true if we wish to force all outputs to mono
AudioPolicyMixCollection mPolicyMixes; // list of registered mixes
#ifdef AUDIO_POLICY_TEST
@@ -644,6 +649,11 @@
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
+ void updateMono(audio_io_handle_t output) {
+ AudioParameter param;
+ param.addInt(String8(AUDIO_PARAMETER_MONO_OUTPUT), (int)mMasterMono);
+ mpClientInterface->setParameters(output, param.toString());
+ }
};
};