AudioFlinger: Create Client callback
Test: atest AudioTrackTest AudioRecordTest
Test: Camera YouTube
Bug: 291319167
Merged-In: I09328a818726b2dcf6c68247643eae4ec4cb48b8
Change-Id: I09328a818726b2dcf6c68247643eae4ec4cb48b8
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3f37a2c..ae16fa9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1035,7 +1035,7 @@
// (for which promote() is always != 0), otherwise create a new entry and Client.
sp<Client> client = mClients.valueFor(pid).promote();
if (client == 0) {
- client = new Client(this, pid);
+ client = sp<Client>::make(sp<IAfClientCallback>::fromExisting(this), pid);
mClients.add(pid, client);
}
@@ -2310,16 +2310,16 @@
// ----------------------------------------------------------------------------
-Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+Client::Client(const sp<IAfClientCallback>& afClientCallback, pid_t pid)
: RefBase(),
- mAudioFlinger(audioFlinger),
+ mAfClientCallback(afClientCallback),
mPid(pid),
mClientAllocator(AllocatorFactory::getClientAllocator()) {}
// Client destructor must be called with AudioFlinger::mClientLock held
Client::~Client()
{
- mAudioFlinger->removeClient_l(mPid);
+ mAfClientCallback->removeClient_l(mPid);
}
AllocatorFactory::ClientAllocator& Client::allocator()
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 357578b..c730d67 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -123,6 +123,9 @@
#include "Client.h"
#include "ResamplerBufferProvider.h"
+// TODO(b/291319167) remove me when AudioFlinger class not directly used by subcomponents
+namespace android { class AudioFlinger; }
+
// include AudioFlinger component interfaces
#include "IAfPatchPanel.h" // this should be listed before other IAf* interfaces.
#include "IAfEffect.h"
@@ -161,10 +164,10 @@
class AudioFlinger
: public AudioFlingerServerAdapter::Delegate // IAudioFlinger client interface
+ , public IAfClientCallback
{
friend class sp<AudioFlinger>;
// TODO(b/291319167) Create interface and remove friends.
- friend class Client; // removeClient_l();
friend class DeviceEffectManager;
friend class DeviceEffectManagerCallback;
friend class MelReporter;
@@ -358,6 +361,18 @@
// ---- end of IAudioFlinger interface
+ // ---- begin IAfClientCallback interface
+
+ Mutex& clientMutex() const final { return mClientLock; }
+ void removeClient_l(pid_t pid) final;
+ void removeNotificationClient(pid_t pid) final;
+ status_t moveAuxEffectToIo(
+ int effectId,
+ const sp<IAfPlaybackThread>& dstThread,
+ sp<IAfPlaybackThread>* srcThread) final;
+
+ // ---- end of IAfClientCallback interface
+
bool isAudioPolicyReady() const { return mAudioPolicyReady.load(); }
/* List available audio ports and their attributes */
@@ -655,12 +670,6 @@
status_t moveEffectChain_l(audio_session_t sessionId,
IAfPlaybackThread* srcThread, IAfPlaybackThread* dstThread);
-public:
- // TODO(b/291319167) cluster together
- status_t moveAuxEffectToIo(int EffectId,
- const sp<IAfPlaybackThread>& dstThread, sp<IAfPlaybackThread>* srcThread);
-private:
-
// return thread associated with primary hardware device, or NULL
IAfPlaybackThread* primaryPlaybackThread_l() const;
DeviceTypeSet primaryOutputDevice_l() const;
@@ -677,9 +686,6 @@
IAfPlaybackThread* thread,
const std::vector<audio_io_handle_t>& secondaryOutputs) const;
-
- void removeClient_l(pid_t pid);
- void removeNotificationClient(pid_t pid);
public:
// TODO(b/291319167) cluster together
bool isNonOffloadableGlobalEffectEnabled_l();
@@ -731,9 +737,9 @@
// must be locked after mLock and ThreadBase::mLock if both must be locked
// avoids acquiring AudioFlinger::mLock from inside thread loop.
- // TODO(b/291319167) access by getter,
- mutable Mutex mClientLock;
private:
+ mutable Mutex mClientLock;
+
// protected by mClientLock
DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client()
diff --git a/services/audioflinger/Client.h b/services/audioflinger/Client.h
index 142d384..36d6ff7 100644
--- a/services/audioflinger/Client.h
+++ b/services/audioflinger/Client.h
@@ -19,23 +19,34 @@
// TODO(b/291318727) Move to nested namespace
namespace android {
-class AudioFlinger;
+class IAfPlaybackThread;
+
+class IAfClientCallback : public virtual RefBase {
+public:
+ virtual Mutex& clientMutex() const = 0;
+ virtual void removeClient_l(pid_t pid) = 0;
+ virtual void removeNotificationClient(pid_t pid) = 0;
+ virtual status_t moveAuxEffectToIo(
+ int effectId,
+ const sp<IAfPlaybackThread>& dstThread,
+ sp<IAfPlaybackThread>* srcThread) = 0;
+};
class Client : public RefBase {
public:
- Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
+ Client(const sp<IAfClientCallback>& audioFlinger, pid_t pid);
// TODO(b/289139675) make Client container.
// Client destructor must be called with AudioFlinger::mClientLock held
~Client() override;
AllocatorFactory::ClientAllocator& allocator();
pid_t pid() const { return mPid; }
- sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
+ const auto& afClientCallback() const { return mAfClientCallback; }
private:
DISALLOW_COPY_AND_ASSIGN(Client);
- const sp<AudioFlinger> mAudioFlinger;
+ const sp<IAfClientCallback> mAfClientCallback;
const pid_t mPid;
AllocatorFactory::ClientAllocator mClientAllocator;
};
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 0f78f80..e9d1baf 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -1886,7 +1886,7 @@
}
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l2(mClient->audioFlinger()->mClientLock);
+ Mutex::Autolock _l2(mClient->afClientCallback()->clientMutex());
mClient.clear();
}
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9169783..979779d 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -276,7 +276,7 @@
mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
if (mClient != 0) {
// Client destructor must run with AudioFlinger client mutex locked
- Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
+ Mutex::Autolock _l(mClient->afClientCallback()->clientMutex());
// If the client's reference count drops to zero, the associated destructor
// must run with AudioFlinger lock held. Thus the explicit clear() rather than
// relying on the automatic clear() at end of scope.
@@ -1678,7 +1678,7 @@
auto dstThread = thread->asIAfPlaybackThread();
// srcThread is initialized by call to moveAuxEffectToIo()
sp<IAfPlaybackThread> srcThread;
- sp<AudioFlinger> af = mClient->audioFlinger();
+ const auto& af = mClient->afClientCallback();
status_t status = af->moveAuxEffectToIo(EffectId, dstThread, &srcThread);
if (EffectId != 0 && status == NO_ERROR) {