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
This commit is contained in:
tonihei 2023-10-10 02:20:43 -07:00 committed by Copybara-Service
parent fe7c62afe0
commit 0bddd06938
2 changed files with 36 additions and 9 deletions

View File

@ -23,6 +23,7 @@ import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -97,11 +98,18 @@ public final class BundleListRetriever extends Binder {
* @return The list of {@link Bundle Bundles}. * @return The list of {@link Bundle Bundles}.
*/ */
public static ImmutableList<Bundle> getList(IBinder binder) { public static ImmutableList<Bundle> getList(IBinder binder) {
ImmutableList.Builder<Bundle> 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<Bundle> getListFromRemoteBinder(IBinder binder) {
ImmutableList.Builder<Bundle> builder = ImmutableList.builder();
int index = 0; int index = 0;
int replyCode = REPLY_CONTINUE; int replyCode = REPLY_CONTINUE;
while (replyCode != REPLY_END_OF_LIST) { while (replyCode != REPLY_END_OF_LIST) {
Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain(); Parcel reply = Parcel.obtain();
@ -121,7 +129,6 @@ public final class BundleListRetriever extends Binder {
data.recycle(); data.recycle();
} }
} }
return builder.build(); return builder.build();
} }
} }

View File

@ -15,11 +15,12 @@
*/ */
package androidx.media3.common; package androidx.media3.common;
import static com.google.common.truth.Truth.assertThat;
import android.os.Bundle; import android.os.Bundle;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.ext.truth.os.BundleSubject; import androidx.test.ext.truth.os.BundleSubject;
import java.util.ArrayList; import com.google.common.collect.ImmutableList;
import java.util.List;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -28,16 +29,35 @@ import org.junit.runner.RunWith;
public class BundleListRetrieverTest { public class BundleListRetrieverTest {
@Test @Test
public void getList_preservedLargeList() { public void getList_inProcess_returnsOriginalImmutableList() {
int count = 100_000; int count = 100_000;
List<Bundle> listBefore = new ArrayList<>(); ImmutableList.Builder<Bundle> listBuilder = ImmutableList.builder();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt("i", i); bundle.putInt("i", i);
listBefore.add(bundle); listBuilder.add(bundle);
}
ImmutableList<Bundle> listBefore = listBuilder.build();
ImmutableList<Bundle> listAfter =
BundleListRetriever.getList(new BundleListRetriever(listBefore));
assertThat(listAfter).isSameInstanceAs(listBefore);
} }
List<Bundle> listAfter = BundleListRetriever.getList(new BundleListRetriever(listBefore)); @Test
public void getList_fromRemoteBinder_preservedLargeList() {
int count = 100_000;
ImmutableList.Builder<Bundle> listBuilder = ImmutableList.builder();
for (int i = 0; i < count; i++) {
Bundle bundle = new Bundle();
bundle.putInt("i", i);
listBuilder.add(bundle);
}
ImmutableList<Bundle> listBefore = listBuilder.build();
ImmutableList<Bundle> listAfter =
BundleListRetriever.getListFromRemoteBinder(new BundleListRetriever(listBefore));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Bundle bundle = listAfter.get(i); Bundle bundle = listAfter.get(i);