AudioFlinger: Add IAfPatchPanel interface
Test: atest audiorecord_tests audiotrack_tests audiorouting_tests trackplayerbase_tests audiosystem_tests
Test: atest AAudioTests AudioTrackOffloadTest
Test: atest AudioTrackTest AudioRecordTest
Test: YouTube Camera
Bug: 288339104
Bug: 291284401
Merged-In: I57b64268d95621a694d12bf347adc195570cab65
Change-Id: I57b64268d95621a694d12bf347adc195570cab65
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 4bb11b0..6caf527 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -21,211 +21,48 @@
public: // TODO(b/288339104) extract out of AudioFlinger class
// PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
-class PatchPanel {
+class PatchPanel : public IAfPatchPanel {
public:
- class SoftwarePatch {
- public:
- SoftwarePatch(const PatchPanel &patchPanel, audio_patch_handle_t patchHandle,
- audio_io_handle_t playbackThreadHandle, audio_io_handle_t recordThreadHandle)
- : mPatchPanel(patchPanel), mPatchHandle(patchHandle),
- mPlaybackThreadHandle(playbackThreadHandle),
- mRecordThreadHandle(recordThreadHandle) {}
- SoftwarePatch(const SoftwarePatch&) = default;
-
- // Must be called under AudioFlinger::mLock
- status_t getLatencyMs_l(double *latencyMs) const;
- audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
- audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
- audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
- private:
- const PatchPanel &mPatchPanel;
- const audio_patch_handle_t mPatchHandle;
- const audio_io_handle_t mPlaybackThreadHandle;
- const audio_io_handle_t mRecordThreadHandle;
- };
-
explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
/* List connected audio ports and their attributes */
status_t listAudioPorts(unsigned int *num_ports,
- struct audio_port *ports);
+ struct audio_port* ports) final;
/* Get supported attributes for a given audio port */
- status_t getAudioPort(struct audio_port_v7 *port);
+ status_t getAudioPort(struct audio_port_v7* port) final;
/* Create a patch between several source and sink ports */
status_t createAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
- bool endpointPatch = false);
+ bool endpointPatch = false) final;
/* Release a patch */
- status_t releaseAudioPatch(audio_patch_handle_t handle);
+ status_t releaseAudioPatch(audio_patch_handle_t handle) final;
/* List connected audio devices and they attributes */
status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches);
+ struct audio_patch* patches) final;
// Retrieves all currently estrablished software patches for a stream
// opened on an intermediate module.
status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
- std::vector<SoftwarePatch> *patches) const;
+ std::vector<SoftwarePatch>* patches) const final;
// Notifies patch panel about all opened and closed streams.
void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream,
- struct audio_patch *patch);
- void notifyStreamClosed(audio_io_handle_t stream);
+ struct audio_patch* patch) final;
+ void notifyStreamClosed(audio_io_handle_t stream) final;
- void dump(int fd) const;
-
- template<typename ThreadType, typename TrackType>
- class Endpoint final {
- public:
- Endpoint() = default;
- Endpoint(const Endpoint&) = delete;
- Endpoint& operator=(const Endpoint& other) noexcept {
- mThread = other.mThread;
- mCloseThread = other.mCloseThread;
- mHandle = other.mHandle;
- mTrack = other.mTrack;
- return *this;
- }
- Endpoint(Endpoint&& other) noexcept { swap(other); }
- Endpoint& operator=(Endpoint&& other) noexcept {
- swap(other);
- return *this;
- }
- ~Endpoint() {
- ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
- "A non empty Patch Endpoint leaked, handle %d", mHandle);
- }
-
- status_t checkTrack(TrackType *trackOrNull) const {
- if (trackOrNull == nullptr) return NO_MEMORY;
- return trackOrNull->initCheck();
- }
- audio_patch_handle_t handle() const { return mHandle; }
- sp<ThreadType> thread() const { return mThread; }
- sp<TrackType> track() const { return mTrack; }
- sp<const ThreadType> const_thread() const { return mThread; }
- sp<const TrackType> const_track() const { return mTrack; }
-
- void closeConnections(PatchPanel *panel) {
- if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
- panel->releaseAudioPatch(mHandle);
- mHandle = AUDIO_PATCH_HANDLE_NONE;
- }
- if (mThread != 0) {
- if (mTrack != 0) {
- mThread->deletePatchTrack(mTrack);
- }
- if (mCloseThread) {
- panel->mAudioFlinger.closeThreadInternal_l(mThread);
- }
- }
- }
- audio_patch_handle_t* handlePtr() { return &mHandle; }
- void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
- mThread = thread;
- mCloseThread = closeThread;
- }
- template <typename T>
- void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer, bool holdReference) {
- mTrack = track;
- mThread->addPatchTrack(mTrack);
- mTrack->setPeerProxy(peer, holdReference);
- mClearPeerProxy = holdReference;
- }
- void clearTrackPeer() { if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); }
- void stopTrack() { if (mTrack) mTrack->stop(); }
-
- void swap(Endpoint &other) noexcept {
- using std::swap;
- swap(mThread, other.mThread);
- swap(mCloseThread, other.mCloseThread);
- swap(mClearPeerProxy, other.mClearPeerProxy);
- swap(mHandle, other.mHandle);
- swap(mTrack, other.mTrack);
- }
-
- friend void swap(Endpoint &a, Endpoint &b) noexcept {
- a.swap(b);
- }
-
- private:
- sp<ThreadType> mThread;
- bool mCloseThread = true;
- bool mClearPeerProxy = true;
- audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
- sp<TrackType> mTrack;
- };
-
- class Patch final {
- public:
- Patch(const struct audio_patch &patch, bool endpointPatch) :
- mAudioPatch(patch), mIsEndpointPatch(endpointPatch) {}
- Patch() = default;
- ~Patch();
- Patch(const Patch& other) noexcept {
- mAudioPatch = other.mAudioPatch;
- mHalHandle = other.mHalHandle;
- mPlayback = other.mPlayback;
- mRecord = other.mRecord;
- mThread = other.mThread;
- mIsEndpointPatch = other.mIsEndpointPatch;
- }
- Patch(Patch&& other) noexcept { swap(other); }
- Patch& operator=(Patch&& other) noexcept {
- swap(other);
- return *this;
- }
-
- void swap(Patch &other) noexcept {
- using std::swap;
- swap(mAudioPatch, other.mAudioPatch);
- swap(mHalHandle, other.mHalHandle);
- swap(mPlayback, other.mPlayback);
- swap(mRecord, other.mRecord);
- swap(mThread, other.mThread);
- swap(mIsEndpointPatch, other.mIsEndpointPatch);
- }
-
- friend void swap(Patch &a, Patch &b) noexcept {
- a.swap(b);
- }
-
- status_t createConnections(PatchPanel *panel);
- void clearConnections(PatchPanel *panel);
- bool isSoftware() const {
- return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
- mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
-
- void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; }
- wp<IAfThreadBase> thread() const { return mThread; }
-
- // returns the latency of the patch (from record to playback).
- status_t getLatencyMs(double *latencyMs) const;
-
- String8 dump(audio_patch_handle_t myHandle) const;
-
- // Note that audio_patch::id is only unique within a HAL module
- struct audio_patch mAudioPatch;
- // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
- audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
- // below members are used by a software audio patch connecting a source device from a
- // given audio HW module to a sink device on an other audio HW module.
- // the objects are created by createConnections() and released by clearConnections()
- // playback thread is created if no existing playback thread can be used
- // connects playback thread output to sink device
- Endpoint<IAfPlaybackThread, IAfPatchTrack> mPlayback;
- // connects source device to record thread input
- Endpoint<IAfRecordThread, IAfPatchRecord> mRecord;
-
- wp<IAfThreadBase> mThread;
- bool mIsEndpointPatch;
- };
+ void dump(int fd) const final;
// Call with AudioFlinger mLock held
- std::map<audio_patch_handle_t, Patch>& patches_l() { return mPatches; }
+ const std::map<audio_patch_handle_t, Patch>& patches_l() const final { return mPatches; }
+
+ // Must be called under AudioFlinger::mLock
+ status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const final;
+
+ void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const final;
private:
AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);