Invalidate tracks by a list of port id.
Adding an interface to just invalidate tracks with the given list of
port id. By invalidating the tracks via given port id, it can help
prevent mmap tracks from being invalidated when a mixer policy is
registered.
Bug: 139763500
Test: manually
Test: atest audiopolicy_tests
Test: audioflinger_fuzzer
Change-Id: Ifaadb981314088e3b2ac3223accece1576a2a575
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();