From 0bddd06938fb5dc97a99a0cb3a444815a47be41c Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 10 Oct 2023 02:20:43 -0700 Subject: [PATCH] Make BundleListRetriever local Binder aware When used within the same process, we don't have to go via the onTransact method (which includes marshalling and unmarhsalling the data), but can directly return the list. #minor-release PiperOrigin-RevId: 572179846 --- .../media3/common/BundleListRetriever.java | 13 ++++++-- .../common/BundleListRetrieverTest.java | 32 +++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/BundleListRetriever.java b/libraries/common/src/main/java/androidx/media3/common/BundleListRetriever.java index 7825127ac0..2e8ba90dc9 100644 --- a/libraries/common/src/main/java/androidx/media3/common/BundleListRetriever.java +++ b/libraries/common/src/main/java/androidx/media3/common/BundleListRetriever.java @@ -23,6 +23,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import com.google.common.collect.ImmutableList; @@ -97,11 +98,18 @@ public final class BundleListRetriever extends Binder { * @return The list of {@link Bundle Bundles}. */ public static ImmutableList getList(IBinder binder) { - ImmutableList.Builder builder = ImmutableList.builder(); + if (binder instanceof BundleListRetriever) { + // In-process binder calls can return the list directly instead of using the transact method. + return ((BundleListRetriever) binder).list; + } + return getListFromRemoteBinder(binder); + } + @VisibleForTesting + /* package-private */ static ImmutableList getListFromRemoteBinder(IBinder binder) { + ImmutableList.Builder builder = ImmutableList.builder(); int index = 0; int replyCode = REPLY_CONTINUE; - while (replyCode != REPLY_END_OF_LIST) { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -121,7 +129,6 @@ public final class BundleListRetriever extends Binder { data.recycle(); } } - return builder.build(); } } diff --git a/libraries/common/src/test/java/androidx/media3/common/BundleListRetrieverTest.java b/libraries/common/src/test/java/androidx/media3/common/BundleListRetrieverTest.java index 0eada2f765..6f348f6c79 100644 --- a/libraries/common/src/test/java/androidx/media3/common/BundleListRetrieverTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/BundleListRetrieverTest.java @@ -15,11 +15,12 @@ */ package androidx.media3.common; +import static com.google.common.truth.Truth.assertThat; + import android.os.Bundle; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.truth.os.BundleSubject; -import java.util.ArrayList; -import java.util.List; +import com.google.common.collect.ImmutableList; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,16 +29,35 @@ import org.junit.runner.RunWith; public class BundleListRetrieverTest { @Test - public void getList_preservedLargeList() { + public void getList_inProcess_returnsOriginalImmutableList() { int count = 100_000; - List listBefore = new ArrayList<>(); + ImmutableList.Builder listBuilder = ImmutableList.builder(); for (int i = 0; i < count; i++) { Bundle bundle = new Bundle(); bundle.putInt("i", i); - listBefore.add(bundle); + listBuilder.add(bundle); } + ImmutableList listBefore = listBuilder.build(); - List listAfter = BundleListRetriever.getList(new BundleListRetriever(listBefore)); + ImmutableList listAfter = + BundleListRetriever.getList(new BundleListRetriever(listBefore)); + + assertThat(listAfter).isSameInstanceAs(listBefore); + } + + @Test + public void getList_fromRemoteBinder_preservedLargeList() { + int count = 100_000; + ImmutableList.Builder listBuilder = ImmutableList.builder(); + for (int i = 0; i < count; i++) { + Bundle bundle = new Bundle(); + bundle.putInt("i", i); + listBuilder.add(bundle); + } + ImmutableList listBefore = listBuilder.build(); + + ImmutableList listAfter = + BundleListRetriever.getListFromRemoteBinder(new BundleListRetriever(listBefore)); for (int i = 0; i < count; i++) { Bundle bundle = listAfter.get(i);