Skip to content

Commit cbd2208

Browse files
committed
Make MediaControllerImplBase local binder aware
The session->controller data flow already nicely avoids bundling if we don't have to bundle by skipping the entire PlayerInfo object which contains almost everything. But in the controller->session data flow, some complex objects (MediaMetadata, MediaItem and TrackSelectionParameters) were always bundled even if we don't have to. This change skips bundling for these object and should improve performance significantly when sending large lists of MediaItems to a session in the same process.
1 parent ec6ac47 commit cbd2208

File tree

8 files changed

+244
-62
lines changed

8 files changed

+244
-62
lines changed

‎libraries/common/src/main/java/androidx/media3/common/MediaItem.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222
import static androidx.media3.common.util.Util.usToMs;
2323

2424
import android.net.Uri;
25+
import android.os.Binder;
2526
import android.os.Bundle;
27+
import android.os.IBinder;
2628
import androidx.annotation.IntRange;
2729
import androidx.annotation.Nullable;
30+
import androidx.annotation.RestrictTo;
2831
import androidx.annotation.VisibleForTesting;
2932
import androidx.media3.common.util.Assertions;
3033
import androidx.media3.common.util.BundleCollectionUtil;
@@ -2394,6 +2397,7 @@ public int hashCode() {
23942397
private static final String FIELD_CLIPPING_PROPERTIES = Util.intToStringMaxRadix(3);
23952398
private static final String FIELD_REQUEST_METADATA = Util.intToStringMaxRadix(4);
23962399
private static final String FIELD_LOCAL_CONFIGURATION = Util.intToStringMaxRadix(5);
2400+
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(6);
23972401

23982402
@UnstableApi
23992403
private Bundle toBundle(boolean includeLocalConfiguration) {
@@ -2439,6 +2443,17 @@ public Bundle toBundleIncludeLocalConfiguration() {
24392443
return toBundle(/* includeLocalConfiguration= */ true);
24402444
}
24412445

2446+
/**
2447+
* Returns a {@link Bundle} containing the entirety of this {@link #MediaItem} object without
2448+
* bundling it, for use in local process communication only.
2449+
*/
2450+
@UnstableApi
2451+
public Bundle toBundleIncludeLocalConfigurationForLocalProcess() {
2452+
Bundle bundle = new Bundle();
2453+
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
2454+
return bundle;
2455+
}
2456+
24422457
/**
24432458
* Restores a {@code MediaItem} from a {@link Bundle}.
24442459
*
@@ -2447,6 +2462,10 @@ public Bundle toBundleIncludeLocalConfiguration() {
24472462
@UnstableApi
24482463
@SuppressWarnings("deprecation") // Unbundling to ClippingProperties while it still exists.
24492464
public static MediaItem fromBundle(Bundle bundle) {
2465+
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
2466+
if (inProcessBinder instanceof InProcessBinder) {
2467+
return ((InProcessBinder) inProcessBinder).getMediaItem();
2468+
}
24502469
String mediaId = checkNotNull(bundle.getString(FIELD_MEDIA_ID, DEFAULT_MEDIA_ID));
24512470
@Nullable Bundle liveConfigurationBundle = bundle.getBundle(FIELD_LIVE_CONFIGURATION);
24522471
LiveConfiguration liveConfiguration;
@@ -2491,4 +2510,24 @@ public static MediaItem fromBundle(Bundle bundle) {
24912510
mediaMetadata,
24922511
requestMetadata);
24932512
}
2513+
2514+
private final class InProcessBinder extends Binder {
2515+
public MediaItem getMediaItem() {
2516+
return MediaItem.this;
2517+
}
2518+
}
2519+
2520+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
2521+
@UnstableApi
2522+
public static final class ListInProcessBinder extends Binder {
2523+
private final ImmutableList<MediaItem> theList;
2524+
2525+
public ListInProcessBinder(List<MediaItem> theList) {
2526+
this.theList = ImmutableList.copyOf(theList);
2527+
}
2528+
2529+
public ImmutableList<MediaItem> getMediaItemList() {
2530+
return theList;
2531+
}
2532+
}
24942533
}

‎libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import static java.lang.annotation.ElementType.TYPE_USE;
2424

2525
import android.net.Uri;
26+
import android.os.Binder;
2627
import android.os.Bundle;
28+
import android.os.IBinder;
2729
import androidx.annotation.IntDef;
2830
import androidx.annotation.IntRange;
2931
import androidx.annotation.Nullable;
@@ -1334,6 +1336,7 @@ public int hashCode() {
13341336
private static final String FIELD_IS_BROWSABLE = Util.intToStringMaxRadix(32);
13351337
private static final String FIELD_DURATION_MS = Util.intToStringMaxRadix(33);
13361338
private static final String FIELD_SUPPORTED_COMMANDS = Util.intToStringMaxRadix(34);
1339+
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(35);
13371340
private static final String FIELD_EXTRAS = Util.intToStringMaxRadix(1000);
13381341

13391342
@SuppressWarnings("deprecation") // Bundling deprecated fields.
@@ -1448,10 +1451,25 @@ public Bundle toBundle() {
14481451
return bundle;
14491452
}
14501453

1454+
/**
1455+
* Returns a {@link Bundle} containing the entirety of this {@link #MediaMetadata} object without
1456+
* bundling it, for use in local process communication only.
1457+
*/
1458+
@UnstableApi
1459+
public Bundle toBundleForLocalProcess() {
1460+
Bundle bundle = new Bundle();
1461+
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
1462+
return bundle;
1463+
}
1464+
14511465
/** Restores a {@code MediaMetadata} from a {@link Bundle}. */
14521466
@UnstableApi
14531467
@SuppressWarnings("deprecation") // Unbundling deprecated fields.
14541468
public static MediaMetadata fromBundle(Bundle bundle) {
1469+
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
1470+
if (inProcessBinder instanceof InProcessBinder) {
1471+
return ((InProcessBinder) inProcessBinder).getMediaMetadata();
1472+
}
14551473
Builder builder = new Builder();
14561474
builder
14571475
.setTitle(bundle.getCharSequence(FIELD_TITLE))
@@ -1612,4 +1630,10 @@ public static MediaMetadata fromBundle(Bundle bundle) {
16121630
return MEDIA_TYPE_FOLDER_MIXED;
16131631
}
16141632
}
1633+
1634+
private final class InProcessBinder extends Binder {
1635+
public MediaMetadata getMediaMetadata() {
1636+
return MediaMetadata.this;
1637+
}
1638+
}
16151639
}

‎libraries/common/src/main/java/androidx/media3/common/TrackSelectionParameters.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
import static java.lang.annotation.RetentionPolicy.SOURCE;
2323

2424
import android.content.Context;
25+
import android.os.Binder;
2526
import android.os.Bundle;
27+
import android.os.IBinder;
2628
import android.view.accessibility.CaptioningManager;
2729
import androidx.annotation.CallSuper;
2830
import androidx.annotation.IntDef;
@@ -1597,6 +1599,7 @@ public int hashCode() {
15971599
private static final String FIELD_PREFERRED_VIDEO_LABELS = Util.intToStringMaxRadix(36);
15981600
private static final String FIELD_PREFERRED_AUDIO_LABELS = Util.intToStringMaxRadix(37);
15991601
private static final String FIELD_PREFERRED_TEXT_LABELS = Util.intToStringMaxRadix(38);
1602+
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(39);
16001603

16011604
/**
16021605
* Defines a minimum field ID value for subclasses to use when implementing {@link #toBundle()}
@@ -1675,8 +1678,29 @@ public Bundle toBundle() {
16751678
return bundle;
16761679
}
16771680

1681+
/**
1682+
* Returns a {@link Bundle} containing the entirety of this {@link #TrackSelectionParameters}
1683+
* object without bundling it, for use in local process communication only.
1684+
*/
1685+
@UnstableApi
1686+
public Bundle toBundleForLocalProcess() {
1687+
Bundle bundle = new Bundle();
1688+
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
1689+
return bundle;
1690+
}
1691+
16781692
/** Construct an instance from a {@link Bundle} produced by {@link #toBundle()}. */
16791693
public static TrackSelectionParameters fromBundle(Bundle bundle) {
1694+
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
1695+
if (inProcessBinder instanceof InProcessBinder) {
1696+
return ((InProcessBinder) inProcessBinder).getTrackSelectionParameters();
1697+
}
16801698
return new Builder(bundle).build();
16811699
}
1700+
1701+
private final class InProcessBinder extends Binder {
1702+
public TrackSelectionParameters getTrackSelectionParameters() {
1703+
return TrackSelectionParameters.this;
1704+
}
1705+
}
16821706
}

‎libraries/common/src/test/java/androidx/media3/common/MediaItemTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,15 @@ public void buildUpon_wholeObjectSetters_equalsToOriginal() {
10211021
assertThat(copy).isEqualTo(mediaItem);
10221022
}
10231023

1024+
@Test
1025+
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
1026+
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
1027+
MediaItem unbundledItem =
1028+
MediaItem.fromBundle(mediaItem.toBundleIncludeLocalConfigurationForLocalProcess());
1029+
1030+
assertThat(mediaItem == unbundledItem).isTrue();
1031+
}
1032+
10241033
@Test
10251034
public void roundTripViaBundle_withoutLocalConfiguration_yieldsEqualInstance() {
10261035
MediaItem mediaItem =

‎libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ public void roundTripViaBundle_withJustNonNullExtras_restoresAllData() {
180180
assertThat(restoredMetadata.extras.get("key")).isEqualTo("value");
181181
}
182182

183+
@Test
184+
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
185+
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setGenre("hi").build();
186+
MediaMetadata unbundledMetadata =
187+
MediaMetadata.fromBundle(mediaMetadata.toBundleForLocalProcess());
188+
189+
assertThat(mediaMetadata == unbundledMetadata).isTrue();
190+
}
191+
183192
@SuppressWarnings("deprecation") // Testing deprecated setter.
184193
@Test
185194
public void builderSetFolderType_toNone_setsIsBrowsableToFalse() {

‎libraries/common/src/test/java/androidx/media3/common/TrackSelectionParametersTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,16 @@ public void roundTripViaBundle_withOverride_yieldsEqualInstance() {
239239
.containsExactly(override.mediaTrackGroup, override);
240240
}
241241

242+
@Test
243+
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
244+
TrackSelectionParameters parameters =
245+
new TrackSelectionParameters.Builder().setMaxVideoSizeSd().build();
246+
TrackSelectionParameters unbundledParameters =
247+
TrackSelectionParameters.fromBundle(parameters.toBundleForLocalProcess());
248+
249+
assertThat(parameters == unbundledParameters).isTrue();
250+
}
251+
242252
@Test
243253
public void roundTripViaBundle_withLegacyPreferenceFields_yieldsEqualInstance() {
244254
TrackSelectionParameters trackSelectionParameters =

0 commit comments

Comments
 (0)