diff options
| author | 2020-06-03 09:25:25 -0700 | |
|---|---|---|
| committer | 2020-06-05 10:15:42 -0700 | |
| commit | 14e3bd0c3ee6581b8df73573af780baef40869e0 (patch) | |
| tree | 4adfd0765edf55de415d45eebae6a247f329b3da | |
| parent | 84bc21cbecc6481403b6f2b0f99b4740882e4c59 (diff) | |
Adding lock to sendEventFromNative
Eliminate potential race condition for postEventFromNative.
Fixes: 157755647
Test: atest com.android.car where race condition was hit
Change-Id: I5d11f8769d2c09a6a630332db447302e06a5869b
| -rw-r--r-- | media/java/android/media/SoundPool.java | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 26e65dda5ebf..1bf2863989a5 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -16,28 +16,22 @@ package android.media; -import java.io.File; -import java.io.FileDescriptor; -import java.lang.ref.WeakReference; - import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityThread; -import android.app.AppOpsManager; import android.content.Context; import android.content.res.AssetFileDescriptor; -import android.media.PlayerBase; import android.os.Handler; -import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; -import android.os.Process; -import android.os.RemoteException; -import android.os.ServiceManager; import android.util.AndroidRuntimeException; import android.util.Log; +import java.io.File; +import java.io.FileDescriptor; +import java.lang.ref.WeakReference; +import java.util.concurrent.atomic.AtomicReference; + /** * The SoundPool class manages and plays audio resources for applications. @@ -122,13 +116,12 @@ public class SoundPool extends PlayerBase { private final static String TAG = "SoundPool"; private final static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private final AtomicReference<EventHandler> mEventHandler = new AtomicReference<>(null); + private long mNativeContext; // accessed by native methods - private EventHandler mEventHandler; - private SoundPool.OnLoadCompleteListener mOnLoadCompleteListener; private boolean mHasAppOpsPlayAudio; - private final Object mLock; private final AudioAttributes mAttributes; /** @@ -159,7 +152,6 @@ public class SoundPool extends PlayerBase { if (native_setup(new WeakReference<SoundPool>(this), maxStreams, attributes) != 0) { throw new RuntimeException("Native setup failed"); } - mLock = new Object(); mAttributes = attributes; baseRegisterPlayer(); @@ -491,21 +483,18 @@ public class SoundPool extends PlayerBase { * Sets the callback hook for the OnLoadCompleteListener. */ public void setOnLoadCompleteListener(OnLoadCompleteListener listener) { - synchronized(mLock) { - if (listener != null) { - // setup message handler - Looper looper; - if ((looper = Looper.myLooper()) != null) { - mEventHandler = new EventHandler(looper); - } else if ((looper = Looper.getMainLooper()) != null) { - mEventHandler = new EventHandler(looper); - } else { - mEventHandler = null; - } - } else { - mEventHandler = null; - } - mOnLoadCompleteListener = listener; + if (listener == null) { + mEventHandler.set(null); + return; + } + + Looper looper; + if ((looper = Looper.myLooper()) != null) { + mEventHandler.set(new EventHandler(looper, listener)); + } else if ((looper = Looper.getMainLooper()) != null) { + mEventHandler.set(new EventHandler(looper, listener)); + } else { + mEventHandler.set(null); } } @@ -525,35 +514,36 @@ public class SoundPool extends PlayerBase { @SuppressWarnings("unchecked") private static void postEventFromNative(Object ref, int msg, int arg1, int arg2, Object obj) { SoundPool soundPool = ((WeakReference<SoundPool>) ref).get(); - if (soundPool == null) + if (soundPool == null) { return; + } - if (soundPool.mEventHandler != null) { - Message m = soundPool.mEventHandler.obtainMessage(msg, arg1, arg2, obj); - soundPool.mEventHandler.sendMessage(m); + Handler eventHandler = soundPool.mEventHandler.get(); + if (eventHandler == null) { + return; } + + Message message = eventHandler.obtainMessage(msg, arg1, arg2, obj); + eventHandler.sendMessage(message); } private final class EventHandler extends Handler { - public EventHandler(Looper looper) { + private final OnLoadCompleteListener mOnLoadCompleteListener; + + EventHandler(Looper looper, @NonNull OnLoadCompleteListener onLoadCompleteListener) { super(looper); + mOnLoadCompleteListener = onLoadCompleteListener; } @Override public void handleMessage(Message msg) { - switch(msg.what) { - case SAMPLE_LOADED: - if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded"); - synchronized(mLock) { - if (mOnLoadCompleteListener != null) { - mOnLoadCompleteListener.onLoadComplete(SoundPool.this, msg.arg1, msg.arg2); - } - } - break; - default: + if (msg.what != SAMPLE_LOADED) { Log.e(TAG, "Unknown message type " + msg.what); return; } + + if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded"); + mOnLoadCompleteListener.onLoadComplete(SoundPool.this, msg.arg1, msg.arg2); } } |