Fix race condition in Effects

Main problem was in AudioFlinger::EffectChain::EffectChain(), where
the thread* argument could possibly have been destroyed before the
creation of the weak pointer
(AudioFlinger::EffectChain::EffectCallback::mThread) around it.

While here, cleaned up a bunch of other pointer-related operations
in order to avoid trafficking in raw pointers to RefBase subclasses.

Bug: 147770363
Change-Id: I508ca94dd38a04e13f1a1c413f548001b961c721
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 0fac36d..d4e0ae2 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -343,7 +343,10 @@
 
         virtual ~SyncEvent() {}
 
-        void trigger() { Mutex::Autolock _l(mLock); if (mCallback) mCallback(this); }
+        void trigger() {
+            Mutex::Autolock _l(mLock);
+            if (mCallback) mCallback(wp<SyncEvent>(this));
+        }
         bool isCancelled() const { Mutex::Autolock _l(mLock); return (mCallback == NULL); }
         void cancel() { Mutex::Autolock _l(mLock); mCallback = NULL; }
         AudioSystem::sync_event_t type() const { return mType; }
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 70c56e3..2f3724f 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -737,7 +737,7 @@
             }
             if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float.
                 if (!auxType) {
-                    if (mInConversionBuffer.get() == nullptr) {
+                    if (mInConversionBuffer == nullptr) {
                         ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
                         goto data_bypass;
                     }
@@ -748,7 +748,7 @@
                     inBuffer = mInConversionBuffer;
                 }
                 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
-                    if (mOutConversionBuffer.get() == nullptr) {
+                    if (mOutConversionBuffer == nullptr) {
                         ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
                         goto data_bypass;
                     }
@@ -921,9 +921,8 @@
     mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
 
     ALOGV("configure() %p chain %p buffer %p framecount %zu",
-            this, mCallback->chain().promote() != nullptr ? mCallback->chain().promote().get() :
-                                                            nullptr,
-              mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
+          this, mCallback->chain().promote().get(),
+          mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
 
     status_t cmdStatus;
     size = sizeof(int);
@@ -1290,7 +1289,7 @@
     const uint32_t inChannelCount =
             audio_channel_count_from_out_mask(mConfig.inputCfg.channels);
     const bool formatMismatch = !mSupportsFloat || mInChannelCountRequested != inChannelCount;
-    if (!auxType && formatMismatch && mInBuffer.get() != nullptr) {
+    if (!auxType && formatMismatch && mInBuffer != nullptr) {
         // we need to translate - create hidl shared buffer and intercept
         const size_t inFrameCount = mConfig.inputCfg.buffer.frameCount;
         // Use FCC_2 in case mInChannelCountRequested is mono and the effect is stereo.
@@ -1300,13 +1299,13 @@
         ALOGV("%s: setInBuffer updating for inChannels:%d inFrameCount:%zu total size:%zu",
                 __func__, inChannels, inFrameCount, size);
 
-        if (size > 0 && (mInConversionBuffer.get() == nullptr
+        if (size > 0 && (mInConversionBuffer == nullptr
                 || size > mInConversionBuffer->getSize())) {
             mInConversionBuffer.clear();
             ALOGV("%s: allocating mInConversionBuffer %zu", __func__, size);
             (void)mCallback->allocateHalBuffer(size, &mInConversionBuffer);
         }
-        if (mInConversionBuffer.get() != nullptr) {
+        if (mInConversionBuffer != nullptr) {
             mInConversionBuffer->setFrameCount(inFrameCount);
             mEffectInterface->setInBuffer(mInConversionBuffer);
         } else if (size > 0) {
@@ -1335,7 +1334,7 @@
     const uint32_t outChannelCount =
             audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
     const bool formatMismatch = !mSupportsFloat || mOutChannelCountRequested != outChannelCount;
-    if (formatMismatch && mOutBuffer.get() != nullptr) {
+    if (formatMismatch && mOutBuffer != nullptr) {
         const size_t outFrameCount = mConfig.outputCfg.buffer.frameCount;
         // Use FCC_2 in case mOutChannelCountRequested is mono and the effect is stereo.
         const uint32_t outChannels = std::max((uint32_t)FCC_2, mOutChannelCountRequested);
@@ -1344,13 +1343,13 @@
         ALOGV("%s: setOutBuffer updating for outChannels:%d outFrameCount:%zu total size:%zu",
                 __func__, outChannels, outFrameCount, size);
 
-        if (size > 0 && (mOutConversionBuffer.get() == nullptr
+        if (size > 0 && (mOutConversionBuffer == nullptr
                 || size > mOutConversionBuffer->getSize())) {
             mOutConversionBuffer.clear();
             ALOGV("%s: allocating mOutConversionBuffer %zu", __func__, size);
             (void)mCallback->allocateHalBuffer(size, &mOutConversionBuffer);
         }
-        if (mOutConversionBuffer.get() != nullptr) {
+        if (mOutConversionBuffer != nullptr) {
             mOutConversionBuffer->setFrameCount(outFrameCount);
             mEffectInterface->setOutBuffer(mOutConversionBuffer);
         } else if (size > 0) {
@@ -1521,7 +1520,7 @@
 static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
     std::stringstream ss;
 
-    if (buffer.get() == nullptr) {
+    if (buffer == nullptr) {
         return "nullptr"; // make different than below
     } else if (buffer->externalData() != nullptr) {
         ss << (isInput ? buffer->externalData() : buffer->audioBuffer()->raw)
@@ -1937,19 +1936,20 @@
 #undef LOG_TAG
 #define LOG_TAG "AudioFlinger::EffectChain"
 
-AudioFlinger::EffectChain::EffectChain(ThreadBase *thread,
-                                        audio_session_t sessionId)
+AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& thread,
+                                       audio_session_t sessionId)
     : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
       mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
       mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
-      mEffectCallback(new EffectCallback(this, thread, thread->mAudioFlinger.get()))
+      mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
 {
     mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
-    if (thread == nullptr) {
+    sp<ThreadBase> p = thread.promote();
+    if (p == nullptr) {
         return;
     }
-    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
-                                    thread->frameCount();
+    mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) /
+                                    p->frameCount();
 }
 
 AudioFlinger::EffectChain::~EffectChain()
@@ -2638,7 +2638,7 @@
 void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread)
 {
     Mutex::Autolock _l(mLock);
-    mEffectCallback->setThread(thread.get());
+    mEffectCallback->setThread(thread);
 }
 
 void AudioFlinger::EffectChain::checkOutputFlagCompatibility(audio_output_flags_t *flags) const
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 40bb226..1dfa1ae 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -402,7 +402,6 @@
 class EffectChain : public RefBase {
 public:
     EffectChain(const wp<ThreadBase>& wThread, audio_session_t sessionId);
-    EffectChain(ThreadBase *thread, audio_session_t sessionId);
     virtual ~EffectChain();
 
     // special key used for an entry in mSuspendedEffects keyed vector
@@ -513,8 +512,11 @@
 
     class EffectCallback :  public EffectCallbackInterface {
     public:
-        EffectCallback(EffectChain *chain, ThreadBase *thread, AudioFlinger *audioFlinger)
-            : mChain(chain), mThread(thread), mAudioFlinger(audioFlinger) {}
+        EffectCallback(const wp<EffectChain>& chain,
+                       const wp<ThreadBase>& thread)
+            : mChain(chain) {
+            setThread(thread);
+        }
 
         status_t createEffectHal(const effect_uuid_t *pEffectUuid,
                int32_t sessionId, int32_t deviceId, sp<EffectHalInterface> *effect) override;
@@ -550,7 +552,12 @@
         wp<EffectChain> chain() const override { return mChain; }
 
         wp<ThreadBase> thread() { return mThread; }
-        void setThread(ThreadBase *thread) { mThread = thread; };
+
+        void setThread(const wp<ThreadBase>& thread) {
+            mThread = thread;
+            sp<ThreadBase> p = thread.promote();
+            mAudioFlinger = p ? p->mAudioFlinger : nullptr;
+        }
 
     private:
         wp<EffectChain> mChain;
@@ -623,7 +630,8 @@
                 effect_descriptor_t *desc, int id)
             : EffectBase(callback, desc, id, AUDIO_SESSION_DEVICE, false),
                 mDevice(device), mManagerCallback(callback),
-                mMyCallback(new ProxyCallback(this, callback)) {}
+                mMyCallback(new ProxyCallback(wp<DeviceEffectProxy>(this),
+                                              callback)) {}
 
     status_t setEnabled(bool enabled, bool fromHandle) override;
     sp<DeviceEffectProxy> asDeviceEffectProxy() override { return this; }
@@ -649,7 +657,7 @@
 
     class ProxyCallback :  public EffectCallbackInterface {
     public:
-                ProxyCallback(DeviceEffectProxy *proxy,
+                ProxyCallback(const wp<DeviceEffectProxy>& proxy,
                         const sp<DeviceEffectManagerCallback>& callback)
                     : mProxy(proxy), mManagerCallback(callback) {}