From 3b5acfe29726b8e2fe061eba1ccfc4fd8ee1af35 Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Thu, 23 Dec 2021 14:52:28 -0800 Subject: [PATCH] media: don't reuse ParceledListSlices ParceledListSlice cannot be used for more than one transfer. Test: boots, no exceptions Bug: 213236807 Change-Id: I434f7cfef496d19e5fd58b7c8d699ba5700383d2 --- .../media/MediaCommunicationService.java | 31 ++++++++++--------- .../server/media/MediaSessionRecord.java | 19 ++++++------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java index e48f234c5569b..7d47e250f99d6 100644 --- a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java +++ b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java @@ -79,7 +79,7 @@ public class MediaCommunicationService extends SystemService { final Executor mRecordExecutor = Executors.newSingleThreadExecutor(); @GuardedBy("mLock") - final List mCallbackRecords = new ArrayList<>(); + final ArrayList mCallbackRecords = new ArrayList<>(); final NotificationManager mNotificationManager; MediaSessionManager mSessionManager; @@ -150,8 +150,8 @@ public class MediaCommunicationService extends SystemService { return null; } - List getSession2TokensLocked(int userId) { - List list = new ArrayList<>(); + ArrayList getSession2TokensLocked(int userId) { + ArrayList list = new ArrayList<>(); if (userId == ALL.getIdentifier()) { int size = mUserRecords.size(); for (int i = 0; i < size; i++) { @@ -237,28 +237,29 @@ public class MediaCommunicationService extends SystemService { } void dispatchSession2Changed(int userId) { - MediaParceledListSlice allSession2Tokens; - MediaParceledListSlice userSession2Tokens; + ArrayList allSession2Tokens; + ArrayList userSession2Tokens; synchronized (mLock) { - allSession2Tokens = - new MediaParceledListSlice<>(getSession2TokensLocked(ALL.getIdentifier())); - userSession2Tokens = new MediaParceledListSlice<>(getSession2TokensLocked(userId)); - } - allSession2Tokens.setInlineCountLimit(1); - userSession2Tokens.setInlineCountLimit(1); + allSession2Tokens = getSession2TokensLocked(ALL.getIdentifier()); + userSession2Tokens = getSession2TokensLocked(userId); - synchronized (mLock) { for (CallbackRecord record : mCallbackRecords) { if (record.mUserId == ALL.getIdentifier()) { try { - record.mCallback.onSession2Changed(allSession2Tokens); + MediaParceledListSlice toSend = + new MediaParceledListSlice<>(allSession2Tokens); + toSend.setInlineCountLimit(0); + record.mCallback.onSession2Changed(toSend); } catch (RemoteException e) { Log.w(TAG, "Failed to notify session2 tokens changed " + record); } } else if (record.mUserId == userId) { try { - record.mCallback.onSession2Changed(userSession2Tokens); + MediaParceledListSlice toSend = + new MediaParceledListSlice<>(userSession2Tokens); + toSend.setInlineCountLimit(0); + record.mCallback.onSession2Changed(toSend); } catch (RemoteException e) { Log.w(TAG, "Failed to notify session2 tokens changed " + record); } @@ -382,7 +383,7 @@ public class MediaCommunicationService extends SystemService { try { // Check that they can make calls on behalf of the user and get the final user id int resolvedUserId = handleIncomingUser(pid, uid, userId, null); - List result; + ArrayList result; synchronized (mLock) { result = getSession2TokensLocked(resolvedUserId); } diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 4822d6a62ac70..96391ac62530c 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -52,7 +52,6 @@ import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SystemClock; -import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -643,22 +642,24 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } private void pushQueueUpdate() { - ParceledListSlice parcelableQueue; + ArrayList toSend; synchronized (mLock) { if (mDestroyed) { return; } - if (mQueue == null) { - parcelableQueue = null; - } else { - parcelableQueue = new ParceledListSlice<>(mQueue); - // Limit the size of initial Parcel to prevent binder buffer overflow - // as onQueueChanged is an async binder call. - parcelableQueue.setInlineCountLimit(1); + toSend = new ArrayList<>(); + if (mQueue != null) { + toSend.ensureCapacity(mQueue.size()); + toSend.addAll(mQueue); } } Collection deadCallbackHolders = null; for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) { + ParceledListSlice parcelableQueue = new ParceledListSlice<>(toSend); + // Limit the size of initial Parcel to prevent binder buffer overflow + // as onQueueChanged is an async binder call. + parcelableQueue.setInlineCountLimit(1); + try { holder.mCallback.onQueueChanged(parcelableQueue); } catch (DeadObjectException e) {