AudioFlinger: Add Track interfaces
Add new interfaces
IAfTrackBase
IAfTrack
IAfOutputTrack
IAfMmapTrack
IAfRecordTrack
Test: atest audiorecord_tests audiotrack_tests audiorouting_tests trackplayerbase_tests audiosystem_tests
Test: atest AudioTrackTest AudioRecordTest
Test: YouTube Camera
Bug: 288339104
Bug: 288468076
Merged-In: Iee8fd68fcd1c430da09b11d68a57fc62ba4c6f75
Change-Id: Iee8fd68fcd1c430da09b11d68a57fc62ba4c6f75
(cherry picked from commit d29af631bd879ee4e477da265288211339fa2ee8)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 90f984e..87bf81e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -435,7 +435,7 @@
for (; i < mPlaybackThreads.size(); ++i) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
Mutex::Autolock _tl(thread->mLock);
- sp<PlaybackThread::Track> track = thread->getTrackById_l(trackId);
+ sp<IAfTrack> track = thread->getTrackById_l(trackId);
if (track != nullptr) {
ALOGD("%s trackId: %u", __func__, trackId);
updateSecondaryOutputsForTrack_l(track.get(), thread, secondaryOutputs);
@@ -1107,7 +1107,7 @@
CreateTrackInput input = VALUE_OR_RETURN_STATUS(CreateTrackInput::fromAidl(_input));
CreateTrackOutput output;
- sp<PlaybackThread::Track> track;
+ sp<IAfTrack> track;
sp<Client> client;
status_t lStatus;
audio_stream_type_t streamType;
@@ -1297,7 +1297,7 @@
AudioSystem::moveEffectsToIo(effectIds, effectThreadId);
}
- output.audioTrack = PlaybackThread::Track::createIAudioTrackAdapter(track);
+ output.audioTrack = IAfTrack::createIAudioTrackAdapter(track);
_output = VALUE_OR_FATAL(output.toAidl());
Exit:
@@ -2549,7 +2549,7 @@
output.buffers = recordTrack->getBuffers();
output.portId = portId;
- output.audioRecord = RecordThread::RecordTrack::createIAudioRecordAdapter(recordTrack);
+ output.audioRecord = IAfRecordTrack::createIAudioRecordAdapter(recordTrack);
_output = VALUE_OR_FATAL(output.toAidl());
Exit:
@@ -3899,7 +3899,7 @@
}
void AudioFlinger::updateSecondaryOutputsForTrack_l(
- PlaybackThread::Track* track,
+ IAfTrack* track,
PlaybackThread* thread,
const std::vector<audio_io_handle_t> &secondaryOutputs) const {
TeePatches teePatches;
@@ -3989,14 +3989,14 @@
patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
}
- track->setTeePatchesToUpdate(std::move(teePatches));
+ track->setTeePatchesToUpdate(&teePatches); // TODO(b/288339104) void* to std::move()
}
sp<audioflinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
audio_session_t triggerSession,
audio_session_t listenerSession,
const audioflinger::SyncEventCallback& callBack,
- const wp<RefBase>& cookie)
+ const wp<IAfTrackBase>& cookie)
{
Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ba6200f..614b452 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -121,6 +121,7 @@
// include AudioFlinger component interfaces
#include "IAfEffect.h"
+#include "IAfTrack.h"
namespace android {
@@ -397,7 +398,7 @@
audio_session_t triggerSession,
audio_session_t listenerSession,
const audioflinger::SyncEventCallback& callBack,
- const wp<RefBase>& cookie);
+ const wp<IAfTrackBase>& cookie);
bool btNrecIsOff() const { return mBtNrecIsOff.load(); }
@@ -729,7 +730,7 @@
ThreadBase *hapticPlaybackThread_l() const;
void updateSecondaryOutputsForTrack_l(
- PlaybackThread::Track* track,
+ IAfTrack* track,
PlaybackThread* thread,
const std::vector<audio_io_handle_t>& secondaryOutputs) const;
diff --git a/services/audioflinger/IAfTrack.h b/services/audioflinger/IAfTrack.h
new file mode 100644
index 0000000..65d265a
--- /dev/null
+++ b/services/audioflinger/IAfTrack.h
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace android {
+
+// Common interface to all Playback and Record tracks.
+class IAfTrackBase : public virtual RefBase {
+public:
+ enum track_state : int32_t {
+ IDLE,
+ FLUSHED, // for PlaybackTracks only
+ STOPPED,
+ // next 2 states are currently used for fast tracks
+ // and offloaded tracks only
+ STOPPING_1, // waiting for first underrun
+ STOPPING_2, // waiting for presentation complete
+ RESUMING, // for PlaybackTracks only
+ ACTIVE,
+ PAUSING,
+ PAUSED,
+ STARTING_1, // for RecordTrack only
+ STARTING_2, // for RecordTrack only
+ };
+
+ // where to allocate the data buffer
+ enum alloc_type {
+ ALLOC_CBLK, // allocate immediately after control block
+ ALLOC_READONLY, // allocate from a separate read-only heap per thread
+ ALLOC_PIPE, // do not allocate; use the pipe buffer
+ ALLOC_LOCAL, // allocate a local buffer
+ ALLOC_NONE, // do not allocate:use the buffer passed to TrackBase constructor
+ };
+
+ enum track_type {
+ TYPE_DEFAULT,
+ TYPE_OUTPUT,
+ TYPE_PATCH,
+ };
+
+ virtual status_t initCheck() const = 0;
+ virtual status_t start(
+ AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) = 0;
+ virtual void stop() = 0;
+ virtual sp<IMemory> getCblk() const = 0;
+ virtual audio_track_cblk_t* cblk() const = 0;
+ virtual audio_session_t sessionId() const = 0;
+ virtual uid_t uid() const = 0;
+ virtual pid_t creatorPid() const = 0;
+ virtual uint32_t sampleRate() const = 0;
+ virtual size_t frameSize() const = 0;
+ virtual audio_port_handle_t portId() const = 0;
+ virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) = 0;
+ virtual track_state state() const = 0;
+ virtual void setState(track_state state) = 0;
+ virtual sp<IMemory> getBuffers() const = 0;
+ virtual void* buffer() const = 0;
+ virtual size_t bufferSize() const = 0;
+ virtual bool isFastTrack() const = 0;
+ virtual bool isDirect() const = 0;
+ virtual bool isOutputTrack() const = 0;
+ virtual bool isPatchTrack() const = 0;
+ virtual bool isExternalTrack() const = 0;
+
+ virtual void invalidate() = 0;
+ virtual bool isInvalid() const = 0;
+
+ virtual void terminate() = 0;
+ virtual bool isTerminated() const = 0;
+
+ virtual audio_attributes_t attributes() const = 0;
+ virtual bool isSpatialized() const = 0;
+ virtual bool isBitPerfect() const = 0;
+
+ // not currently implemented in TrackBase, but overridden.
+ virtual void destroy() {}; // MmapTrack doesn't implement.
+ virtual void appendDumpHeader(String8& result) const = 0;
+ virtual void appendDump(String8& result, bool active) const = 0;
+
+ // Dup with AudioBufferProvider interface
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+ virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+
+ // Added for RecordTrack and OutputTrack
+ // TODO(b/288339104) type
+ virtual wp<Thread> thread() const = 0;
+ virtual const sp<ServerProxy>& serverProxy() const = 0;
+
+ // TEE_SINK
+ virtual void dumpTee(int fd __unused, const std::string& reason __unused) const {};
+
+ /** returns the buffer contents size converted to time in milliseconds
+ * for PCM Playback or Record streaming tracks. The return value is zero for
+ * PCM static tracks and not defined for non-PCM tracks.
+ *
+ * This may be called without the thread lock.
+ */
+ virtual double bufferLatencyMs() const = 0;
+
+ /** returns whether the track supports server latency computation.
+ * This is set in the constructor and constant throughout the track lifetime.
+ */
+ virtual bool isServerLatencySupported() const = 0;
+
+ /** computes the server latency for PCM Playback or Record track
+ * to the device sink/source. This is the time for the next frame in the track buffer
+ * written or read from the server thread to the device source or sink.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the server thread to/from the track buffer
+ * from the device source/sink.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ virtual status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const = 0;
+
+ /** computes the total client latency for PCM Playback or Record tracks
+ * for the next client app access to the device sink/source; i.e. the
+ * server latency plus the buffer latency.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the client app to/from the track buffer
+ * from the device sink/source.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ virtual status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const = 0;
+
+ // TODO: Consider making this external.
+ struct FrameTime {
+ int64_t frames;
+ int64_t timeNs;
+ };
+
+ // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
+ virtual void getKernelFrameTime(FrameTime* ft) const = 0;
+
+ virtual audio_format_t format() const = 0;
+ virtual int id() const = 0;
+
+ virtual const char* getTrackStateAsString() const = 0;
+
+ // Called by the PlaybackThread to indicate that the track is becoming active
+ // and a new interval should start with a given device list.
+ virtual void logBeginInterval(const std::string& devices) = 0;
+
+ // Called by the PlaybackThread to indicate the track is no longer active.
+ virtual void logEndInterval() = 0;
+
+ // Called to tally underrun frames in playback.
+ virtual void tallyUnderrunFrames(size_t frames) = 0;
+
+ virtual audio_channel_mask_t channelMask() const = 0;
+
+ /** @return true if the track has changed (metadata or volume) since
+ * the last time this function was called,
+ * true if this function was never called since the track creation,
+ * false otherwise.
+ * Thread safe.
+ */
+ virtual bool readAndClearHasChanged() = 0;
+
+ /** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
+ virtual void setMetadataHasChanged() = 0;
+
+ /**
+ * For RecordTrack
+ * TODO(b/288339104) either use this or add asRecordTrack or asTrack etc.
+ */
+ virtual void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event __unused){};
+
+ // For Thread use, fast tracks and offloaded tracks only
+ // TODO(b/288339104) rearrange to IAfTrack.
+ virtual bool isStopped() const = 0;
+ virtual bool isStopping() const = 0;
+ virtual bool isStopping_1() const = 0;
+ virtual bool isStopping_2() const = 0;
+};
+
+// Common interface for Playback tracks.
+class IAfTrack : public virtual IAfTrackBase {
+public:
+ // createIAudioTrackAdapter() is a static constructor which creates an
+ // IAudioTrack AIDL interface adapter from the Track object that
+ // may be passed back to the client (if needed).
+ //
+ // Only one AIDL IAudioTrack interface adapter should be created per Track.
+ static sp<media::IAudioTrack> createIAudioTrackAdapter(const sp<IAfTrack>& track);
+
+ virtual void pause() = 0;
+ virtual void flush() = 0;
+ virtual audio_stream_type_t streamType() const = 0;
+ virtual bool isOffloaded() const = 0;
+ virtual bool isOffloadedOrDirect() const = 0;
+ virtual bool isStatic() const = 0;
+ virtual status_t setParameters(const String8& keyValuePairs) = 0;
+ virtual status_t selectPresentation(int presentationId, int programId) = 0;
+ virtual status_t attachAuxEffect(int EffectId) = 0;
+ virtual void setAuxBuffer(int EffectId, int32_t* buffer) = 0;
+ virtual int32_t* auxBuffer() const = 0;
+ virtual void setMainBuffer(float* buffer) = 0;
+ virtual float* mainBuffer() const = 0;
+ virtual int auxEffectId() const = 0;
+ virtual status_t getTimestamp(AudioTimestamp& timestamp) = 0;
+ virtual void signal() = 0;
+ virtual status_t getDualMonoMode(audio_dual_mono_mode_t* mode) const = 0;
+ virtual status_t setDualMonoMode(audio_dual_mono_mode_t mode) = 0;
+ virtual status_t getAudioDescriptionMixLevel(float* leveldB) const = 0;
+ virtual status_t setAudioDescriptionMixLevel(float leveldB) = 0;
+ virtual status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) const = 0;
+ virtual status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) = 0;
+
+ // implement FastMixerState::VolumeProvider interface
+ virtual gain_minifloat_packed_t getVolumeLR() const = 0;
+
+ // implement volume handling.
+ virtual media::VolumeShaper::Status applyVolumeShaper(
+ const sp<media::VolumeShaper::Configuration>& configuration,
+ const sp<media::VolumeShaper::Operation>& operation) = 0;
+ virtual sp<media::VolumeShaper::State> getVolumeShaperState(int id) const = 0;
+ virtual sp<media::VolumeHandler> getVolumeHandler() const = 0;
+ /** Set the computed normalized final volume of the track.
+ * !masterMute * masterVolume * streamVolume * averageLRVolume */
+ virtual void setFinalVolume(float volumeLeft, float volumeRight) = 0;
+ virtual float getFinalVolume() const = 0;
+ virtual void getFinalVolume(float* left, float* right) const = 0;
+
+ using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
+ /** Copy the track metadata in the provided iterator. Thread safe. */
+ virtual void copyMetadataTo(MetadataInserter& backInserter) const = 0;
+
+ /** Return haptic playback of the track is enabled or not, used in mixer. */
+ virtual bool getHapticPlaybackEnabled() const = 0;
+ /** Set haptic playback of the track is enabled or not, should be
+ * set after query or get callback from vibrator service */
+ virtual void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) = 0;
+ /** Return at what intensity to play haptics, used in mixer. */
+ virtual os::HapticScale getHapticIntensity() const = 0;
+ /** Return the maximum amplitude allowed for haptics data, used in mixer. */
+ virtual float getHapticMaxAmplitude() const = 0;
+ /** Set intensity of haptic playback, should be set after querying vibrator service. */
+ virtual void setHapticIntensity(os::HapticScale hapticIntensity) = 0;
+ /** Set maximum amplitude allowed for haptic data, should be set after querying
+ * vibrator service.
+ */
+ virtual void setHapticMaxAmplitude(float maxAmplitude) = 0;
+ virtual sp<os::ExternalVibration> getExternalVibration() const = 0;
+
+ // This function should be called with holding thread lock.
+ virtual void updateTeePatches() = 0;
+
+ // TODO(b/288339104) type
+ virtual void setTeePatchesToUpdate(
+ const void* teePatchesToUpdate /* TeePatches& teePatchesToUpdate */) = 0;
+
+ static bool checkServerLatencySupported(audio_format_t format, audio_output_flags_t flags) {
+ return audio_is_linear_pcm(format) && (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == 0;
+ }
+
+ virtual audio_output_flags_t getOutputFlags() const = 0;
+ virtual float getSpeed() const = 0;
+
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ virtual void processMuteEvent_l(
+ const sp<IAudioManager>& audioManager, mute_state_t muteState) = 0;
+
+ virtual void triggerEvents(AudioSystem::sync_event_t type) = 0;
+
+ virtual void disable() = 0;
+ virtual int& fastIndex() = 0;
+ virtual bool isPlaybackRestricted() const = 0;
+};
+
+// playback track, used by DuplicatingThread
+class IAfOutputTrack : public virtual IAfTrack {
+public:
+ virtual ssize_t write(void* data, uint32_t frames) = 0;
+ virtual bool bufferQueueEmpty() const = 0;
+ virtual bool isActive() const = 0;
+
+ /** Set the metadatas of the upstream tracks. Thread safe. */
+ virtual void setMetadatas(const SourceMetadatas& metadatas) = 0;
+ /** returns client timestamp to the upstream duplicating thread. */
+ virtual ExtendedTimestamp getClientProxyTimestamp() const = 0;
+};
+
+class IAfMmapTrack : public virtual IAfTrackBase {
+public:
+ // protected by MMapThread::mLock
+ virtual void setSilenced_l(bool silenced) = 0;
+ // protected by MMapThread::mLock
+ virtual bool isSilenced_l() const = 0;
+ // protected by MMapThread::mLock
+ virtual bool getAndSetSilencedNotified_l() = 0;
+
+ /**
+ * Updates the mute state and notifies the audio service. Call this only when holding player
+ * thread lock.
+ */
+ virtual void processMuteEvent_l( // see IAfTrack
+ const sp<IAudioManager>& audioManager, mute_state_t muteState) = 0;
+};
+
+class IAfRecordTrack : public virtual IAfTrackBase {
+public:
+ // createIAudioRecordAdapter() is a static constructor which creates an
+ // IAudioRecord AIDL interface adapter from the RecordTrack object that
+ // may be passed back to the client (if needed).
+ //
+ // Only one AIDL IAudioRecord interface adapter should be created per RecordTrack.
+ static sp<media::IAudioRecord> createIAudioRecordAdapter(const sp<IAfRecordTrack>& recordTrack);
+
+ // clear the buffer overflow flag
+ virtual void clearOverflow() = 0;
+ // set the buffer overflow flag and return previous value
+ virtual bool setOverflow() = 0;
+
+ // TODO(b/288339104) handleSyncStartEvent in IAfTrackBase should move here.
+ virtual void clearSyncStartEvent() = 0;
+ virtual void updateTrackFrameInfo(
+ int64_t trackFramesReleased, int64_t sourceFramesRead, uint32_t halSampleRate,
+ const ExtendedTimestamp& timestamp) = 0;
+
+ virtual void setSilenced(bool silenced) = 0;
+ virtual bool isSilenced() const = 0;
+ virtual status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const = 0;
+
+ virtual status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) = 0;
+ virtual status_t setPreferredMicrophoneFieldDimension(float zoom) = 0;
+ virtual status_t shareAudioHistory(
+ const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) = 0;
+ virtual int32_t startFrames() const = 0;
+
+ static bool checkServerLatencySupported(audio_format_t format, audio_input_flags_t flags) {
+ return audio_is_linear_pcm(format) && (flags & AUDIO_INPUT_FLAG_HW_AV_SYNC) == 0;
+ }
+
+ using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
+ virtual void copyMetadataTo(MetadataInserter& backInserter) const = 0; // see IAfTrack
+};
+
+} // namespace android
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index cb46c52..0ab1adb 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -20,7 +20,7 @@
#endif
// playback track
-class MmapTrack : public TrackBase {
+class MmapTrack : public TrackBase, public IAfMmapTrack {
public:
MmapTrack(ThreadBase *thread,
const audio_attributes_t& attr,
@@ -32,26 +32,25 @@
const android::content::AttributionSourceState& attributionSource,
pid_t creatorPid,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
- virtual ~MmapTrack();
+ ~MmapTrack() override;
- // TrackBase virtual
- virtual status_t initCheck() const;
- virtual status_t start(AudioSystem::sync_event_t event,
- audio_session_t triggerSession);
- virtual void stop();
- virtual bool isFastTrack() const { return false; }
- bool isDirect() const override { return true; }
+ status_t initCheck() const final;
+ status_t start(
+ AudioSystem::sync_event_t event, audio_session_t triggerSession) final;
+ void stop() final;
+ bool isFastTrack() const final { return false; }
+ bool isDirect() const final { return true; }
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
// protected by MMapThread::mLock
- void setSilenced_l(bool silenced) { mSilenced = silenced;
+ void setSilenced_l(bool silenced) final { mSilenced = silenced;
mSilencedNotified = false;}
// protected by MMapThread::mLock
- bool isSilenced_l() const { return mSilenced; }
+ bool isSilenced_l() const final { return mSilenced; }
// protected by MMapThread::mLock
- bool getAndSetSilencedNotified_l() { bool silencedNotified = mSilencedNotified;
+ bool getAndSetSilencedNotified_l() final { bool silencedNotified = mSilencedNotified;
mSilencedNotified = true;
return silencedNotified; }
@@ -61,7 +60,7 @@
*/
void processMuteEvent_l(const sp<IAudioManager>& audioManager,
mute_state_t muteState)
- REQUIRES(AudioFlinger::MmapPlaybackThread::mLock);
+ REQUIRES(AudioFlinger::MmapPlaybackThread::mLock) final;
private:
friend class MmapThread;
@@ -72,11 +71,11 @@
// releaseBuffer() not overridden
// ExtendedAudioBufferProvider interface
- virtual size_t framesReady() const;
- virtual int64_t framesReleased() const;
- virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+ size_t framesReady() const final;
+ int64_t framesReleased() const final;
+ void onTimestamp(const ExtendedTimestamp ×tamp) final;
- pid_t mPid;
+ const pid_t mPid;
bool mSilenced; // protected by MMapThread::mLock
bool mSilencedNotified; // protected by MMapThread::mLock
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 837d045..e323cdd 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -679,7 +679,7 @@
// If so, do a frame diff and time difference computation to estimate
// the total patch latency. This requires that frame counts are reported by the
// HAL are matched properly in the case of record overruns and playback underruns.
- ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
+ IAfTrack::FrameTime recordFT{}, playFT{};
recordTrack->getKernelFrameTime(&recordFT);
playbackTrack->getKernelFrameTime(&playFT);
if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 7ff2394..ee2dd9b 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -67,15 +67,8 @@
};
// playback track
-class Track : public TrackBase, public VolumeProvider {
+class Track : public TrackBase, public virtual IAfTrack, public VolumeProvider {
public:
- // createIAudioTrackAdapter() is a static constructor which creates an
- // IAudioTrack AIDL interface adapter from the Track object that
- // may be passed back to the client (if needed).
- //
- // Only one AIDL IAudioTrack interface wrapper should be created per Track.
- static sp<media::IAudioTrack> createIAudioTrackAdapter(const sp<Track>& track);
-
Track( PlaybackThread *thread,
const sp<Client>& client,
audio_stream_type_t streamType,
@@ -99,72 +92,66 @@
float speed = 1.0f,
bool isSpatialized = false,
bool isBitPerfect = false);
- virtual ~Track();
- virtual status_t initCheck() const;
-
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
- virtual status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
- virtual void stop();
- void pause();
-
- void flush();
- void destroy();
-
- virtual uint32_t sampleRate() const;
-
- audio_stream_type_t streamType() const {
+ ~Track() override;
+ status_t initCheck() const final;
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
+ status_t start(AudioSystem::sync_event_t event = AudioSystem::SYNC_EVENT_NONE,
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) override;
+ void stop() override;
+ void pause() final;
+ void flush() final;
+ void destroy() final;
+ uint32_t sampleRate() const final;
+ audio_stream_type_t streamType() const final {
return mStreamType;
}
- bool isOffloaded() const
+ bool isOffloaded() const final
{ return (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0; }
- bool isDirect() const override
+ bool isDirect() const final
{ return (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0; }
- bool isOffloadedOrDirect() const { return (mFlags
+ bool isOffloadedOrDirect() const final { return (mFlags
& (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
| AUDIO_OUTPUT_FLAG_DIRECT)) != 0; }
- bool isStatic() const { return mSharedBuffer.get() != nullptr; }
+ bool isStatic() const final { return mSharedBuffer.get() != nullptr; }
- status_t setParameters(const String8& keyValuePairs);
- status_t selectPresentation(int presentationId, int programId);
- status_t attachAuxEffect(int EffectId);
- void setAuxBuffer(int EffectId, int32_t *buffer);
- int32_t *auxBuffer() const { return mAuxBuffer; }
- void setMainBuffer(float *buffer) { mMainBuffer = buffer; }
- float *mainBuffer() const { return mMainBuffer; }
- int auxEffectId() const { return mAuxEffectId; }
- virtual status_t getTimestamp(AudioTimestamp& timestamp);
- void signal();
- status_t getDualMonoMode(audio_dual_mono_mode_t* mode);
- status_t setDualMonoMode(audio_dual_mono_mode_t mode);
- status_t getAudioDescriptionMixLevel(float* leveldB);
- status_t setAudioDescriptionMixLevel(float leveldB);
- status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate);
- status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate);
+ status_t setParameters(const String8& keyValuePairs) final;
+ status_t selectPresentation(int presentationId, int programId) final;
+ status_t attachAuxEffect(int EffectId) final;
+ void setAuxBuffer(int EffectId, int32_t* buffer) final;
+ int32_t* auxBuffer() const final { return mAuxBuffer; }
+ void setMainBuffer(float* buffer) final { mMainBuffer = buffer; }
+ float* mainBuffer() const final { return mMainBuffer; }
+ int auxEffectId() const final { return mAuxEffectId; }
+ status_t getTimestamp(AudioTimestamp& timestamp) final;
+ void signal() final;
+ status_t getDualMonoMode(audio_dual_mono_mode_t* mode) const final;
+ status_t setDualMonoMode(audio_dual_mono_mode_t mode) final;
+ status_t getAudioDescriptionMixLevel(float* leveldB) const final;
+ status_t setAudioDescriptionMixLevel(float leveldB) final;
+ status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) const final;
+ status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) final;
-// implement FastMixerState::VolumeProvider interface
- virtual gain_minifloat_packed_t getVolumeLR();
+ // implement FastMixerState::VolumeProvider interface
+ gain_minifloat_packed_t getVolumeLR() const final;
- status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
-
- virtual bool isFastTrack() const { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
-
- double bufferLatencyMs() const override {
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) final;
+ bool isFastTrack() const final { return (mFlags & AUDIO_OUTPUT_FLAG_FAST) != 0; }
+ double bufferLatencyMs() const final {
return isStatic() ? 0. : TrackBase::bufferLatencyMs();
}
-// implement volume handling.
+ // implement volume handling.
media::VolumeShaper::Status applyVolumeShaper(
const sp<media::VolumeShaper::Configuration>& configuration,
const sp<media::VolumeShaper::Operation>& operation);
- sp<media::VolumeShaper::State> getVolumeShaperState(int id);
- sp<media::VolumeHandler> getVolumeHandler() { return mVolumeHandler; }
+ sp<media::VolumeShaper::State> getVolumeShaperState(int id) const final;
+ sp<media::VolumeHandler> getVolumeHandler() const final{ return mVolumeHandler; }
/** Set the computed normalized final volume of the track.
* !masterMute * masterVolume * streamVolume * averageLRVolume */
- void setFinalVolume(float volumeLeft, float volumeRight);
- float getFinalVolume() const { return mFinalVolume; }
- void getFinalVolume(float* left, float* right) const {
+ void setFinalVolume(float volumeLeft, float volumeRight) final;
+ float getFinalVolume() const final { return mFinalVolume; }
+ void getFinalVolume(float* left, float* right) const final {
*left = mFinalVolumeLeft;
*right = mFinalVolumeRight;
}
@@ -172,21 +159,22 @@
using SourceMetadatas = std::vector<playback_track_metadata_v7_t>;
using MetadataInserter = std::back_insert_iterator<SourceMetadatas>;
/** Copy the track metadata in the provided iterator. Thread safe. */
- virtual void copyMetadataTo(MetadataInserter& backInserter) const;
+ void copyMetadataTo(MetadataInserter& backInserter) const override;
+
/** Return haptic playback of the track is enabled or not, used in mixer. */
- bool getHapticPlaybackEnabled() const { return mHapticPlaybackEnabled; }
+ bool getHapticPlaybackEnabled() const final { return mHapticPlaybackEnabled; }
/** Set haptic playback of the track is enabled or not, should be
* set after query or get callback from vibrator service */
- void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) {
+ void setHapticPlaybackEnabled(bool hapticPlaybackEnabled) final {
mHapticPlaybackEnabled = hapticPlaybackEnabled;
}
/** Return at what intensity to play haptics, used in mixer. */
- os::HapticScale getHapticIntensity() const { return mHapticIntensity; }
+ os::HapticScale getHapticIntensity() const final { return mHapticIntensity; }
/** Return the maximum amplitude allowed for haptics data, used in mixer. */
- float getHapticMaxAmplitude() const { return mHapticMaxAmplitude; }
+ float getHapticMaxAmplitude() const final { return mHapticMaxAmplitude; }
/** Set intensity of haptic playback, should be set after querying vibrator service. */
- void setHapticIntensity(os::HapticScale hapticIntensity) {
+ void setHapticIntensity(os::HapticScale hapticIntensity) final {
if (os::isValidHapticScale(hapticIntensity)) {
mHapticIntensity = hapticIntensity;
setHapticPlaybackEnabled(mHapticIntensity != os::HapticScale::MUTE);
@@ -195,16 +183,19 @@
/** Set maximum amplitude allowed for haptic data, should be set after querying
* vibrator service.
*/
- void setHapticMaxAmplitude(float maxAmplitude) {
+ void setHapticMaxAmplitude(float maxAmplitude) final {
mHapticMaxAmplitude = maxAmplitude;
}
- sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }
+ sp<os::ExternalVibration> getExternalVibration() const final { return mExternalVibration; }
// This function should be called with holding thread lock.
- void updateTeePatches();
- void setTeePatchesToUpdate(TeePatches teePatchesToUpdate);
+ void updateTeePatches() final;
+ void setTeePatchesToUpdate(const void* teePatchesToUpdate) final {
+ setTeePatchesToUpdate(*reinterpret_cast<const TeePatches*>(teePatchesToUpdate));
+ }
+ void setTeePatchesToUpdate(TeePatches teePatchesToUpdate);
- void tallyUnderrunFrames(size_t frames) override {
+ void tallyUnderrunFrames(size_t frames) final {
if (isOut()) { // we expect this from output tracks only
mAudioTrackServerProxy->tallyUnderrunFrames(frames);
// Fetch absolute numbers from AudioTrackShared as it counts
@@ -215,22 +206,16 @@
}
}
- static bool checkServerLatencySupported(
- audio_format_t format, audio_output_flags_t flags) {
- return audio_is_linear_pcm(format)
- && (flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) == 0;
- }
-
- audio_output_flags_t getOutputFlags() const { return mFlags; }
- float getSpeed() const { return mSpeed; }
- bool isSpatialized() const override { return mIsSpatialized; }
- bool isBitPerfect() const override { return mIsBitPerfect; }
+ audio_output_flags_t getOutputFlags() const final { return mFlags; }
+ float getSpeed() const final { return mSpeed; }
+ bool isSpatialized() const final { return mIsSpatialized; }
+ bool isBitPerfect() const final { return mIsBitPerfect; }
/**
* Updates the mute state and notifies the audio service. Call this only when holding player
* thread lock.
*/
- void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState);
+ void processMuteEvent_l(const sp<IAudioManager>& audioManager, mute_state_t muteState) final;
protected:
// for numerous
@@ -246,9 +231,9 @@
void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
// ExtendedAudioBufferProvider interface
- virtual size_t framesReady() const;
- virtual int64_t framesReleased() const;
- virtual void onTimestamp(const ExtendedTimestamp ×tamp);
+ size_t framesReady() const override;
+ int64_t framesReleased() const override;
+ void onTimestamp(const ExtendedTimestamp ×tamp) override;
bool isPausing() const { return mState == PAUSING; }
bool isPaused() const { return mState == PAUSED; }
@@ -289,13 +274,11 @@
void signalClientFlag(int32_t flag);
public:
- void triggerEvents(AudioSystem::sync_event_t type);
- virtual void invalidate();
- void disable();
-
- int fastIndex() const { return mFastIndex; }
-
- bool isPlaybackRestricted() const {
+ void triggerEvents(AudioSystem::sync_event_t type) final;
+ void invalidate() final;
+ void disable() final;
+ int& fastIndex() final { return mFastIndex; }
+ bool isPlaybackRestricted() const final {
// The monitor is only created for tracks that can be silenced.
return mOpPlayAudioMonitor ? !mOpPlayAudioMonitor->hasOpPlayAudio() : false; }
@@ -398,7 +381,7 @@
// playback track, used by DuplicatingThread
-class OutputTrack : public Track {
+class OutputTrack : public Track, public IAfOutputTrack {
public:
class Buffer : public AudioBufferProvider::Buffer {
@@ -413,22 +396,21 @@
audio_channel_mask_t channelMask,
size_t frameCount,
const AttributionSourceState& attributionSource);
- virtual ~OutputTrack();
+ ~OutputTrack() override;
- virtual status_t start(AudioSystem::sync_event_t event =
+ status_t start(AudioSystem::sync_event_t event =
AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
- virtual void stop();
- ssize_t write(void* data, uint32_t frames);
- bool bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
- bool isActive() const { return mActive; }
- const wp<ThreadBase>& thread() const { return mThread; }
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) final;
+ void stop() final;
+ ssize_t write(void* data, uint32_t frames) final;
+ bool bufferQueueEmpty() const final { return mBufferQueue.size() == 0; }
+ bool isActive() const final { return mActive; }
- void copyMetadataTo(MetadataInserter& backInserter) const override;
+ void copyMetadataTo(MetadataInserter& backInserter) const final;
/** Set the metadatas of the upstream tracks. Thread safe. */
- void setMetadatas(const SourceMetadatas& metadatas);
+ void setMetadatas(const SourceMetadatas& metadatas) final;
/** returns client timestamp to the upstream duplicating thread. */
- ExtendedTimestamp getClientProxyTimestamp() const {
+ ExtendedTimestamp getClientProxyTimestamp() const final {
// server - kernel difference is not true latency when drained
// i.e. mServerProxy->isDrained().
ExtendedTimestamp timestamp;
@@ -439,7 +421,6 @@
// (with mTimeNs[] filled with -1's) is returned.
return timestamp;
}
-
private:
status_t obtainBuffer(AudioBufferProvider::Buffer* buffer,
uint32_t waitTimeMs);
@@ -491,22 +472,21 @@
* as soon as possible to have
* the lowest possible latency
* even if it might glitch. */);
- virtual ~PatchTrack();
+ ~PatchTrack() override;
- size_t framesReady() const override;
+ size_t framesReady() const final;
- virtual status_t start(AudioSystem::sync_event_t event =
+ status_t start(AudioSystem::sync_event_t event =
AudioSystem::SYNC_EVENT_NONE,
- audio_session_t triggerSession = AUDIO_SESSION_NONE);
+ audio_session_t triggerSession = AUDIO_SESSION_NONE) final;
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) final;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) final;
// PatchProxyBufferProvider interface
- virtual status_t obtainBuffer(Proxy::Buffer* buffer,
- const struct timespec *timeOut = NULL);
- virtual void releaseBuffer(Proxy::Buffer* buffer);
+ status_t obtainBuffer(Proxy::Buffer* buffer, const struct timespec* timeOut = nullptr) final;
+ void releaseBuffer(Proxy::Buffer* buffer) final;
private:
void restartIfDisabled();
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 61f36a1..d98b214 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -22,15 +22,8 @@
#endif
// record track
-class RecordTrack : public TrackBase {
+class RecordTrack : public TrackBase, public IAfRecordTrack {
public:
- // createIAudioRecordAdapter() is a static constructor which creates an
- // IAudioRecord AIDL interface wrapper from the RecordTrack object that
- // may be passed back to the client (if needed).
- //
- // Only one AIDL IAudioRecord interface wrapper should be created per RecordTrack.
- static sp<media::IAudioRecord> createIAudioRecordAdapter(const sp<RecordTrack>& recordTrack);
-
RecordTrack(RecordThread *thread,
const sp<Client>& client,
const audio_attributes_t& attr,
@@ -47,57 +40,50 @@
track_type type,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
int32_t startFrames = -1);
- virtual ~RecordTrack();
- virtual status_t initCheck() const;
+ ~RecordTrack() override;
+ status_t initCheck() const final;
- virtual status_t start(AudioSystem::sync_event_t event, audio_session_t triggerSession);
- virtual void stop();
+ status_t start(AudioSystem::sync_event_t event, audio_session_t triggerSession) final;
+ void stop() final;
+ void destroy() final;
+ void invalidate() final;
- void destroy();
-
- virtual void invalidate();
// clear the buffer overflow flag
- void clearOverflow() { mOverflow = false; }
+ void clearOverflow() final { mOverflow = false; }
// set the buffer overflow flag and return previous value
- bool setOverflow() { bool tmp = mOverflow; mOverflow = true;
+ bool setOverflow() final { bool tmp = mOverflow; mOverflow = true;
return tmp; }
- void appendDumpHeader(String8& result);
- void appendDump(String8& result, bool active);
+ void appendDumpHeader(String8& result) const final;
+ void appendDump(String8& result, bool active) const final;
- void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event);
- void clearSyncStartEvent();
+ void handleSyncStartEvent(const sp<audioflinger::SyncEvent>& event) final;
+ void clearSyncStartEvent() final;
- void updateTrackFrameInfo(int64_t trackFramesReleased,
+ void updateTrackFrameInfo(int64_t trackFramesReleased,
int64_t sourceFramesRead,
uint32_t halSampleRate,
- const ExtendedTimestamp ×tamp);
+ const ExtendedTimestamp ×tamp) final;
- virtual bool isFastTrack() const { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
- bool isDirect() const override
+ bool isFastTrack() const final { return (mFlags & AUDIO_INPUT_FLAG_FAST) != 0; }
+ bool isDirect() const final
{ return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }
- void setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
- bool isSilenced() const { return mSilenced; }
+ void setSilenced(bool silenced) final { if (!isPatchTrack()) mSilenced = silenced; }
+ bool isSilenced() const final { return mSilenced; }
- status_t getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones);
+ status_t getActiveMicrophones(
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const final;
- status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction);
- status_t setPreferredMicrophoneFieldDimension(float zoom);
- status_t shareAudioHistory(const std::string& sharedAudioPackageName,
- int64_t sharedAudioStartMs);
- int32_t startFrames() { return mStartFrames; }
+ status_t setPreferredMicrophoneDirection(audio_microphone_direction_t direction) final;
+ status_t setPreferredMicrophoneFieldDimension(float zoom) final;
+ status_t shareAudioHistory(const std::string& sharedAudioPackageName,
+ int64_t sharedAudioStartMs) final;
+ int32_t startFrames() const final { return mStartFrames; }
- static bool checkServerLatencySupported(
- audio_format_t format, audio_input_flags_t flags) {
- return audio_is_linear_pcm(format)
- && (flags & AUDIO_INPUT_FLAG_HW_AV_SYNC) == 0;
- }
-
- using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
- using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
- virtual void copyMetadataTo(MetadataInserter& backInserter) const;
+ using SinkMetadatas = std::vector<record_track_metadata_v7_t>;
+ using MetadataInserter = std::back_insert_iterator<SinkMetadatas>;
+ void copyMetadataTo(MetadataInserter& backInserter) const final;
private:
friend class AudioFlinger; // for mState
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 16f5a98..fc09927 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7502,7 +7502,8 @@
if (numTracks > 0) {
ss << ":";
for (const auto &track : mOutputTracks) {
- const sp<ThreadBase> thread = track->thread().promote();
+ // TODO(b/288339104) type
+ const auto thread = sp<ThreadBase>::cast(track->thread().promote());
ss << " (" << track->id() << " : ";
if (thread.get() != nullptr) {
ss << thread.get() << ", " << thread->id();
@@ -7586,7 +7587,8 @@
{
mWaitTimeMs = UINT_MAX;
for (size_t i = 0; i < mOutputTracks.size(); i++) {
- sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
+ // TODO(b/288339104) type
+ const auto strong = sp<ThreadBase>::cast(mOutputTracks[i]->thread().promote());
if (strong != 0) {
uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
if (waitTimeMs < mWaitTimeMs) {
@@ -7599,7 +7601,8 @@
bool AudioFlinger::DuplicatingThread::outputsReady()
{
for (size_t i = 0; i < outputTracks.size(); i++) {
- sp<ThreadBase> thread = outputTracks[i]->thread().promote();
+ // TODO(b/288339104) type
+ const auto thread = sp<ThreadBase>::cast(outputTracks[i]->thread().promote());
if (thread == 0) {
ALOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p",
outputTracks[i].get());
@@ -8877,10 +8880,11 @@
sp<audioflinger::SyncEvent> strongEvent = event.promote();
if (strongEvent != 0) {
- sp<RefBase> ptr = std::any_cast<const wp<RefBase>>(strongEvent->cookie()).promote();
- if (ptr != 0) {
- RecordTrack *recordTrack = (RecordTrack *)ptr.get();
- recordTrack->handleSyncStartEvent(strongEvent);
+ sp<IAfTrackBase> ptr =
+ std::any_cast<const wp<IAfTrackBase>>(strongEvent->cookie()).promote();
+ if (ptr != nullptr) {
+ // TODO(b/288339104) handleSyncStartEvent is in IAfTrackBase not IAfRecordTrack.
+ ptr->handleSyncStartEvent(strongEvent);
}
}
}
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index d5b6a98..4e62b57 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -20,40 +20,8 @@
#endif
// base for record and playback
-class TrackBase : public ExtendedAudioBufferProvider, public RefBase {
-
+class TrackBase : public ExtendedAudioBufferProvider, public virtual IAfTrackBase {
public:
- enum track_state : int32_t {
- IDLE,
- FLUSHED, // for PlaybackTracks only
- STOPPED,
- // next 2 states are currently used for fast tracks
- // and offloaded tracks only
- STOPPING_1, // waiting for first underrun
- STOPPING_2, // waiting for presentation complete
- RESUMING, // for PlaybackTracks only
- ACTIVE,
- PAUSING,
- PAUSED,
- STARTING_1, // for RecordTrack only
- STARTING_2, // for RecordTrack only
- };
-
- // where to allocate the data buffer
- enum alloc_type {
- ALLOC_CBLK, // allocate immediately after control block
- ALLOC_READONLY, // allocate from a separate read-only heap per thread
- ALLOC_PIPE, // do not allocate; use the pipe buffer
- ALLOC_LOCAL, // allocate a local buffer
- ALLOC_NONE, // do not allocate:use the buffer passed to TrackBase constructor
- };
-
- enum track_type {
- TYPE_DEFAULT,
- TYPE_OUTPUT,
- TYPE_PATCH,
- };
-
TrackBase(ThreadBase *thread,
const sp<Client>& client,
const audio_attributes_t& mAttr,
@@ -71,87 +39,80 @@
track_type type = TYPE_DEFAULT,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE,
std::string metricsId = {});
- virtual ~TrackBase();
- virtual status_t initCheck() const;
+ ~TrackBase() override;
+ status_t initCheck() const override;
+ sp<IMemory> getCblk() const final { return mCblkMemory; }
+ audio_track_cblk_t* cblk() const final { return mCblk; }
+ audio_session_t sessionId() const final { return mSessionId; }
+ uid_t uid() const final { return mUid; }
+ pid_t creatorPid() const final { return mCreatorPid; }
+ audio_port_handle_t portId() const final { return mPortId; }
+ status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event) override;
+ track_state state() const final { return mState; }
+ void setState(track_state state) final { mState = state; }
+ sp<IMemory> getBuffers() const final { return mBufferMemory; }
+ void* buffer() const final { return mBuffer; }
+ size_t bufferSize() const final { return mBufferSize; }
- virtual status_t start(AudioSystem::sync_event_t event,
- audio_session_t triggerSession) = 0;
- virtual void stop() = 0;
- sp<IMemory> getCblk() const { return mCblkMemory; }
- audio_track_cblk_t* cblk() const { return mCblk; }
- audio_session_t sessionId() const { return mSessionId; }
- uid_t uid() const { return mUid; }
- pid_t creatorPid() const { return mCreatorPid; }
-
- audio_port_handle_t portId() const { return mPortId; }
- virtual status_t setSyncEvent(const sp<audioflinger::SyncEvent>& event);
-
- sp<IMemory> getBuffers() const { return mBufferMemory; }
- void* buffer() const { return mBuffer; }
- size_t bufferSize() const { return mBufferSize; }
- virtual bool isFastTrack() const = 0;
- virtual bool isDirect() const = 0;
- bool isOutputTrack() const { return (mType == TYPE_OUTPUT); }
- bool isPatchTrack() const { return (mType == TYPE_PATCH); }
- bool isExternalTrack() const { return !isOutputTrack() && !isPatchTrack(); }
-
- virtual void invalidate() {
+ bool isOutputTrack() const final { return (mType == TYPE_OUTPUT); }
+ bool isPatchTrack() const final { return (mType == TYPE_PATCH); }
+ bool isExternalTrack() const final { return !isOutputTrack() && !isPatchTrack(); }
+ void invalidate() override {
if (mIsInvalid) return;
mTrackMetrics.logInvalidate();
mIsInvalid = true;
}
- bool isInvalid() const { return mIsInvalid; }
+ bool isInvalid() const final { return mIsInvalid; }
+ void terminate() final { mTerminated = true; }
+ bool isTerminated() const final { return mTerminated; }
+ audio_attributes_t attributes() const final { return mAttr; }
+ bool isSpatialized() const override { return false; }
+ bool isBitPerfect() const override { return false; }
- void terminate() { mTerminated = true; }
- bool isTerminated() const { return mTerminated; }
+ // TODO(b/288339104) type
+ wp<Thread> thread() const final { return mThread; }
- audio_attributes_t attributes() const { return mAttr; }
-
- virtual bool isSpatialized() const { return false; }
-
- virtual bool isBitPerfect() const { return false; }
+ const sp<ServerProxy>& serverProxy() const final { return mServerProxy; }
#ifdef TEE_SINK
- void dumpTee(int fd, const std::string &reason) const {
- mTee.dump(fd, reason);
- }
+ void dumpTee(int fd, const std::string &reason) const final {
+ mTee.dump(fd, reason);
+ }
#endif
-
- /** returns the buffer contents size converted to time in milliseconds
- * for PCM Playback or Record streaming tracks. The return value is zero for
- * PCM static tracks and not defined for non-PCM tracks.
- *
- * This may be called without the thread lock.
- */
- virtual double bufferLatencyMs() const {
+ /** returns the buffer contents size converted to time in milliseconds
+ * for PCM Playback or Record streaming tracks. The return value is zero for
+ * PCM static tracks and not defined for non-PCM tracks.
+ *
+ * This may be called without the thread lock.
+ */
+ double bufferLatencyMs() const override {
return mServerProxy->framesReadySafe() * 1000. / sampleRate();
}
- /** returns whether the track supports server latency computation.
- * This is set in the constructor and constant throughout the track lifetime.
- */
+ /** returns whether the track supports server latency computation.
+ * This is set in the constructor and constant throughout the track lifetime.
+ */
+ bool isServerLatencySupported() const final { return mServerLatencySupported; }
- bool isServerLatencySupported() const { return mServerLatencySupported; }
-
- /** computes the server latency for PCM Playback or Record track
- * to the device sink/source. This is the time for the next frame in the track buffer
- * written or read from the server thread to the device source or sink.
- *
- * This may be called without the thread lock, but latencyMs and fromTrack
- * may be not be synchronized. For example PatchPanel may not obtain the
- * thread lock before calling.
- *
- * \param latencyMs on success is set to the latency in milliseconds of the
- * next frame written/read by the server thread to/from the track buffer
- * from the device source/sink.
- * \param fromTrack on success is set to true if latency was computed directly
- * from the track timestamp; otherwise set to false if latency was
- * estimated from the server timestamp.
- * fromTrack may be nullptr or omitted if not required.
- *
- * \returns OK or INVALID_OPERATION on failure.
- */
- status_t getServerLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+ /** computes the server latency for PCM Playback or Record track
+ * to the device sink/source. This is the time for the next frame in the track buffer
+ * written or read from the server thread to the device source or sink.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the server thread to/from the track buffer
+ * from the device source/sink.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ status_t getServerLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const final {
if (!isServerLatencySupported()) {
return INVALID_OPERATION;
}
@@ -170,25 +131,25 @@
return OK;
}
- /** computes the total client latency for PCM Playback or Record tracks
- * for the next client app access to the device sink/source; i.e. the
- * server latency plus the buffer latency.
- *
- * This may be called without the thread lock, but latencyMs and fromTrack
- * may be not be synchronized. For example PatchPanel may not obtain the
- * thread lock before calling.
- *
- * \param latencyMs on success is set to the latency in milliseconds of the
- * next frame written/read by the client app to/from the track buffer
- * from the device sink/source.
- * \param fromTrack on success is set to true if latency was computed directly
- * from the track timestamp; otherwise set to false if latency was
- * estimated from the server timestamp.
- * fromTrack may be nullptr or omitted if not required.
- *
- * \returns OK or INVALID_OPERATION on failure.
- */
- status_t getTrackLatencyMs(double *latencyMs, bool *fromTrack = nullptr) const {
+ /** computes the total client latency for PCM Playback or Record tracks
+ * for the next client app access to the device sink/source; i.e. the
+ * server latency plus the buffer latency.
+ *
+ * This may be called without the thread lock, but latencyMs and fromTrack
+ * may be not be synchronized. For example PatchPanel may not obtain the
+ * thread lock before calling.
+ *
+ * \param latencyMs on success is set to the latency in milliseconds of the
+ * next frame written/read by the client app to/from the track buffer
+ * from the device sink/source.
+ * \param fromTrack on success is set to true if latency was computed directly
+ * from the track timestamp; otherwise set to false if latency was
+ * estimated from the server timestamp.
+ * fromTrack may be nullptr or omitted if not required.
+ *
+ * \returns OK or INVALID_OPERATION on failure.
+ */
+ status_t getTrackLatencyMs(double* latencyMs, bool* fromTrack = nullptr) const {
double serverLatencyMs;
status_t status = getServerLatencyMs(&serverLatencyMs, fromTrack);
if (status == OK) {
@@ -197,21 +158,15 @@
return status;
}
- // TODO: Consider making this external.
- struct FrameTime {
- int64_t frames;
- int64_t timeNs;
- };
-
- // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
- void getKernelFrameTime(FrameTime *ft) const {
+ // KernelFrameTime is updated per "mix" period even for non-pcm tracks.
+ void getKernelFrameTime(FrameTime* ft) const final {
*ft = mKernelFrameTime.load();
}
- audio_format_t format() const { return mFormat; }
- int id() const { return mId; }
+ audio_format_t format() const final { return mFormat; }
+ int id() const final { return mId; }
- const char *getTrackStateAsString() const {
+ const char* getTrackStateAsString() const final {
if (isTerminated()) {
return "TERMINATED";
}
@@ -245,19 +200,19 @@
// Called by the PlaybackThread to indicate that the track is becoming active
// and a new interval should start with a given device list.
- void logBeginInterval(const std::string& devices) {
+ void logBeginInterval(const std::string& devices) final {
mTrackMetrics.logBeginInterval(devices);
}
// Called by the PlaybackThread to indicate the track is no longer active.
- void logEndInterval() {
+ void logEndInterval() final {
mTrackMetrics.logEndInterval();
}
// Called to tally underrun frames in playback.
- virtual void tallyUnderrunFrames(size_t /* frames */) {}
+ void tallyUnderrunFrames(size_t /* frames */) override {}
- audio_channel_mask_t channelMask() const { return mChannelMask; }
+ audio_channel_mask_t channelMask() const final { return mChannelMask; }
/** @return true if the track has changed (metadata or volume) since
* the last time this function was called,
@@ -265,10 +220,10 @@
* false otherwise.
* Thread safe.
*/
- bool readAndClearHasChanged() { return !mChangeNotified.test_and_set(); }
+ bool readAndClearHasChanged() final { return !mChangeNotified.test_and_set(); }
/** Set that a metadata has changed and needs to be notified to backend. Thread safe. */
- void setMetadataHasChanged() { mChangeNotified.clear(); }
+ void setMetadataHasChanged() final { mChangeNotified.clear(); }
protected:
DISALLOW_COPY_AND_ASSIGN(TrackBase);
@@ -285,31 +240,31 @@
}
// AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ // status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) override;
+ void releaseBuffer(AudioBufferProvider::Buffer* buffer) override;
// ExtendedAudioBufferProvider interface is only needed for Track,
// but putting it in TrackBase avoids the complexity of virtual inheritance
- virtual size_t framesReady() const { return SIZE_MAX; }
+ size_t framesReady() const override { return SIZE_MAX; } // MmapTrack doesn't implement.
uint32_t channelCount() const { return mChannelCount; }
- size_t frameSize() const { return mFrameSize; }
+ size_t frameSize() const final { return mFrameSize; }
- virtual uint32_t sampleRate() const { return mSampleRate; }
+ uint32_t sampleRate() const override { return mSampleRate; }
- bool isStopped() const {
+ bool isStopped() const final {
return (mState == STOPPED || mState == FLUSHED);
}
// for fast tracks and offloaded tracks only
- bool isStopping() const {
+ bool isStopping() const final {
return mState == STOPPING_1 || mState == STOPPING_2;
}
- bool isStopping_1() const {
+ bool isStopping_1() const final {
return mState == STOPPING_1;
}
- bool isStopping_2() const {
+ bool isStopping_2() const final {
return mState == STOPPING_2;
}
@@ -421,7 +376,7 @@
{
public:
- virtual ~PatchProxyBufferProvider() {}
+ virtual ~PatchProxyBufferProvider() = default;
virtual bool producesBufferOnDemand() const = 0;
virtual status_t obtainBuffer(Proxy::Buffer* buffer,
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9ec3ee3..20033dd 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -94,7 +94,7 @@
track_type type,
audio_port_handle_t portId,
std::string metricsId)
- : RefBase(),
+ :
mThread(thread),
mAllocType(alloc),
mClient(client),
@@ -339,7 +339,7 @@
class TrackHandle : public android::media::BnAudioTrack {
public:
- explicit TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track);
+ explicit TrackHandle(const sp<IAfTrack>& track);
~TrackHandle() override;
binder::Status getCblk(std::optional<media::SharedFileRegion>* _aidl_return) final;
@@ -373,16 +373,15 @@
const media::audio::common::AudioPlaybackRate& playbackRate) final;
private:
- const sp<AudioFlinger::PlaybackThread::Track> mTrack;
+ const sp<IAfTrack> mTrack;
};
/* static */
-sp<media::IAudioTrack> AudioFlinger::PlaybackThread::Track::createIAudioTrackAdapter(
- const sp<Track>& track) {
+sp<media::IAudioTrack> IAfTrack::createIAudioTrackAdapter(const sp<IAfTrack>& track) {
return sp<TrackHandle>::make(track);
}
-TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
+TrackHandle::TrackHandle(const sp<IAfTrack>& track)
: BnAudioTrack(),
mTrack(track)
{
@@ -852,7 +851,7 @@
forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
}
-void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
+void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result) const
{
result.appendFormat("Type Id Active Client Session Port Id S Flags "
" Format Chn mask SRate "
@@ -863,7 +862,7 @@
isServerLatencySupported() ? " Latency" : "");
}
-void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
+void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active) const
{
char trackType;
switch (mType) {
@@ -1460,7 +1459,7 @@
return status;
}
-sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id)
+sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id) const
{
// Note: We don't check if Thread exists.
@@ -1751,7 +1750,7 @@
// implement VolumeBufferProvider interface
-gain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
+gain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR() const
{
// called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
@@ -1824,7 +1823,7 @@
}
}
-status_t AudioFlinger::PlaybackThread::Track::getDualMonoMode(audio_dual_mono_mode_t* mode)
+status_t AudioFlinger::PlaybackThread::Track::getDualMonoMode(audio_dual_mono_mode_t* mode) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
@@ -1857,7 +1856,7 @@
return status;
}
-status_t AudioFlinger::PlaybackThread::Track::getAudioDescriptionMixLevel(float* leveldB)
+status_t AudioFlinger::PlaybackThread::Track::getAudioDescriptionMixLevel(float* leveldB) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
@@ -1891,7 +1890,7 @@
}
status_t AudioFlinger::PlaybackThread::Track::getPlaybackRateParameters(
- audio_playback_rate_t* playbackRate)
+ audio_playback_rate_t* playbackRate) const
{
status_t status = INVALID_OPERATION;
if (isOffloadedOrDirect()) {
@@ -2483,7 +2482,7 @@
class RecordHandle : public android::media::BnAudioRecord {
public:
- explicit RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack);
+ explicit RecordHandle(const sp<IAfRecordTrack>& recordTrack);
~RecordHandle() override;
binder::Status start(int /*AudioSystem::sync_event_t*/ event,
int /*audio_session_t*/ triggerSession) final;
@@ -2497,20 +2496,20 @@
const std::string& sharedAudioPackageName, int64_t sharedAudioStartMs) final;
private:
- const sp<AudioFlinger::RecordThread::RecordTrack> mRecordTrack;
+ const sp<IAfRecordTrack> mRecordTrack;
// for use from destructor
void stop_nonvirtual();
};
/* static */
-sp<media::IAudioRecord> AudioFlinger::RecordThread::RecordTrack::createIAudioRecordAdapter(
- const sp<RecordTrack>& recordTrack) {
+sp<media::IAudioRecord> IAfRecordTrack::createIAudioRecordAdapter(
+ const sp<IAfRecordTrack>& recordTrack) {
return sp<RecordHandle>::make(recordTrack);
}
RecordHandle::RecordHandle(
- const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
+ const sp<IAfRecordTrack>& recordTrack)
: BnAudioRecord(),
mRecordTrack(recordTrack)
{
@@ -2752,7 +2751,7 @@
}
-void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
+void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result) const
{
result.appendFormat("Active Id Client Session Port Id S Flags "
" Format Chn mask SRate Source "
@@ -2760,7 +2759,7 @@
isServerLatencySupported() ? " Latency" : "");
}
-void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
+void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active) const
{
result.appendFormat("%c%5s %6d %6u %7u %7u %2s 0x%03X "
"%08X %08X %6u %6X "
@@ -2859,7 +2858,7 @@
}
status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
- std::vector<media::MicrophoneInfoFw>* activeMicrophones)
+ std::vector<media::MicrophoneInfoFw>* activeMicrophones) const
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
@@ -3331,13 +3330,13 @@
}
}
-void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
+void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result) const
{
result.appendFormat("Client Session Port Id Format Chn mask SRate Flags %s\n",
isOut() ? "Usg CT": "Source");
}
-void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
+void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused) const
{
result.appendFormat("%6u %7u %7u %08X %08X %6u 0x%03X ",
mPid,
diff --git a/services/audioflinger/fastpath/FastMixerState.h b/services/audioflinger/fastpath/FastMixerState.h
index c70e42a..8ab6d25 100644
--- a/services/audioflinger/fastpath/FastMixerState.h
+++ b/services/audioflinger/fastpath/FastMixerState.h
@@ -35,7 +35,7 @@
class VolumeProvider {
public:
// The provider implementation is responsible for validating that the return value is in range.
- virtual gain_minifloat_packed_t getVolumeLR() = 0;
+ virtual gain_minifloat_packed_t getVolumeLR() const = 0;
protected:
VolumeProvider() = default;
virtual ~VolumeProvider() = default;