Merge "Invalidate tracks by a list of port id."
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 259af97..81abfc2 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -493,12 +493,6 @@
return statusTFromBinderStatus(mDelegate->closeInput(inputAidl));
}
-status_t AudioFlingerClientAdapter::invalidateStream(audio_stream_type_t stream) {
- AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
- legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
- return statusTFromBinderStatus(mDelegate->invalidateStream(streamAidl));
-}
-
status_t AudioFlingerClientAdapter::setVoiceVolume(float volume) {
return statusTFromBinderStatus(mDelegate->setVoiceVolume(volume));
}
@@ -858,6 +852,14 @@
return statusTFromBinderStatus(mDelegate->getSoundDoseInterface(callback, soundDose));
}
+status_t AudioFlingerClientAdapter::invalidateTracks(
+ const std::vector<audio_port_handle_t>& portIds) {
+ std::vector<int32_t> portIdsAidl = VALUE_OR_RETURN_STATUS(
+ convertContainer<std::vector<int32_t>>(
+ portIds, legacy2aidl_audio_port_handle_t_int32_t));
+ return statusTFromBinderStatus(mDelegate->invalidateTracks(portIdsAidl));
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// AudioFlingerServerAdapter
AudioFlingerServerAdapter::AudioFlingerServerAdapter(
@@ -1090,12 +1092,6 @@
return Status::fromStatusT(mDelegate->closeInput(inputLegacy));
}
-Status AudioFlingerServerAdapter::invalidateStream(AudioStreamType stream) {
- audio_stream_type_t streamLegacy = VALUE_OR_RETURN_BINDER(
- aidl2legacy_AudioStreamType_audio_stream_type_t(stream));
- return Status::fromStatusT(mDelegate->invalidateStream(streamLegacy));
-}
-
Status AudioFlingerServerAdapter::setVoiceVolume(float volume) {
return Status::fromStatusT(mDelegate->setVoiceVolume(volume));
}
@@ -1385,4 +1381,12 @@
return Status::fromStatusT(mDelegate->getSoundDoseInterface(callback, soundDose));
}
+Status AudioFlingerServerAdapter::invalidateTracks(const std::vector<int32_t>& portIds) {
+ std::vector<audio_port_handle_t> portIdsLegacy = VALUE_OR_RETURN_BINDER(
+ convertContainer<std::vector<audio_port_handle_t>>(
+ portIds, aidl2legacy_int32_t_audio_port_handle_t));
+ RETURN_BINDER_IF_ERROR(mDelegate->invalidateTracks(portIdsLegacy));
+ return Status::ok();
+}
+
} // namespace android
diff --git a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
index 2f74404..b94af6e 100644
--- a/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioFlingerService.aidl
@@ -134,8 +134,6 @@
OpenInputResponse openInput(in OpenInputRequest request);
void closeInput(int /* audio_io_handle_t */ input);
- void invalidateStream(AudioStreamType stream);
-
void setVoiceVolume(float volume);
RenderPosition getRenderPosition(int /* audio_io_handle_t */ output);
@@ -254,6 +252,11 @@
*/
ISoundDose getSoundDoseInterface(in ISoundDoseCallback callback);
+ /**
+ * Invalidate all tracks with given port ids.
+ */
+ void invalidateTracks(in int[] /* audio_port_handle_t[] */ portIds);
+
// When adding a new method, please review and update
// IAudioFlinger.h AudioFlingerServerAdapter::Delegate::TransactionCode
// AudioFlinger.cpp AudioFlinger::onTransactWrapper()
diff --git a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
index 5536bcb..47fe0f6 100644
--- a/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
+++ b/media/libaudioclient/fuzzer/audioflinger_fuzzer.cpp
@@ -584,7 +584,12 @@
float balance = mFdp.ConsumeFloatingPoint<float>();
af->getMasterBalance(&balance);
- af->invalidateStream(static_cast<audio_stream_type_t>(mFdp.ConsumeIntegral<uint32_t>()));
+
+ std::vector<audio_port_handle_t> tracks;
+ for (int i = 0; i < mFdp.ConsumeIntegralInRange<int32_t>(0, MAX_ARRAY_LENGTH); ++i) {
+ tracks.push_back(static_cast<audio_port_handle_t>(mFdp.ConsumeIntegral<int32_t>()));
+ }
+ af->invalidateTracks(tracks);
}
status_t AudioFlingerFuzzer::invokeAudioInputDevice() {
diff --git a/media/libaudioclient/include/media/AudioCommonTypes.h b/media/libaudioclient/include/media/AudioCommonTypes.h
index 862a0f9..2567542 100644
--- a/media/libaudioclient/include/media/AudioCommonTypes.h
+++ b/media/libaudioclient/include/media/AudioCommonTypes.h
@@ -94,6 +94,7 @@
using AttributesVector = std::vector<audio_attributes_t>;
using StreamTypeVector = std::vector<audio_stream_type_t>;
+using PortHandleVector = std::vector<audio_port_handle_t>;
using TrackSecondaryOutputsMap = std::map<audio_port_handle_t, std::vector<audio_io_handle_t>>;
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 6057d81..05630bb 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -268,8 +268,6 @@
virtual status_t closeInput(audio_io_handle_t input) = 0;
- virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
-
virtual status_t setVoiceVolume(float volume) = 0;
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
@@ -374,6 +372,8 @@
virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) = 0;
+
+ virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
};
/**
@@ -428,7 +428,6 @@
status_t openInput(const media::OpenInputRequest& request,
media::OpenInputResponse* response) override;
status_t closeInput(audio_io_handle_t input) override;
- status_t invalidateStream(audio_stream_type_t stream) override;
status_t setVoiceVolume(float volume) override;
status_t getRenderPosition(uint32_t* halFrames, uint32_t* dspFrames,
audio_io_handle_t output) const override;
@@ -482,6 +481,7 @@
audio_io_handle_t output, std::vector<audio_latency_mode_t>* modes) override;
status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose) override;
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
private:
const sp<media::IAudioFlingerService> mDelegate;
@@ -535,7 +535,6 @@
RESTORE_OUTPUT = media::BnAudioFlingerService::TRANSACTION_restoreOutput,
OPEN_INPUT = media::BnAudioFlingerService::TRANSACTION_openInput,
CLOSE_INPUT = media::BnAudioFlingerService::TRANSACTION_closeInput,
- INVALIDATE_STREAM = media::BnAudioFlingerService::TRANSACTION_invalidateStream,
SET_VOICE_VOLUME = media::BnAudioFlingerService::TRANSACTION_setVoiceVolume,
GET_RENDER_POSITION = media::BnAudioFlingerService::TRANSACTION_getRenderPosition,
GET_INPUT_FRAMES_LOST = media::BnAudioFlingerService::TRANSACTION_getInputFramesLost,
@@ -574,6 +573,7 @@
SET_REQUESTED_LATENCY_MODE = media::BnAudioFlingerService::TRANSACTION_setRequestedLatencyMode,
GET_SUPPORTED_LATENCY_MODES = media::BnAudioFlingerService::TRANSACTION_getSupportedLatencyModes,
GET_SOUND_DOSE_INTERFACE = media::BnAudioFlingerService::TRANSACTION_getSoundDoseInterface,
+ INVALIDATE_TRACKS = media::BnAudioFlingerService::TRANSACTION_invalidateTracks,
};
protected:
@@ -653,7 +653,6 @@
Status openInput(const media::OpenInputRequest& request,
media::OpenInputResponse* _aidl_return) override;
Status closeInput(int32_t input) override;
- Status invalidateStream(media::audio::common::AudioStreamType stream) override;
Status setVoiceVolume(float volume) override;
Status getRenderPosition(int32_t output, media::RenderPosition* _aidl_return) override;
Status getInputFramesLost(int32_t ioHandle, int32_t* _aidl_return) override;
@@ -700,6 +699,7 @@
std::vector<media::LatencyMode>* _aidl_return) override;
Status getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* _aidl_return) override;
+ Status invalidateTracks(const std::vector<int32_t>& portIds) override;
private:
const sp<AudioFlingerServerAdapter::Delegate> mDelegate;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index cf7e135..d03bacb 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -194,7 +194,6 @@
BINDER_METHOD_ENTRY(restoreOutput) \
BINDER_METHOD_ENTRY(openInput) \
BINDER_METHOD_ENTRY(closeInput) \
-BINDER_METHOD_ENTRY(invalidateStream) \
BINDER_METHOD_ENTRY(setVoiceVolume) \
BINDER_METHOD_ENTRY(getRenderPosition) \
BINDER_METHOD_ENTRY(getInputFramesLost) \
@@ -3398,17 +3397,23 @@
closeInputFinish(thread);
}
-status_t AudioFlinger::invalidateStream(audio_stream_type_t stream)
-{
+status_t AudioFlinger::invalidateTracks(const std::vector<audio_port_handle_t> &portIds) {
Mutex::Autolock _l(mLock);
- ALOGV("invalidateStream() stream %d", stream);
+ ALOGV("%s", __func__);
+ std::set<audio_port_handle_t> portIdSet(portIds.begin(), portIds.end());
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
- thread->invalidateTracks(stream);
+ thread->invalidateTracks(portIdSet);
+ if (portIdSet.empty()) {
+ return NO_ERROR;
+ }
}
for (size_t i = 0; i < mMmapThreads.size(); i++) {
- mMmapThreads[i]->invalidateTracks(stream);
+ mMmapThreads[i]->invalidateTracks(portIdSet);
+ if (portIdSet.empty()) {
+ return NO_ERROR;
+ }
}
return NO_ERROR;
}
@@ -4607,7 +4612,6 @@
case TransactionCode::RESTORE_OUTPUT:
case TransactionCode::OPEN_INPUT:
case TransactionCode::CLOSE_INPUT:
- case TransactionCode::INVALIDATE_STREAM:
case TransactionCode::SET_VOICE_VOLUME:
case TransactionCode::MOVE_EFFECTS:
case TransactionCode::SET_EFFECT_SUSPENDED:
@@ -4622,6 +4626,7 @@
case TransactionCode::SET_DEVICE_CONNECTED_STATE:
case TransactionCode::SET_REQUESTED_LATENCY_MODE:
case TransactionCode::GET_SUPPORTED_LATENCY_MODES:
+ case TransactionCode::INVALIDATE_TRACKS:
ALOGW("%s: transaction %d received from PID %d",
__func__, code, IPCThreadState::self()->getCallingPid());
// return status only for non void methods
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 360ad36..7daa4c4 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -210,8 +210,6 @@
virtual status_t closeInput(audio_io_handle_t input);
- virtual status_t invalidateStream(audio_stream_type_t stream);
-
virtual status_t setVoiceVolume(float volume);
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
@@ -310,6 +308,8 @@
virtual status_t getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
sp<media::ISoundDose>* soundDose);
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+
status_t onTransactWrapper(TransactionCode code, const Parcel& data, uint32_t flags,
const std::function<status_t()>& delegate) override;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 3bdc786..0dd915a 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3571,6 +3571,28 @@
invalidateTracks_l(streamType);
}
+void AudioFlinger::PlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
+ Mutex::Autolock _l(mLock);
+ invalidateTracks_l(portIds);
+}
+
+bool AudioFlinger::PlaybackThread::invalidateTracks_l(std::set<audio_port_handle_t>& portIds) {
+ bool trackMatch = false;
+ const size_t size = mTracks.size();
+ for (size_t i = 0; i < size; i++) {
+ sp<Track> t = mTracks[i];
+ if (t->isExternalTrack() && portIds.find(t->portId()) != portIds.end()) {
+ t->invalidate();
+ portIds.erase(t->portId());
+ trackMatch = true;
+ }
+ if (portIds.empty()) {
+ break;
+ }
+ }
+ return trackMatch;
+}
+
// getTrackById_l must be called with holding thread lock
AudioFlinger::PlaybackThread::Track* AudioFlinger::PlaybackThread::getTrackById_l(
audio_port_handle_t trackPortId) {
@@ -7218,6 +7240,13 @@
}
}
+void AudioFlinger::OffloadThread::invalidateTracks(std::set<audio_port_handle_t>& portIds) {
+ Mutex::Autolock _l(mLock);
+ if (PlaybackThread::invalidateTracks_l(portIds)) {
+ mFlushPending = true;
+ }
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger,
@@ -10562,6 +10591,25 @@
}
}
+void AudioFlinger::MmapPlaybackThread::invalidateTracks(std::set<audio_port_handle_t>& portIds)
+{
+ Mutex::Autolock _l(mLock);
+ bool trackMatch = false;
+ for (const sp<MmapTrack> &track : mActiveTracks) {
+ if (portIds.find(track->portId()) != portIds.end()) {
+ track->invalidate();
+ trackMatch = true;
+ portIds.erase(track->portId());
+ }
+ if (portIds.empty()) {
+ break;
+ }
+ }
+ if (trackMatch) {
+ broadcast_l();
+ }
+}
+
void AudioFlinger::MmapPlaybackThread::processVolume_l()
{
float volume;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index f484192..01ea5d9 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1036,7 +1036,11 @@
// called with AudioFlinger lock held
bool invalidateTracks_l(audio_stream_type_t streamType);
+ bool invalidateTracks_l(std::set<audio_port_handle_t>& portIds);
virtual void invalidateTracks(audio_stream_type_t streamType);
+ // Invalidate tracks by a set of port ids. The port id will be removed from
+ // the given set if the corresponding track is found and invalidated.
+ virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds);
virtual size_t frameCount() const { return mNormalFrameCount; }
@@ -1655,6 +1659,7 @@
virtual bool waitingAsyncCallback();
virtual bool waitingAsyncCallback_l();
virtual void invalidateTracks(audio_stream_type_t streamType);
+ void invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
virtual bool keepWakeLock() const { return (mKeepWakeLock || (mDrainSequence & 1)); }
@@ -2151,6 +2156,7 @@
virtual audio_stream_type_t streamType() { return AUDIO_STREAM_DEFAULT; }
virtual void invalidateTracks(audio_stream_type_t streamType __unused) {}
+ virtual void invalidateTracks(std::set<audio_port_handle_t>& portIds __unused) {}
// Sets the UID records silence
virtual void setRecordSilenced(audio_port_handle_t portId __unused,
@@ -2230,6 +2236,7 @@
void setMasterMute_l(bool muted) { mMasterMute = muted; }
virtual void invalidateTracks(audio_stream_type_t streamType);
+ void invalidateTracks(std::set<audio_port_handle_t>& portIds) override;
virtual audio_stream_type_t streamType() { return mStreamType; }
virtual void checkSilentMode_l();
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 8e0315b..520bad2 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -492,9 +492,6 @@
virtual status_t setStreamVolume(audio_stream_type_t stream, float volume,
audio_io_handle_t output, int delayMs = 0) = 0;
- // invalidate a stream type, causing a reroute to an unspecified new output
- virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
-
// function enabling to send proprietary informations directly from audio policy manager to
// audio hardware interface.
virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs,
@@ -564,6 +561,8 @@
const TrackSecondaryOutputsMap& trackSecondaryOutputs) = 0;
virtual status_t setDeviceConnectedState(const struct audio_port_v7 *port, bool connected) = 0;
+
+ virtual status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) = 0;
};
// These are the signatures of createAudioPolicyManager/destroyAudioPolicyManager
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index c513098..52a000f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -442,6 +442,8 @@
bool isConfigurationMatched(const audio_config_base_t& config, audio_output_flags_t flags);
+ PortHandleVector getClientsForStream(audio_stream_type_t streamType) const;
+
const sp<IOProfile> mProfile; // I/O profile this output derives from
audio_io_handle_t mIoHandle; // output handle
uint32_t mLatency; //
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index c7296e9..a46186b 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -947,6 +947,17 @@
&& mFormat == config.format;
}
+PortHandleVector SwAudioOutputDescriptor::getClientsForStream(
+ audio_stream_type_t streamType) const {
+ PortHandleVector clientsForStream;
+ for (const auto& client : getClientIterable()) {
+ if (client->stream() == streamType) {
+ clientsForStream.push_back(client->portId());
+ }
+ }
+ return clientsForStream;
+}
+
void SwAudioOutputCollection::dump(String8 *dst) const
{
dst->appendFormat("\n Outputs (%zu):\n", size());
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index aad82fb..1d4eb1e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -820,7 +820,7 @@
if (isStateInCall(oldState)) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
// force reevaluating accessibility routing when call stops
- mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
+ invalidateStreams({AUDIO_STREAM_ACCESSIBILITY});
}
/**
@@ -903,7 +903,7 @@
if (isStateInCall(state)) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
// force reevaluating accessibility routing when call starts
- mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
+ invalidateStreams({AUDIO_STREAM_ACCESSIBILITY});
}
// Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
@@ -936,8 +936,7 @@
// force client reconnection to reevaluate flag AUDIO_FLAG_AUDIBILITY_ENFORCED
if (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM) {
- mpClientInterface->invalidateStream(AUDIO_STREAM_SYSTEM);
- mpClientInterface->invalidateStream(AUDIO_STREAM_ENFORCED_AUDIBLE);
+ invalidateStreams({AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE});
}
//FIXME: workaround for truncated touch sounds
@@ -2298,7 +2297,7 @@
// force reevaluating accessibility routing when ringtone or alarm starts
if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
- mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
+ invalidateStreams({AUDIO_STREAM_ACCESSIBILITY});
}
if (waitMs > muteWaitMs) {
@@ -5183,9 +5182,7 @@
// invalidate all tracks in this strategy to force re connection.
// Otherwise select new device on the output mix.
if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
- for (auto stream : mEngine->getStreamTypesForProductStrategy(ps)) {
- mpClientInterface->invalidateStream(stream);
- }
+ invalidateStreams(mEngine->getStreamTypesForProductStrategy(ps));
} else {
DeviceVector newDevices = getNewOutputDevices(outputDesc, false /*fromCache*/);
if (outputDesc->mUsePreferredMixerAttributes && outputDesc->devices() != newDevices) {
@@ -5753,9 +5750,7 @@
}
}
- for (audio_stream_type_t stream : streamsToInvalidate) {
- mpClientInterface->invalidateStream(stream);
- }
+ invalidateStreams(StreamTypeVector(streamsToInvalidate.begin(), streamsToInvalidate.end()));
}
@@ -6769,9 +6764,7 @@
}
// Move tracks associated to this stream (and linked) from previous output to new output
if (!invalidatedOutputs.empty()) {
- for (auto stream : mEngine->getStreamTypesForProductStrategy(psId)) {
- mpClientInterface->invalidateStream(stream);
- }
+ invalidateStreams(mEngine->getStreamTypesForProductStrategy(psId));
for (sp<SwAudioOutputDescriptor> desc : invalidatedOutputs) {
desc->setTracksInvalidatedStatusByStrategy(psId);
}
@@ -6789,7 +6782,7 @@
}
void AudioPolicyManager::checkSecondaryOutputs() {
- std::set<audio_stream_type_t> streamsToInvalidate;
+ PortHandleVector clientsToInvalidate;
TrackSecondaryOutputsMap trackSecondaryOutputs;
for (size_t i = 0; i < mOutputs.size(); i++) {
const sp<SwAudioOutputDescriptor>& outputDescriptor = mOutputs[i];
@@ -6807,8 +6800,11 @@
}
}
- if (status != OK) {
- streamsToInvalidate.insert(client->stream());
+ if (status != OK &&
+ (client->flags() & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == AUDIO_OUTPUT_FLAG_NONE) {
+ // When it failed to query secondary output, only invalidate the client that is not
+ // MMAP. The reason is that MMAP stream will not support secondary output.
+ clientsToInvalidate.push_back(client->portId());
} else if (!std::equal(
client->getSecondaryOutputs().begin(),
client->getSecondaryOutputs().end(),
@@ -6816,7 +6812,7 @@
if (!audio_is_linear_pcm(client->config().format)) {
// If the format is not PCM, the tracks should be invalidated to get correct
// behavior when the secondary output is changed.
- streamsToInvalidate.insert(client->stream());
+ clientsToInvalidate.push_back(client->portId());
} else {
std::vector<wp<SwAudioOutputDescriptor>> weakSecondaryDescs;
std::vector<audio_io_handle_t> secondaryOutputIds;
@@ -6833,9 +6829,9 @@
if (!trackSecondaryOutputs.empty()) {
mpClientInterface->updateSecondaryOutputs(trackSecondaryOutputs);
}
- for (audio_stream_type_t stream : streamsToInvalidate) {
- ALOGD("%s Invalidate stream %d due to fail getting output for attr", __func__, stream);
- mpClientInterface->invalidateStream(stream);
+ if (!clientsToInvalidate.empty()) {
+ ALOGD("%s Invalidate clients due to fail getting output for attr", __func__);
+ mpClientInterface->invalidateTracks(clientsToInvalidate);
}
}
@@ -8332,4 +8328,23 @@
}
}
+PortHandleVector AudioPolicyManager::getClientsForStream(
+ audio_stream_type_t streamType) const {
+ PortHandleVector clients;
+ for (size_t i = 0; i < mOutputs.size(); ++i) {
+ PortHandleVector clientsForStream = mOutputs.valueAt(i)->getClientsForStream(streamType);
+ clients.insert(clients.end(), clientsForStream.begin(), clientsForStream.end());
+ }
+ return clients;
+}
+
+void AudioPolicyManager::invalidateStreams(StreamTypeVector streams) const {
+ PortHandleVector clients;
+ for (auto stream : streams) {
+ PortHandleVector clientsForStream = getClientsForStream(stream);
+ clients.insert(clients.end(), clientsForStream.begin(), clientsForStream.end());
+ }
+ mpClientInterface->invalidateTracks(clients);
+}
+
} // namespace android
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 7476ec2..885f7c6 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -1305,6 +1305,7 @@
sp<PreferredMixerAttributesInfo> getPreferredMixerAttributesInfo(
audio_port_handle_t devicePortId, product_strategy_t strategy);
+
sp<SwAudioOutputDescriptor> reopenOutput(
sp<SwAudioOutputDescriptor> outputDesc,
const audio_config_t *config,
@@ -1313,6 +1314,9 @@
void reopenOutputsWithDevices(
const std::map<audio_io_handle_t, DeviceVector>& outputsToReopen);
+
+ PortHandleVector getClientsForStream(audio_stream_type_t streamType) const;
+ void invalidateStreams(StreamTypeVector streams) const;
};
};
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 5d420b5..1bb89df 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -174,16 +174,6 @@
delay_ms);
}
-status_t AudioPolicyService::AudioPolicyClient::invalidateStream(audio_stream_type_t stream)
-{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- return PERMISSION_DENIED;
- }
-
- return af->invalidateStream(stream);
-}
-
void AudioPolicyService::AudioPolicyClient::setParameters(audio_io_handle_t io_handle,
const String8& keyValuePairs,
int delay_ms)
@@ -328,5 +318,15 @@
return af->setDeviceConnectedState(port, connected);
}
+status_t AudioPolicyService::AudioPolicyClient::invalidateTracks(
+ const std::vector<audio_port_handle_t>& portIds) {
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ return PERMISSION_DENIED;
+ }
+
+ return af->invalidateTracks(portIds);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 7d022cb..50f2180 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -782,9 +782,6 @@
// for each output (destination device) it is attached to.
virtual status_t setStreamVolume(audio_stream_type_t stream, float volume, audio_io_handle_t output, int delayMs = 0);
- // invalidate a stream type, causing a reroute to an unspecified new output
- virtual status_t invalidateStream(audio_stream_type_t stream);
-
// function enabling to send proprietary informations directly from audio policy manager to audio hardware interface.
virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs = 0);
// function enabling to receive proprietary informations directly from audio hardware interface to audio policy manager.
@@ -844,6 +841,8 @@
status_t setDeviceConnectedState(
const struct audio_port_v7 *port, bool connected) override;
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& portIds) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index 8a85fee..0c04e35 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -54,7 +54,6 @@
float /*volume*/,
audio_io_handle_t /*output*/,
int /*delayMs*/) override { return NO_INIT; }
- status_t invalidateStream(audio_stream_type_t /*stream*/) override { return NO_INIT; }
void setParameters(audio_io_handle_t /*ioHandle*/,
const String8& /*keyValuePairs*/,
int /*delayMs*/) override { }
@@ -101,6 +100,9 @@
const struct audio_port_v7 *port __unused, bool connected __unused) override {
return NO_INIT;
}
+ status_t invalidateTracks(const std::vector<audio_port_handle_t>& /*portIds*/) override {
+ return NO_INIT;
+ }
};
} // namespace android