Prevent object of AudioEffect be deleted until construction finished

The object of AudioEffect may be deleted when construction ongoing,
if the method of mIEffectClient invoked by the proxy in audioflinger.

If mIEffectClient cleared in the destructor of AudioEffect before IEffect
linkToDeath to mIEffectClient in the constructor of the AudioEffect,
the aforementioned case may lead to an abort, i.e.,
"Abort Message: 'linkToDeath():recipient must be non-NULL".

Test: monkey test
Change-Id: I5fe8227b8528fb9fb9c9a1e636bd4dc0cc22c2cf
diff --git a/media/libaudioclient/AudioEffect.cpp b/media/libaudioclient/AudioEffect.cpp
index b1cb0e7..b40f0db 100644
--- a/media/libaudioclient/AudioEffect.cpp
+++ b/media/libaudioclient/AudioEffect.cpp
@@ -52,6 +52,7 @@
                 )
     : mStatus(NO_INIT), mOpPackageName(opPackageName)
 {
+    AutoMutex lock(mConstructLock);
     mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
 }
 
@@ -85,6 +86,7 @@
         }
     }
 
+    AutoMutex lock(mConstructLock);
     mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
 }
 
diff --git a/media/libaudioclient/include/media/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
index bfc068b..324bcb9 100644
--- a/media/libaudioclient/include/media/AudioEffect.h
+++ b/media/libaudioclient/include/media/AudioEffect.h
@@ -414,6 +414,7 @@
      effect_descriptor_t     mDescriptor;        // effect descriptor
      int32_t                 mId;                // system wide unique effect engine instance ID
      Mutex                   mLock;              // Mutex for mEnabled access
+     Mutex                   mConstructLock;     // Mutex for integrality construction
 
      String16                mOpPackageName;     // The package name used for app op checks.
 
@@ -440,12 +441,22 @@
         virtual void controlStatusChanged(bool controlGranted) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->controlStatusChanged(controlGranted);
             }
         }
         virtual void enableStatusChanged(bool enabled) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->enableStatusChanged(enabled);
             }
         }
@@ -456,6 +467,11 @@
                                      void *pReplyData) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->commandExecuted(
                     cmdCode, cmdSize, pCmdData, replySize, pReplyData);
             }
@@ -465,6 +481,11 @@
         virtual void binderDied(const wp<IBinder>& /*who*/) {
             sp<AudioEffect> effect = mEffect.promote();
             if (effect != 0) {
+                {
+                    // Got the mConstructLock means the construction of AudioEffect
+                    // has finished, we should release the mConstructLock immediately.
+                    AutoMutex lock(effect->mConstructLock);
+                }
                 effect->binderDied();
             }
         }