Skip to content

Make MediaControllerImplBase local binder aware #2642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
import static androidx.media3.common.util.Util.usToMs;

import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BundleCollectionUtil;
Expand Down Expand Up @@ -2394,6 +2397,7 @@ public int hashCode() {
private static final String FIELD_CLIPPING_PROPERTIES = Util.intToStringMaxRadix(3);
private static final String FIELD_REQUEST_METADATA = Util.intToStringMaxRadix(4);
private static final String FIELD_LOCAL_CONFIGURATION = Util.intToStringMaxRadix(5);
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(6);

@UnstableApi
private Bundle toBundle(boolean includeLocalConfiguration) {
Expand Down Expand Up @@ -2439,6 +2443,17 @@ public Bundle toBundleIncludeLocalConfiguration() {
return toBundle(/* includeLocalConfiguration= */ true);
}

/**
* Returns a {@link Bundle} containing the entirety of this {@link #MediaItem} object without
* bundling it, for use in local process communication only.
*/
@UnstableApi
public Bundle toBundleIncludeLocalConfigurationForLocalProcess() {
Bundle bundle = new Bundle();
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}

/**
* Restores a {@code MediaItem} from a {@link Bundle}.
*
Expand All @@ -2447,6 +2462,10 @@ public Bundle toBundleIncludeLocalConfiguration() {
@UnstableApi
@SuppressWarnings("deprecation") // Unbundling to ClippingProperties while it still exists.
public static MediaItem fromBundle(Bundle bundle) {
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getMediaItem();
}
String mediaId = checkNotNull(bundle.getString(FIELD_MEDIA_ID, DEFAULT_MEDIA_ID));
@Nullable Bundle liveConfigurationBundle = bundle.getBundle(FIELD_LIVE_CONFIGURATION);
LiveConfiguration liveConfiguration;
Expand Down Expand Up @@ -2491,4 +2510,24 @@ public static MediaItem fromBundle(Bundle bundle) {
mediaMetadata,
requestMetadata);
}

private final class InProcessBinder extends Binder {
public MediaItem getMediaItem() {
return MediaItem.this;
}
}

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@UnstableApi
public static final class ListInProcessBinder extends Binder {
private final ImmutableList<MediaItem> theList;

public ListInProcessBinder(List<MediaItem> theList) {
this.theList = ImmutableList.copyOf(theList);
}

public ImmutableList<MediaItem> getMediaItemList() {
return theList;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import static java.lang.annotation.ElementType.TYPE_USE;

import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -1334,6 +1336,7 @@ public int hashCode() {
private static final String FIELD_IS_BROWSABLE = Util.intToStringMaxRadix(32);
private static final String FIELD_DURATION_MS = Util.intToStringMaxRadix(33);
private static final String FIELD_SUPPORTED_COMMANDS = Util.intToStringMaxRadix(34);
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(35);
private static final String FIELD_EXTRAS = Util.intToStringMaxRadix(1000);

@SuppressWarnings("deprecation") // Bundling deprecated fields.
Expand Down Expand Up @@ -1448,10 +1451,25 @@ public Bundle toBundle() {
return bundle;
}

/**
* Returns a {@link Bundle} containing the entirety of this {@link #MediaMetadata} object without
* bundling it, for use in local process communication only.
*/
@UnstableApi
public Bundle toBundleForLocalProcess() {
Bundle bundle = new Bundle();
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}

/** Restores a {@code MediaMetadata} from a {@link Bundle}. */
@UnstableApi
@SuppressWarnings("deprecation") // Unbundling deprecated fields.
public static MediaMetadata fromBundle(Bundle bundle) {
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getMediaMetadata();
}
Builder builder = new Builder();
builder
.setTitle(bundle.getCharSequence(FIELD_TITLE))
Expand Down Expand Up @@ -1612,4 +1630,10 @@ public static MediaMetadata fromBundle(Bundle bundle) {
return MEDIA_TYPE_FOLDER_MIXED;
}
}

private final class InProcessBinder extends Binder {
public MediaMetadata getMediaMetadata() {
return MediaMetadata.this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.view.accessibility.CaptioningManager;
import androidx.annotation.CallSuper;
import androidx.annotation.IntDef;
Expand Down Expand Up @@ -1597,6 +1599,7 @@ public int hashCode() {
private static final String FIELD_PREFERRED_VIDEO_LABELS = Util.intToStringMaxRadix(36);
private static final String FIELD_PREFERRED_AUDIO_LABELS = Util.intToStringMaxRadix(37);
private static final String FIELD_PREFERRED_TEXT_LABELS = Util.intToStringMaxRadix(38);
private static final String FIELD_IN_PROCESS_BINDER = Util.intToStringMaxRadix(39);

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

/**
* Returns a {@link Bundle} containing the entirety of this {@link #TrackSelectionParameters}
* object without bundling it, for use in local process communication only.
*/
@UnstableApi
public Bundle toBundleForLocalProcess() {
Bundle bundle = new Bundle();
bundle.putBinder(FIELD_IN_PROCESS_BINDER, new InProcessBinder());
return bundle;
}

/** Construct an instance from a {@link Bundle} produced by {@link #toBundle()}. */
public static TrackSelectionParameters fromBundle(Bundle bundle) {
IBinder inProcessBinder = bundle.getBinder(FIELD_IN_PROCESS_BINDER);
if (inProcessBinder instanceof InProcessBinder) {
return ((InProcessBinder) inProcessBinder).getTrackSelectionParameters();
}
return new Builder(bundle).build();
}

private final class InProcessBinder extends Binder {
public TrackSelectionParameters getTrackSelectionParameters() {
return TrackSelectionParameters.this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,15 @@ public void buildUpon_wholeObjectSetters_equalsToOriginal() {
assertThat(copy).isEqualTo(mediaItem);
}

@Test
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
MediaItem unbundledItem =
MediaItem.fromBundle(mediaItem.toBundleIncludeLocalConfigurationForLocalProcess());

assertThat(mediaItem == unbundledItem).isTrue();
}

@Test
public void roundTripViaBundle_withoutLocalConfiguration_yieldsEqualInstance() {
MediaItem mediaItem =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ public void roundTripViaBundle_withJustNonNullExtras_restoresAllData() {
assertThat(restoredMetadata.extras.get("key")).isEqualTo("value");
}

@Test
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setGenre("hi").build();
MediaMetadata unbundledMetadata =
MediaMetadata.fromBundle(mediaMetadata.toBundleForLocalProcess());

assertThat(mediaMetadata == unbundledMetadata).isTrue();
}

@SuppressWarnings("deprecation") // Testing deprecated setter.
@Test
public void builderSetFolderType_toNone_setsIsBrowsableToFalse() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ public void roundTripViaBundle_withOverride_yieldsEqualInstance() {
.containsExactly(override.mediaTrackGroup, override);
}

@Test
public void roundTripViaBundleForLocalProcess_yieldsSameInstance() {
TrackSelectionParameters parameters =
new TrackSelectionParameters.Builder().setMaxVideoSizeSd().build();
TrackSelectionParameters unbundledParameters =
TrackSelectionParameters.fromBundle(parameters.toBundleForLocalProcess());

assertThat(parameters == unbundledParameters).isTrue();
}

@Test
public void roundTripViaBundle_withLegacyPreferenceFields_yieldsEqualInstance() {
TrackSelectionParameters trackSelectionParameters =
Expand Down
Loading