Remove all null-tolerant methods from BundleableUtil.

In most cases it's clearer to in-line these null-checks with ternary
operators.

PiperOrigin-RevId: 449474621
This commit is contained in:
ibaker 2022-05-18 15:12:53 +01:00 committed by Ian Baker
parent 1a171a004a
commit 7c235d2b84
25 changed files with 270 additions and 276 deletions

View File

@ -1548,7 +1548,9 @@ public final class Format implements Bundleable {
bundle.putFloat(keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), pixelWidthHeightRatio); bundle.putFloat(keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), pixelWidthHeightRatio);
bundle.putByteArray(keyForField(FIELD_PROJECTION_DATA), projectionData); bundle.putByteArray(keyForField(FIELD_PROJECTION_DATA), projectionData);
bundle.putInt(keyForField(FIELD_STEREO_MODE), stereoMode); bundle.putInt(keyForField(FIELD_STEREO_MODE), stereoMode);
bundle.putBundle(keyForField(FIELD_COLOR_INFO), BundleableUtil.toNullableBundle(colorInfo)); if (colorInfo != null) {
bundle.putBundle(keyForField(FIELD_COLOR_INFO), colorInfo.toBundle());
}
// Audio specific. // Audio specific.
bundle.putInt(keyForField(FIELD_CHANNEL_COUNT), channelCount); bundle.putInt(keyForField(FIELD_CHANNEL_COUNT), channelCount);
bundle.putInt(keyForField(FIELD_SAMPLE_RATE), sampleRate); bundle.putInt(keyForField(FIELD_SAMPLE_RATE), sampleRate);
@ -1615,11 +1617,13 @@ public final class Format implements Bundleable {
bundle.getFloat( bundle.getFloat(
keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), DEFAULT.pixelWidthHeightRatio)) keyForField(FIELD_PIXEL_WIDTH_HEIGHT_RATIO), DEFAULT.pixelWidthHeightRatio))
.setProjectionData(bundle.getByteArray(keyForField(FIELD_PROJECTION_DATA))) .setProjectionData(bundle.getByteArray(keyForField(FIELD_PROJECTION_DATA)))
.setStereoMode(bundle.getInt(keyForField(FIELD_STEREO_MODE), DEFAULT.stereoMode)) .setStereoMode(bundle.getInt(keyForField(FIELD_STEREO_MODE), DEFAULT.stereoMode));
.setColorInfo( Bundle colorInfoBundle = bundle.getBundle(keyForField(FIELD_COLOR_INFO));
BundleableUtil.fromNullableBundle( if (colorInfoBundle != null) {
ColorInfo.CREATOR, bundle.getBundle(keyForField(FIELD_COLOR_INFO)))) builder.setColorInfo(ColorInfo.CREATOR.fromBundle(colorInfoBundle));
}
// Audio specific. // Audio specific.
builder
.setChannelCount(bundle.getInt(keyForField(FIELD_CHANNEL_COUNT), DEFAULT.channelCount)) .setChannelCount(bundle.getInt(keyForField(FIELD_CHANNEL_COUNT), DEFAULT.channelCount))
.setSampleRate(bundle.getInt(keyForField(FIELD_SAMPLE_RATE), DEFAULT.sampleRate)) .setSampleRate(bundle.getInt(keyForField(FIELD_SAMPLE_RATE), DEFAULT.sampleRate))
.setPcmEncoding(bundle.getInt(keyForField(FIELD_PCM_ENCODING), DEFAULT.pcmEncoding)) .setPcmEncoding(bundle.getInt(keyForField(FIELD_PCM_ENCODING), DEFAULT.pcmEncoding))

View File

@ -33,7 +33,6 @@ import androidx.annotation.IntRange;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.text.Cue; import androidx.media3.common.text.Cue;
import androidx.media3.common.text.CueGroup; import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.BundleableUtil;
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.base.Objects; import com.google.common.base.Objects;
@ -295,7 +294,9 @@ public interface Player {
public Bundle toBundle() { public Bundle toBundle() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(keyForField(FIELD_MEDIA_ITEM_INDEX), mediaItemIndex); bundle.putInt(keyForField(FIELD_MEDIA_ITEM_INDEX), mediaItemIndex);
bundle.putBundle(keyForField(FIELD_MEDIA_ITEM), BundleableUtil.toNullableBundle(mediaItem)); if (mediaItem != null) {
bundle.putBundle(keyForField(FIELD_MEDIA_ITEM), mediaItem.toBundle());
}
bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex); bundle.putInt(keyForField(FIELD_PERIOD_INDEX), periodIndex);
bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs); bundle.putLong(keyForField(FIELD_POSITION_MS), positionMs);
bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs); bundle.putLong(keyForField(FIELD_CONTENT_POSITION_MS), contentPositionMs);
@ -310,10 +311,10 @@ public interface Player {
private static PositionInfo fromBundle(Bundle bundle) { private static PositionInfo fromBundle(Bundle bundle) {
int mediaItemIndex = int mediaItemIndex =
bundle.getInt(keyForField(FIELD_MEDIA_ITEM_INDEX), /* defaultValue= */ C.INDEX_UNSET); bundle.getInt(keyForField(FIELD_MEDIA_ITEM_INDEX), /* defaultValue= */ C.INDEX_UNSET);
@Nullable Bundle mediaItemBundle = bundle.getBundle(keyForField(FIELD_MEDIA_ITEM));
@Nullable @Nullable
MediaItem mediaItem = MediaItem mediaItem =
BundleableUtil.fromNullableBundle( mediaItemBundle == null ? null : MediaItem.CREATOR.fromBundle(mediaItemBundle);
MediaItem.CREATOR, bundle.getBundle(keyForField(FIELD_MEDIA_ITEM)));
int periodIndex = int periodIndex =
bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET); bundle.getInt(keyForField(FIELD_PERIOD_INDEX), /* defaultValue= */ C.INDEX_UNSET);
long positionMs = long positionMs =

View File

@ -189,11 +189,12 @@ public final class TrackGroup implements Bundleable {
@UnstableApi @UnstableApi
public static final Creator<TrackGroup> CREATOR = public static final Creator<TrackGroup> CREATOR =
bundle -> { bundle -> {
@Nullable
List<Bundle> formatBundles = bundle.getParcelableArrayList(keyForField(FIELD_FORMATS));
List<Format> formats = List<Format> formats =
BundleableUtil.fromBundleNullableList( formatBundles == null
Format.CREATOR, ? ImmutableList.of()
bundle.getParcelableArrayList(keyForField(FIELD_FORMATS)), : BundleableUtil.fromBundleList(Format.CREATOR, formatBundles);
ImmutableList.of());
String id = bundle.getString(keyForField(FIELD_ID), /* defaultValue= */ ""); String id = bundle.getString(keyForField(FIELD_ID), /* defaultValue= */ "");
return new TrackGroup(id, formats.toArray(new Format[0])); return new TrackGroup(id, formats.toArray(new Format[0]));
}; };

View File

@ -16,7 +16,6 @@
package androidx.media3.common; package androidx.media3.common;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.BundleableUtil.fromBundleNullableList;
import static androidx.media3.common.util.BundleableUtil.toBundleArrayList; import static androidx.media3.common.util.BundleableUtil.toBundleArrayList;
import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.MoreObjects.firstNonNull;
@ -28,6 +27,7 @@ import android.view.accessibility.CaptioningManager;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.media3.common.util.BundleableUtil;
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;
@ -247,11 +247,13 @@ public class TrackSelectionParameters implements Bundleable {
bundle.getBoolean( bundle.getBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
@Nullable
List<Bundle> overrideBundleList =
bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES));
List<TrackSelectionOverride> overrideList = List<TrackSelectionOverride> overrideList =
fromBundleNullableList( overrideBundleList == null
TrackSelectionOverride.CREATOR, ? ImmutableList.of()
bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDES)), : BundleableUtil.fromBundleList(TrackSelectionOverride.CREATOR, overrideBundleList);
ImmutableList.of());
overrides = new HashMap<>(); overrides = new HashMap<>();
for (int i = 0; i < overrideList.size(); i++) { for (int i = 0; i < overrideList.size(); i++) {
TrackSelectionOverride override = overrideList.get(i); TrackSelectionOverride override = overrideList.get(i);

View File

@ -17,14 +17,13 @@ package androidx.media3.common;
import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.BundleableUtil.fromBundleNullableList;
import static androidx.media3.common.util.BundleableUtil.fromNullableBundle;
import static androidx.media3.common.util.BundleableUtil.toBundleArrayList; import static androidx.media3.common.util.BundleableUtil.toBundleArrayList;
import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.ElementType.TYPE_USE;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -252,10 +251,10 @@ public final class Tracks implements Bundleable {
@UnstableApi @UnstableApi
public static final Creator<Group> CREATOR = public static final Creator<Group> CREATOR =
bundle -> { bundle -> {
// Can't create a Tracks.Group without a TrackGroup
TrackGroup trackGroup = TrackGroup trackGroup =
fromNullableBundle( TrackGroup.CREATOR.fromBundle(
TrackGroup.CREATOR, bundle.getBundle(keyForField(FIELD_TRACK_GROUP))); checkNotNull(bundle.getBundle(keyForField(FIELD_TRACK_GROUP))));
checkNotNull(trackGroup); // Can't create a trackGroup info without a trackGroup
final @C.FormatSupport int[] trackSupport = final @C.FormatSupport int[] trackSupport =
MoreObjects.firstNonNull( MoreObjects.firstNonNull(
bundle.getIntArray(keyForField(FIELD_TRACK_SUPPORT)), new int[trackGroup.length]); bundle.getIntArray(keyForField(FIELD_TRACK_SUPPORT)), new int[trackGroup.length]);
@ -408,11 +407,12 @@ public final class Tracks implements Bundleable {
@UnstableApi @UnstableApi
public static final Creator<Tracks> CREATOR = public static final Creator<Tracks> CREATOR =
bundle -> { bundle -> {
@Nullable
List<Bundle> groupBundles = bundle.getParcelableArrayList(keyForField(FIELD_TRACK_GROUPS));
List<Group> groups = List<Group> groups =
fromBundleNullableList( groupBundles == null
Group.CREATOR, ? ImmutableList.of()
bundle.getParcelableArrayList(keyForField(FIELD_TRACK_GROUPS)), : BundleableUtil.fromBundleList(Group.CREATOR, groupBundles);
/* defaultValue= */ ImmutableList.of());
return new Tracks(groups); return new Tracks(groups);
}; };

View File

@ -20,6 +20,7 @@ import static java.lang.annotation.ElementType.TYPE_USE;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.Bundleable; import androidx.media3.common.Bundleable;
import androidx.media3.common.util.BundleableUtil; import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
@ -28,6 +29,7 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** Class to represent the state of active {@link Cue Cues} at a particular time. */ /** Class to represent the state of active {@link Cue Cues} at a particular time. */
@ -74,11 +76,11 @@ public final class CueGroup implements Bundleable {
@UnstableApi public static final Creator<CueGroup> CREATOR = CueGroup::fromBundle; @UnstableApi public static final Creator<CueGroup> CREATOR = CueGroup::fromBundle;
private static final CueGroup fromBundle(Bundle bundle) { private static final CueGroup fromBundle(Bundle bundle) {
@Nullable ArrayList<Bundle> cueBundles = bundle.getParcelableArrayList(keyForField(FIELD_CUES));
List<Cue> cues = List<Cue> cues =
BundleableUtil.fromBundleNullableList( cueBundles == null
Cue.CREATOR, ? ImmutableList.of()
bundle.getParcelableArrayList(keyForField(FIELD_CUES)), : BundleableUtil.fromBundleList(Cue.CREATOR, cueBundles);
/* defaultValue= */ ImmutableList.of());
return new CueGroup(cues); return new CueGroup(cues);
} }

View File

@ -31,34 +31,6 @@ import java.util.List;
@UnstableApi @UnstableApi
public final class BundleableUtil { public final class BundleableUtil {
/**
* Converts a {@link Bundleable} to a {@link Bundle}. It's a convenience wrapper of {@link
* Bundleable#toBundle} that can take nullable values.
*/
@Nullable
public static Bundle toNullableBundle(@Nullable Bundleable bundleable) {
return bundleable == null ? null : bundleable.toBundle();
}
/**
* Converts a {@link Bundle} to a {@link Bundleable}. It's a convenience wrapper of {@link
* Bundleable.Creator#fromBundle} that can take nullable values.
*/
@Nullable
public static <T extends Bundleable> T fromNullableBundle(
Bundleable.Creator<T> creator, @Nullable Bundle bundle) {
return bundle == null ? null : creator.fromBundle(bundle);
}
/**
* Converts a {@link Bundle} to a {@link Bundleable}. It's a convenience wrapper of {@link
* Bundleable.Creator#fromBundle} that provides default value to ensure non-null.
*/
public static <T extends Bundleable> T fromNullableBundle(
Bundleable.Creator<T> creator, @Nullable Bundle bundle, T defaultValue) {
return bundle == null ? defaultValue : creator.fromBundle(bundle);
}
/** Converts a list of {@link Bundleable} to a list {@link Bundle}. */ /** Converts a list of {@link Bundleable} to a list {@link Bundle}. */
public static <T extends Bundleable> ImmutableList<Bundle> toBundleList(List<T> bundleableList) { public static <T extends Bundleable> ImmutableList<Bundle> toBundleList(List<T> bundleableList) {
ImmutableList.Builder<Bundle> builder = ImmutableList.builder(); ImmutableList.Builder<Bundle> builder = ImmutableList.builder();
@ -81,34 +53,6 @@ public final class BundleableUtil {
return builder.build(); return builder.build();
} }
/**
* Converts a list of {@link Bundle} to a list of {@link Bundleable}. Returns {@code defaultValue}
* if {@code bundleList} is null.
*/
public static <T extends Bundleable> List<T> fromBundleNullableList(
Bundleable.Creator<T> creator, @Nullable List<Bundle> bundleList, List<T> defaultValue) {
return (bundleList == null) ? defaultValue : fromBundleList(creator, bundleList);
}
/**
* Converts a {@link SparseArray} of {@link Bundle} to a {@link SparseArray} of {@link
* Bundleable}. Returns {@code defaultValue} if {@code bundleSparseArray} is null.
*/
public static <T extends Bundleable> SparseArray<T> fromBundleNullableSparseArray(
Bundleable.Creator<T> creator,
@Nullable SparseArray<Bundle> bundleSparseArray,
SparseArray<T> defaultValue) {
if (bundleSparseArray == null) {
return defaultValue;
}
// Can't use ImmutableList as it doesn't support null elements.
SparseArray<T> result = new SparseArray<>(bundleSparseArray.size());
for (int i = 0; i < bundleSparseArray.size(); i++) {
result.put(bundleSparseArray.keyAt(i), creator.fromBundle(bundleSparseArray.valueAt(i)));
}
return result;
}
/** /**
* Converts a collection of {@link Bundleable} to an {@link ArrayList} of {@link Bundle} so that * Converts a collection of {@link Bundleable} to an {@link ArrayList} of {@link Bundle} so that
* the returned list can be put to {@link Bundle} using {@link Bundle#putParcelableArrayList} * the returned list can be put to {@link Bundle} using {@link Bundle#putParcelableArrayList}
@ -123,6 +67,19 @@ public final class BundleableUtil {
return arrayList; return arrayList;
} }
/**
* Converts a {@link SparseArray} of {@link Bundle} to a {@link SparseArray} of {@link
* Bundleable}.
*/
public static <T extends Bundleable> SparseArray<T> fromBundleSparseArray(
Bundleable.Creator<T> creator, SparseArray<Bundle> bundleSparseArray) {
SparseArray<T> result = new SparseArray<>(bundleSparseArray.size());
for (int i = 0; i < bundleSparseArray.size(); i++) {
result.put(bundleSparseArray.keyAt(i), creator.fromBundle(bundleSparseArray.valueAt(i)));
}
return result;
}
/** /**
* Converts a {@link SparseArray} of {@link Bundleable} to an {@link SparseArray} of {@link * Converts a {@link SparseArray} of {@link Bundleable} to an {@link SparseArray} of {@link
* Bundle} so that the returned {@link SparseArray} can be put to {@link Bundle} using {@link * Bundle} so that the returned {@link SparseArray} can be put to {@link Bundle} using {@link

View File

@ -33,7 +33,6 @@ import androidx.media3.common.Format;
import androidx.media3.common.MediaPeriodId; import androidx.media3.common.MediaPeriodId;
import androidx.media3.common.PlaybackException; import androidx.media3.common.PlaybackException;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BundleableUtil;
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 androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.MediaSource;
@ -255,9 +254,9 @@ public final class ExoPlaybackException extends PlaybackException {
rendererName = bundle.getString(keyForField(FIELD_RENDERER_NAME)); rendererName = bundle.getString(keyForField(FIELD_RENDERER_NAME));
rendererIndex = rendererIndex =
bundle.getInt(keyForField(FIELD_RENDERER_INDEX), /* defaultValue= */ C.INDEX_UNSET); bundle.getInt(keyForField(FIELD_RENDERER_INDEX), /* defaultValue= */ C.INDEX_UNSET);
@Nullable Bundle rendererFormatBundle = bundle.getBundle(keyForField(FIELD_RENDERER_FORMAT));
rendererFormat = rendererFormat =
BundleableUtil.fromNullableBundle( rendererFormatBundle == null ? null : Format.CREATOR.fromBundle(rendererFormatBundle);
Format.CREATOR, bundle.getBundle(keyForField(FIELD_RENDERER_FORMAT)));
rendererFormatSupport = rendererFormatSupport =
bundle.getInt( bundle.getInt(
keyForField(FIELD_RENDERER_FORMAT_SUPPORT), /* defaultValue= */ C.FORMAT_HANDLED); keyForField(FIELD_RENDERER_FORMAT_SUPPORT), /* defaultValue= */ C.FORMAT_HANDLED);
@ -424,8 +423,9 @@ public final class ExoPlaybackException extends PlaybackException {
bundle.putInt(keyForField(FIELD_TYPE), type); bundle.putInt(keyForField(FIELD_TYPE), type);
bundle.putString(keyForField(FIELD_RENDERER_NAME), rendererName); bundle.putString(keyForField(FIELD_RENDERER_NAME), rendererName);
bundle.putInt(keyForField(FIELD_RENDERER_INDEX), rendererIndex); bundle.putInt(keyForField(FIELD_RENDERER_INDEX), rendererIndex);
bundle.putBundle( if (rendererFormat != null) {
keyForField(FIELD_RENDERER_FORMAT), BundleableUtil.toNullableBundle(rendererFormat)); bundle.putBundle(keyForField(FIELD_RENDERER_FORMAT), rendererFormat.toBundle());
}
bundle.putInt(keyForField(FIELD_RENDERER_FORMAT_SUPPORT), rendererFormatSupport); bundle.putInt(keyForField(FIELD_RENDERER_FORMAT_SUPPORT), rendererFormatSupport);
bundle.putBoolean(keyForField(FIELD_IS_RECOVERABLE), isRecoverable); bundle.putBoolean(keyForField(FIELD_IS_RECOVERABLE), isRecoverable);
return bundle; return bundle;

View File

@ -139,12 +139,15 @@ public final class TrackGroupArray implements Bundleable {
/** Object that can restores a TrackGroupArray from a {@link Bundle}. */ /** Object that can restores a TrackGroupArray from a {@link Bundle}. */
public static final Creator<TrackGroupArray> CREATOR = public static final Creator<TrackGroupArray> CREATOR =
bundle -> { bundle -> {
List<TrackGroup> trackGroups = @Nullable
BundleableUtil.fromBundleNullableList( List<Bundle> trackGroupBundles =
TrackGroup.CREATOR, bundle.getParcelableArrayList(keyForField(FIELD_TRACK_GROUPS));
bundle.getParcelableArrayList(keyForField(FIELD_TRACK_GROUPS)), if (trackGroupBundles == null) {
/* defaultValue= */ ImmutableList.of()); return new TrackGroupArray();
return new TrackGroupArray(trackGroups.toArray(new TrackGroup[0])); }
return new TrackGroupArray(
BundleableUtil.fromBundleList(TrackGroup.CREATOR, trackGroupBundles)
.toArray(new TrackGroup[0]));
}; };
private void verifyCorrectness() { private void verifyCorrectness() {

View File

@ -843,18 +843,23 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int[] rendererIndices = int[] rendererIndices =
bundle.getIntArray( bundle.getIntArray(
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_RENDERER_INDICES)); Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_RENDERER_INDICES));
List<TrackGroupArray> trackGroupArrays = @Nullable
BundleableUtil.fromBundleNullableList( ArrayList<Bundle> trackGroupArrayBundles =
TrackGroupArray.CREATOR,
bundle.getParcelableArrayList( bundle.getParcelableArrayList(
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS)), Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES_TRACK_GROUP_ARRAYS));
/* defaultValue= */ ImmutableList.of()); List<TrackGroupArray> trackGroupArrays =
SparseArray<SelectionOverride> selectionOverrides = trackGroupArrayBundles == null
BundleableUtil.fromBundleNullableSparseArray( ? ImmutableList.of()
SelectionOverride.CREATOR, : BundleableUtil.fromBundleList(TrackGroupArray.CREATOR, trackGroupArrayBundles);
@Nullable
SparseArray<Bundle> selectionOverrideBundles =
bundle.getSparseParcelableArray( bundle.getSparseParcelableArray(
Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES)), Parameters.keyForField(Parameters.FIELD_SELECTION_OVERRIDES));
/* defaultValue= */ new SparseArray<>()); SparseArray<SelectionOverride> selectionOverrides =
selectionOverrideBundles == null
? new SparseArray<>()
: BundleableUtil.fromBundleSparseArray(
SelectionOverride.CREATOR, selectionOverrideBundles);
if (rendererIndices == null || rendererIndices.length != trackGroupArrays.size()) { if (rendererIndices == null || rendererIndices.length != trackGroupArrays.size()) {
return; // Incorrect format, ignore all overrides. return; // Incorrect format, ignore all overrides.

View File

@ -25,7 +25,6 @@ import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.Bundleable; import androidx.media3.common.Bundleable;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -219,8 +218,9 @@ public final class CommandButton implements Bundleable {
@Override @Override
public Bundle toBundle() { public Bundle toBundle() {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putBundle( if (sessionCommand != null) {
keyForField(FIELD_SESSION_COMMAND), BundleableUtil.toNullableBundle(sessionCommand)); bundle.putBundle(keyForField(FIELD_SESSION_COMMAND), sessionCommand.toBundle());
}
bundle.putInt(keyForField(FIELD_PLAYER_COMMAND), playerCommand); bundle.putInt(keyForField(FIELD_PLAYER_COMMAND), playerCommand);
bundle.putInt(keyForField(FIELD_ICON_RES_ID), iconResId); bundle.putInt(keyForField(FIELD_ICON_RES_ID), iconResId);
bundle.putCharSequence(keyForField(FIELD_DISPLAY_NAME), displayName); bundle.putCharSequence(keyForField(FIELD_DISPLAY_NAME), displayName);
@ -233,10 +233,12 @@ public final class CommandButton implements Bundleable {
@UnstableApi public static final Creator<CommandButton> CREATOR = CommandButton::fromBundle; @UnstableApi public static final Creator<CommandButton> CREATOR = CommandButton::fromBundle;
private static CommandButton fromBundle(Bundle bundle) { private static CommandButton fromBundle(Bundle bundle) {
@Nullable Bundle sessionCommandBundle = bundle.getBundle(keyForField(FIELD_SESSION_COMMAND));
@Nullable @Nullable
SessionCommand sessionCommand = SessionCommand sessionCommand =
BundleableUtil.fromNullableBundle( sessionCommandBundle == null
SessionCommand.CREATOR, bundle.getBundle(keyForField(FIELD_SESSION_COMMAND))); ? null
: SessionCommand.CREATOR.fromBundle(sessionCommandBundle);
@Player.Command @Player.Command
int playerCommand = int playerCommand =
bundle.getInt( bundle.getInt(

View File

@ -26,7 +26,6 @@ import androidx.annotation.Nullable;
import androidx.core.app.BundleCompat; import androidx.core.app.BundleCompat;
import androidx.media3.common.Bundleable; import androidx.media3.common.Bundleable;
import androidx.media3.common.Player; import androidx.media3.common.Player;
import androidx.media3.common.util.BundleableUtil;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -135,27 +134,31 @@ import java.lang.annotation.Target;
checkNotNull(BundleCompat.getBinder(bundle, keyForField(FIELD_SESSION_BINDER))); checkNotNull(BundleCompat.getBinder(bundle, keyForField(FIELD_SESSION_BINDER)));
@Nullable @Nullable
PendingIntent sessionActivity = bundle.getParcelable(keyForField(FIELD_SESSION_ACTIVITY)); PendingIntent sessionActivity = bundle.getParcelable(keyForField(FIELD_SESSION_ACTIVITY));
@Nullable Bundle sessionCommandsBundle = bundle.getBundle(keyForField(FIELD_SESSION_COMMANDS));
SessionCommands sessionCommands = SessionCommands sessionCommands =
BundleableUtil.fromNullableBundle( sessionCommandsBundle == null
SessionCommands.CREATOR, ? SessionCommands.EMPTY
bundle.getBundle(keyForField(FIELD_SESSION_COMMANDS)), : SessionCommands.CREATOR.fromBundle(sessionCommandsBundle);
SessionCommands.EMPTY); @Nullable
Bundle playerCommandsFromPlayerBundle =
bundle.getBundle(keyForField(FIELD_PLAYER_COMMANDS_FROM_PLAYER));
Player.Commands playerCommandsFromPlayer = Player.Commands playerCommandsFromPlayer =
BundleableUtil.fromNullableBundle( playerCommandsFromPlayerBundle == null
Player.Commands.CREATOR, ? Player.Commands.EMPTY
bundle.getBundle(keyForField(FIELD_PLAYER_COMMANDS_FROM_PLAYER)), : Player.Commands.CREATOR.fromBundle(playerCommandsFromPlayerBundle);
Player.Commands.EMPTY); @Nullable
Bundle playerCommandsFromSessionBundle =
bundle.getBundle(keyForField(FIELD_PLAYER_COMMANDS_FROM_SESSION));
Player.Commands playerCommandsFromSession = Player.Commands playerCommandsFromSession =
BundleableUtil.fromNullableBundle( playerCommandsFromSessionBundle == null
Player.Commands.CREATOR, ? Player.Commands.EMPTY
bundle.getBundle(keyForField(FIELD_PLAYER_COMMANDS_FROM_SESSION)), : Player.Commands.CREATOR.fromBundle(playerCommandsFromSessionBundle);
Player.Commands.EMPTY);
@Nullable Bundle tokenExtras = bundle.getBundle(keyForField(FIELD_TOKEN_EXTRAS)); @Nullable Bundle tokenExtras = bundle.getBundle(keyForField(FIELD_TOKEN_EXTRAS));
@Nullable Bundle playerInfoBundle = bundle.getBundle(keyForField(FIELD_PLAYER_INFO));
PlayerInfo playerInfo = PlayerInfo playerInfo =
BundleableUtil.fromNullableBundle( playerInfoBundle == null
PlayerInfo.CREATOR, ? PlayerInfo.DEFAULT
bundle.getBundle(keyForField(FIELD_PLAYER_INFO)), : PlayerInfo.CREATOR.fromBundle(playerInfoBundle);
PlayerInfo.DEFAULT);
return new ConnectionState( return new ConnectionState(
version, version,
IMediaSession.Stub.asInterface(sessionBinder), IMediaSession.Stub.asInterface(sessionBinder),

View File

@ -287,7 +287,9 @@ public final class LibraryResult<V> implements Bundleable {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(keyForField(FIELD_RESULT_CODE), resultCode); bundle.putInt(keyForField(FIELD_RESULT_CODE), resultCode);
bundle.putLong(keyForField(FIELD_COMPLETION_TIME_MS), completionTimeMs); bundle.putLong(keyForField(FIELD_COMPLETION_TIME_MS), completionTimeMs);
bundle.putBundle(keyForField(FIELD_PARAMS), BundleableUtil.toNullableBundle(params)); if (params != null) {
bundle.putBundle(keyForField(FIELD_PARAMS), params.toBundle());
}
bundle.putInt(keyForField(FIELD_VALUE_TYPE), valueType); bundle.putInt(keyForField(FIELD_VALUE_TYPE), valueType);
if (value == null) { if (value == null) {
@ -295,8 +297,7 @@ public final class LibraryResult<V> implements Bundleable {
} }
switch (valueType) { switch (valueType) {
case VALUE_TYPE_ITEM: case VALUE_TYPE_ITEM:
bundle.putBundle( bundle.putBundle(keyForField(FIELD_VALUE), ((MediaItem) value).toBundle());
keyForField(FIELD_VALUE), BundleableUtil.toNullableBundle((MediaItem) value));
break; break;
case VALUE_TYPE_ITEM_LIST: case VALUE_TYPE_ITEM_LIST:
BundleCompat.putBinder( BundleCompat.putBinder(
@ -371,18 +372,17 @@ public final class LibraryResult<V> implements Bundleable {
bundle.getLong( bundle.getLong(
keyForField(FIELD_COMPLETION_TIME_MS), keyForField(FIELD_COMPLETION_TIME_MS),
/* defaultValue= */ SystemClock.elapsedRealtime()); /* defaultValue= */ SystemClock.elapsedRealtime());
@Nullable Bundle paramsBundle = bundle.getBundle(keyForField(FIELD_PARAMS));
@Nullable @Nullable
MediaLibraryService.LibraryParams params = MediaLibraryService.LibraryParams params =
BundleableUtil.fromNullableBundle( paramsBundle == null ? null : LibraryParams.CREATOR.fromBundle(paramsBundle);
MediaLibraryService.LibraryParams.CREATOR, bundle.getBundle(keyForField(FIELD_PARAMS)));
@ValueType int valueType = bundle.getInt(keyForField(FIELD_VALUE_TYPE)); @ValueType int valueType = bundle.getInt(keyForField(FIELD_VALUE_TYPE));
@Nullable Object value; @Nullable Object value;
switch (valueType) { switch (valueType) {
case VALUE_TYPE_ITEM: case VALUE_TYPE_ITEM:
checkState(expectedType == null || expectedType == VALUE_TYPE_ITEM); checkState(expectedType == null || expectedType == VALUE_TYPE_ITEM);
value = @Nullable Bundle valueBundle = bundle.getBundle(keyForField(FIELD_VALUE));
BundleableUtil.fromNullableBundle( value = valueBundle == null ? null : MediaItem.CREATOR.fromBundle(valueBundle);
MediaItem.CREATOR, bundle.getBundle(keyForField(FIELD_VALUE)));
break; break;
case VALUE_TYPE_ITEM_LIST: case VALUE_TYPE_ITEM_LIST:
checkState(expectedType == null || expectedType == VALUE_TYPE_ITEM_LIST); checkState(expectedType == null || expectedType == VALUE_TYPE_ITEM_LIST);

View File

@ -31,7 +31,6 @@ import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.session.MediaLibraryService.LibraryParams; import androidx.media3.session.MediaLibraryService.LibraryParams;
import androidx.media3.session.SequencedFutureManager.SequencedFuture; import androidx.media3.session.SequencedFutureManager.SequencedFuture;
@ -59,7 +58,7 @@ import com.google.common.util.concurrent.ListenableFuture;
new RemoteLibrarySessionTask() { new RemoteLibrarySessionTask() {
@Override @Override
public void run(IMediaSession iSession, int seq) throws RemoteException { public void run(IMediaSession iSession, int seq) throws RemoteException {
iSession.getLibraryRoot(controllerStub, seq, BundleableUtil.toNullableBundle(params)); iSession.getLibraryRoot(controllerStub, seq, params == null ? null : params.toBundle());
} }
}); });
} }
@ -73,7 +72,7 @@ import com.google.common.util.concurrent.ListenableFuture;
@Override @Override
public void run(IMediaSession iSession, int seq) throws RemoteException { public void run(IMediaSession iSession, int seq) throws RemoteException {
iSession.subscribe( iSession.subscribe(
controllerStub, seq, parentId, BundleableUtil.toNullableBundle(params)); controllerStub, seq, parentId, params == null ? null : params.toBundle());
} }
}); });
} }
@ -104,7 +103,7 @@ import com.google.common.util.concurrent.ListenableFuture;
parentId, parentId,
page, page,
pageSize, pageSize,
BundleableUtil.toNullableBundle(params)); params == null ? null : params.toBundle());
} }
}); });
} }
@ -129,7 +128,7 @@ import com.google.common.util.concurrent.ListenableFuture;
new RemoteLibrarySessionTask() { new RemoteLibrarySessionTask() {
@Override @Override
public void run(IMediaSession iSession, int seq) throws RemoteException { public void run(IMediaSession iSession, int seq) throws RemoteException {
iSession.search(controllerStub, seq, query, BundleableUtil.toNullableBundle(params)); iSession.search(controllerStub, seq, query, params == null ? null : params.toBundle());
} }
}); });
} }
@ -148,7 +147,7 @@ import com.google.common.util.concurrent.ListenableFuture;
query, query,
page, page,
pageSize, pageSize,
BundleableUtil.toNullableBundle(params)); params == null ? null : params.toBundle());
} }
}); });
} }

View File

@ -209,7 +209,9 @@ import java.util.List;
browser.notifySearchResultChanged( browser.notifySearchResultChanged(
query, query,
itemCount, itemCount,
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParams))); libraryParams == null
? null
: LibraryParams.CREATOR.fromBundle(libraryParams)));
} }
@Override @Override
@ -229,7 +231,9 @@ import java.util.List;
browser.notifyChildrenChanged( browser.notifyChildrenChanged(
parentId, parentId,
itemCount, itemCount,
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParams))); libraryParams == null
? null
: LibraryParams.CREATOR.fromBundle(libraryParams)));
} }
public void destroy() { public void destroy() {

View File

@ -1521,7 +1521,7 @@ import java.util.concurrent.ExecutionException;
} }
@Nullable @Nullable
LibraryParams libraryParams = LibraryParams libraryParams =
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParamsBundle); libraryParamsBundle == null ? null : LibraryParams.CREATOR.fromBundle(libraryParamsBundle);
dispatchSessionTaskWithLibrarySessionCommand( dispatchSessionTaskWithLibrarySessionCommand(
caller, caller,
seq, seq,
@ -1576,7 +1576,7 @@ import java.util.concurrent.ExecutionException;
} }
@Nullable @Nullable
LibraryParams libraryParams = LibraryParams libraryParams =
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParamsBundle); libraryParamsBundle == null ? null : LibraryParams.CREATOR.fromBundle(libraryParamsBundle);
dispatchSessionTaskWithLibrarySessionCommand( dispatchSessionTaskWithLibrarySessionCommand(
caller, caller,
seq, seq,
@ -1602,7 +1602,7 @@ import java.util.concurrent.ExecutionException;
} }
@Nullable @Nullable
LibraryParams libraryParams = LibraryParams libraryParams =
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParamsBundle); libraryParamsBundle == null ? null : LibraryParams.CREATOR.fromBundle(libraryParamsBundle);
dispatchSessionTaskWithLibrarySessionCommand( dispatchSessionTaskWithLibrarySessionCommand(
caller, caller,
seq, seq,
@ -1637,7 +1637,7 @@ import java.util.concurrent.ExecutionException;
} }
@Nullable @Nullable
LibraryParams libraryParams = LibraryParams libraryParams =
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParamsBundle); libraryParamsBundle == null ? null : LibraryParams.CREATOR.fromBundle(libraryParamsBundle);
dispatchSessionTaskWithLibrarySessionCommand( dispatchSessionTaskWithLibrarySessionCommand(
caller, caller,
seq, seq,
@ -1663,7 +1663,7 @@ import java.util.concurrent.ExecutionException;
} }
@Nullable @Nullable
LibraryParams libraryParams = LibraryParams libraryParams =
BundleableUtil.fromNullableBundle(LibraryParams.CREATOR, libraryParamsBundle); libraryParamsBundle == null ? null : LibraryParams.CREATOR.fromBundle(libraryParamsBundle);
dispatchSessionTaskWithLibrarySessionCommand( dispatchSessionTaskWithLibrarySessionCommand(
caller, caller,
seq, seq,
@ -1769,7 +1769,7 @@ import java.util.concurrent.ExecutionException;
int seq, String parentId, int itemCount, @Nullable LibraryParams params) int seq, String parentId, int itemCount, @Nullable LibraryParams params)
throws RemoteException { throws RemoteException {
iController.onChildrenChanged( iController.onChildrenChanged(
seq, parentId, itemCount, BundleableUtil.toNullableBundle(params)); seq, parentId, itemCount, params == null ? null : params.toBundle());
} }
@SuppressWarnings("nullness:argument") // params can be null. @SuppressWarnings("nullness:argument") // params can be null.
@ -1778,7 +1778,7 @@ import java.util.concurrent.ExecutionException;
int seq, String query, int itemCount, @Nullable LibraryParams params) int seq, String query, int itemCount, @Nullable LibraryParams params)
throws RemoteException { throws RemoteException {
iController.onSearchResultChanged( iController.onSearchResultChanged(
seq, query, itemCount, BundleableUtil.toNullableBundle(params)); seq, query, itemCount, params == null ? null : params.toBundle());
} }
@Override @Override

View File

@ -29,7 +29,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationBuilderWithBuilderAccessor; import androidx.core.app.NotificationBuilderWithBuilderAccessor;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
@ -97,8 +96,10 @@ public class MediaStyleNotificationHelper {
if (extras == null) { if (extras == null) {
return null; return null;
} }
return BundleableUtil.fromNullableBundle( Bundle sessionTokenBundle = extras.getBundle(EXTRA_MEDIA3_SESSION);
SessionToken.CREATOR, extras.getBundle(EXTRA_MEDIA3_SESSION)); return sessionTokenBundle == null
? null
: SessionToken.CREATOR.fromBundle(sessionTokenBundle);
} }
private static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3; private static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;

View File

@ -45,7 +45,6 @@ import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.VideoSize; import androidx.media3.common.VideoSize;
import androidx.media3.common.text.CueGroup; import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.BundleableUtil;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -733,14 +732,13 @@ import java.lang.annotation.Target;
boolean excludeCues, boolean excludeCues,
boolean excludeTimeline) { boolean excludeTimeline) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putBundle( if (playerError != null) {
keyForField(FIELD_PLAYBACK_ERROR), BundleableUtil.toNullableBundle(playerError)); bundle.putBundle(keyForField(FIELD_PLAYBACK_ERROR), playerError.toBundle());
}
bundle.putInt(keyForField(FIELD_MEDIA_ITEM_TRANSITION_REASON), mediaItemTransitionReason); bundle.putInt(keyForField(FIELD_MEDIA_ITEM_TRANSITION_REASON), mediaItemTransitionReason);
bundle.putBundle(keyForField(FIELD_SESSION_POSITION_INFO), sessionPositionInfo.toBundle()); bundle.putBundle(keyForField(FIELD_SESSION_POSITION_INFO), sessionPositionInfo.toBundle());
bundle.putBundle( bundle.putBundle(keyForField(FIELD_OLD_POSITION_INFO), oldPositionInfo.toBundle());
keyForField(FIELD_OLD_POSITION_INFO), BundleableUtil.toNullableBundle(oldPositionInfo)); bundle.putBundle(keyForField(FIELD_NEW_POSITION_INFO), newPositionInfo.toBundle());
bundle.putBundle(
keyForField(FIELD_NEW_POSITION_INFO), BundleableUtil.toNullableBundle(newPositionInfo));
bundle.putInt(keyForField(FIELD_DISCONTINUITY_REASON), discontinuityReason); bundle.putInt(keyForField(FIELD_DISCONTINUITY_REASON), discontinuityReason);
bundle.putBundle(keyForField(FIELD_PLAYBACK_PARAMETERS), playbackParameters.toBundle()); bundle.putBundle(keyForField(FIELD_PLAYBACK_PARAMETERS), playbackParameters.toBundle());
bundle.putInt(keyForField(FIELD_REPEAT_MODE), repeatMode); bundle.putInt(keyForField(FIELD_REPEAT_MODE), repeatMode);
@ -749,11 +747,9 @@ import java.lang.annotation.Target;
bundle.putBundle(keyForField(FIELD_TIMELINE), timeline.toBundle(excludeMediaItems)); bundle.putBundle(keyForField(FIELD_TIMELINE), timeline.toBundle(excludeMediaItems));
} }
bundle.putBundle(keyForField(FIELD_VIDEO_SIZE), videoSize.toBundle()); bundle.putBundle(keyForField(FIELD_VIDEO_SIZE), videoSize.toBundle());
bundle.putBundle( if (!excludeMediaItemsMetadata) {
keyForField(FIELD_PLAYLIST_METADATA), bundle.putBundle(keyForField(FIELD_PLAYLIST_METADATA), playlistMetadata.toBundle());
excludeMediaItemsMetadata }
? MediaMetadata.EMPTY.toBundle()
: BundleableUtil.toNullableBundle(playlistMetadata));
bundle.putFloat(keyForField(FIELD_VOLUME), volume); bundle.putFloat(keyForField(FIELD_VOLUME), volume);
bundle.putBundle(keyForField(FIELD_AUDIO_ATTRIBUTES), audioAttributes.toBundle()); bundle.putBundle(keyForField(FIELD_AUDIO_ATTRIBUTES), audioAttributes.toBundle());
if (!excludeCues) { if (!excludeCues) {
@ -793,67 +789,69 @@ import java.lang.annotation.Target;
public static final Creator<PlayerInfo> CREATOR = PlayerInfo::fromBundle; public static final Creator<PlayerInfo> CREATOR = PlayerInfo::fromBundle;
private static PlayerInfo fromBundle(Bundle bundle) { private static PlayerInfo fromBundle(Bundle bundle) {
@Nullable Bundle playerErrorBundle = bundle.getBundle(keyForField(FIELD_PLAYBACK_ERROR));
@Nullable @Nullable
PlaybackException playerError = PlaybackException playerError =
BundleableUtil.fromNullableBundle( playerErrorBundle == null ? null : PlaybackException.CREATOR.fromBundle(playerErrorBundle);
PlaybackException.CREATOR, bundle.getBundle(keyForField(FIELD_PLAYBACK_ERROR)));
int mediaItemTransitionReason = int mediaItemTransitionReason =
bundle.getInt( bundle.getInt(
keyForField(FIELD_MEDIA_ITEM_TRANSITION_REASON), MEDIA_ITEM_TRANSITION_REASON_REPEAT); keyForField(FIELD_MEDIA_ITEM_TRANSITION_REASON), MEDIA_ITEM_TRANSITION_REASON_REPEAT);
@Nullable
Bundle sessionPositionInfoBundle = bundle.getBundle(keyForField(FIELD_SESSION_POSITION_INFO));
SessionPositionInfo sessionPositionInfo = SessionPositionInfo sessionPositionInfo =
BundleableUtil.fromNullableBundle( sessionPositionInfoBundle == null
SessionPositionInfo.CREATOR, ? SessionPositionInfo.DEFAULT
bundle.getBundle(keyForField(FIELD_SESSION_POSITION_INFO)), : SessionPositionInfo.CREATOR.fromBundle(sessionPositionInfoBundle);
SessionPositionInfo.DEFAULT); @Nullable Bundle oldPositionInfoBundle = bundle.getBundle(keyForField(FIELD_OLD_POSITION_INFO));
PositionInfo oldPositionInfo = PositionInfo oldPositionInfo =
BundleableUtil.fromNullableBundle( oldPositionInfoBundle == null
PositionInfo.CREATOR, ? SessionPositionInfo.DEFAULT_POSITION_INFO
bundle.getBundle(keyForField(FIELD_OLD_POSITION_INFO)), : PositionInfo.CREATOR.fromBundle(oldPositionInfoBundle);
SessionPositionInfo.DEFAULT_POSITION_INFO); @Nullable Bundle newPositionInfoBundle = bundle.getBundle(keyForField(FIELD_NEW_POSITION_INFO));
PositionInfo newPositionInfo = PositionInfo newPositionInfo =
BundleableUtil.fromNullableBundle( newPositionInfoBundle == null
PositionInfo.CREATOR, ? SessionPositionInfo.DEFAULT_POSITION_INFO
bundle.getBundle(keyForField(FIELD_NEW_POSITION_INFO)), : PositionInfo.CREATOR.fromBundle(newPositionInfoBundle);
SessionPositionInfo.DEFAULT_POSITION_INFO);
int discontinuityReason = int discontinuityReason =
bundle.getInt( bundle.getInt(
keyForField(FIELD_DISCONTINUITY_REASON), DISCONTINUITY_REASON_AUTO_TRANSITION); keyForField(FIELD_DISCONTINUITY_REASON), DISCONTINUITY_REASON_AUTO_TRANSITION);
@Nullable @Nullable
Bundle playbackParametersBundle = bundle.getBundle(keyForField(FIELD_PLAYBACK_PARAMETERS)); Bundle playbackParametersBundle = bundle.getBundle(keyForField(FIELD_PLAYBACK_PARAMETERS));
PlaybackParameters playbackParameters = PlaybackParameters playbackParameters =
BundleableUtil.fromNullableBundle( playbackParametersBundle == null
PlaybackParameters.CREATOR, ? PlaybackParameters.DEFAULT
playbackParametersBundle, : PlaybackParameters.CREATOR.fromBundle(playbackParametersBundle);
/* defaultValue= */ PlaybackParameters.DEFAULT);
@Player.RepeatMode @Player.RepeatMode
int repeatMode = int repeatMode =
bundle.getInt(keyForField(FIELD_REPEAT_MODE), /* defaultValue= */ Player.REPEAT_MODE_OFF); bundle.getInt(keyForField(FIELD_REPEAT_MODE), /* defaultValue= */ Player.REPEAT_MODE_OFF);
boolean shuffleModeEnabled = boolean shuffleModeEnabled =
bundle.getBoolean(keyForField(FIELD_SHUFFLE_MODE_ENABLED), /* defaultValue= */ false); bundle.getBoolean(keyForField(FIELD_SHUFFLE_MODE_ENABLED), /* defaultValue= */ false);
@Nullable Bundle timelineBundle = bundle.getBundle(keyForField(FIELD_TIMELINE));
Timeline timeline = Timeline timeline =
BundleableUtil.fromNullableBundle( timelineBundle == null ? Timeline.EMPTY : Timeline.CREATOR.fromBundle(timelineBundle);
Timeline.CREATOR, bundle.getBundle(keyForField(FIELD_TIMELINE)), Timeline.EMPTY); @Nullable Bundle videoSizeBundle = bundle.getBundle(keyForField(FIELD_VIDEO_SIZE));
VideoSize videoSize = VideoSize videoSize =
BundleableUtil.fromNullableBundle( videoSizeBundle == null ? VideoSize.UNKNOWN : VideoSize.CREATOR.fromBundle(videoSizeBundle);
VideoSize.CREATOR, bundle.getBundle(keyForField(FIELD_VIDEO_SIZE)), VideoSize.UNKNOWN); @Nullable
Bundle playlistMetadataBundle = bundle.getBundle(keyForField(FIELD_PLAYLIST_METADATA));
MediaMetadata playlistMetadata = MediaMetadata playlistMetadata =
BundleableUtil.fromNullableBundle( playlistMetadataBundle == null
MediaMetadata.CREATOR, ? MediaMetadata.EMPTY
bundle.getBundle(keyForField(FIELD_PLAYLIST_METADATA)), : MediaMetadata.CREATOR.fromBundle(playlistMetadataBundle);
MediaMetadata.EMPTY);
float volume = bundle.getFloat(keyForField(FIELD_VOLUME), /* defaultValue= */ 1); float volume = bundle.getFloat(keyForField(FIELD_VOLUME), /* defaultValue= */ 1);
@Nullable Bundle audioAttributesBundle = bundle.getBundle(keyForField(FIELD_AUDIO_ATTRIBUTES));
AudioAttributes audioAttributes = AudioAttributes audioAttributes =
BundleableUtil.fromNullableBundle( audioAttributesBundle == null
AudioAttributes.CREATOR, ? AudioAttributes.DEFAULT
bundle.getBundle(keyForField(FIELD_AUDIO_ATTRIBUTES)), : AudioAttributes.CREATOR.fromBundle(audioAttributesBundle);
/* defaultValue= */ AudioAttributes.DEFAULT); @Nullable Bundle cueGroupBundle = bundle.getBundle(keyForField(FIELD_CUE_GROUP));
CueGroup cueGroup = CueGroup cueGroup =
BundleableUtil.fromNullableBundle( cueGroupBundle == null ? CueGroup.EMPTY : CueGroup.CREATOR.fromBundle(cueGroupBundle);
CueGroup.CREATOR, bundle.getBundle(keyForField(FIELD_CUE_GROUP)), CueGroup.EMPTY);
@Nullable Bundle deviceInfoBundle = bundle.getBundle(keyForField(FIELD_DEVICE_INFO)); @Nullable Bundle deviceInfoBundle = bundle.getBundle(keyForField(FIELD_DEVICE_INFO));
DeviceInfo deviceInfo = DeviceInfo deviceInfo =
BundleableUtil.fromNullableBundle( deviceInfoBundle == null
DeviceInfo.CREATOR, deviceInfoBundle, /* defaultValue= */ DeviceInfo.UNKNOWN); ? DeviceInfo.UNKNOWN
: DeviceInfo.CREATOR.fromBundle(deviceInfoBundle);
int deviceVolume = bundle.getInt(keyForField(FIELD_DEVICE_VOLUME), /* defaultValue= */ 0); int deviceVolume = bundle.getInt(keyForField(FIELD_DEVICE_VOLUME), /* defaultValue= */ 0);
boolean deviceMuted = boolean deviceMuted =
bundle.getBoolean(keyForField(FIELD_DEVICE_MUTED), /* defaultValue= */ false); bundle.getBoolean(keyForField(FIELD_DEVICE_MUTED), /* defaultValue= */ false);
@ -873,11 +871,11 @@ import java.lang.annotation.Target;
bundle.getInt(keyForField(FIELD_PLAYBACK_STATE), /* defaultValue= */ STATE_IDLE); bundle.getInt(keyForField(FIELD_PLAYBACK_STATE), /* defaultValue= */ STATE_IDLE);
boolean isPlaying = bundle.getBoolean(keyForField(FIELD_IS_PLAYING), /* defaultValue= */ false); boolean isPlaying = bundle.getBoolean(keyForField(FIELD_IS_PLAYING), /* defaultValue= */ false);
boolean isLoading = bundle.getBoolean(keyForField(FIELD_IS_LOADING), /* defaultValue= */ false); boolean isLoading = bundle.getBoolean(keyForField(FIELD_IS_LOADING), /* defaultValue= */ false);
@Nullable Bundle mediaMetadataBundle = bundle.getBundle(keyForField(FIELD_MEDIA_METADATA));
MediaMetadata mediaMetadata = MediaMetadata mediaMetadata =
BundleableUtil.fromNullableBundle( mediaMetadataBundle == null
MediaMetadata.CREATOR, ? MediaMetadata.EMPTY
bundle.getBundle(keyForField(FIELD_MEDIA_METADATA)), : MediaMetadata.CREATOR.fromBundle(mediaMetadataBundle);
MediaMetadata.EMPTY);
long seekBackIncrementMs = long seekBackIncrementMs =
bundle.getLong(keyForField(FIELD_SEEK_BACK_INCREMENT_MS), /* defaultValue= */ 0); bundle.getLong(keyForField(FIELD_SEEK_BACK_INCREMENT_MS), /* defaultValue= */ 0);
long seekForwardIncrementMs = long seekForwardIncrementMs =

View File

@ -23,7 +23,6 @@ import androidx.annotation.Nullable;
import androidx.media3.common.Bundleable; import androidx.media3.common.Bundleable;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.Player.PositionInfo; import androidx.media3.common.Player.PositionInfo;
import androidx.media3.common.util.BundleableUtil;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@ -209,11 +208,11 @@ import java.lang.annotation.Target;
public static final Creator<SessionPositionInfo> CREATOR = SessionPositionInfo::fromBundle; public static final Creator<SessionPositionInfo> CREATOR = SessionPositionInfo::fromBundle;
private static SessionPositionInfo fromBundle(Bundle bundle) { private static SessionPositionInfo fromBundle(Bundle bundle) {
@Nullable Bundle positionInfoBundle = bundle.getBundle(keyForField(FIELD_POSITION_INFO));
PositionInfo positionInfo = PositionInfo positionInfo =
BundleableUtil.fromNullableBundle( positionInfoBundle == null
PositionInfo.CREATOR, ? DEFAULT_POSITION_INFO
bundle.getBundle(keyForField(FIELD_POSITION_INFO)), : PositionInfo.CREATOR.fromBundle(positionInfoBundle);
/* defaultValue= */ DEFAULT_POSITION_INFO);
boolean isPlayingAd = boolean isPlayingAd =
bundle.getBoolean(keyForField(FIELD_IS_PLAYING_AD), /* defaultValue= */ false); bundle.getBoolean(keyForField(FIELD_IS_PLAYING_AD), /* defaultValue= */ false);
long eventTimeMs = long eventTimeMs =

View File

@ -165,7 +165,9 @@ public class MediaControllerProviderService extends Service {
return runOnHandler( return runOnHandler(
() -> { () -> {
MediaController controller = mediaControllerMap.get(controllerId); MediaController controller = mediaControllerMap.get(controllerId);
return BundleableUtil.toNullableBundle(controller.getConnectedToken()); return controller.getConnectedToken() == null
? null
: controller.getConnectedToken().toBundle();
}); });
} }
@ -679,8 +681,9 @@ public class MediaControllerProviderService extends Service {
runOnHandler( runOnHandler(
() -> () ->
browser.getLibraryRoot( browser.getLibraryRoot(
BundleableUtil.fromNullableBundle( libraryParams == null
MediaLibraryService.LibraryParams.CREATOR, libraryParams))); ? null
: MediaLibraryService.LibraryParams.CREATOR.fromBundle(libraryParams)));
LibraryResult<MediaItem> result = getFutureResult(future); LibraryResult<MediaItem> result = getFutureResult(future);
return result.toBundle(); return result.toBundle();
} }
@ -694,8 +697,9 @@ public class MediaControllerProviderService extends Service {
() -> () ->
browser.subscribe( browser.subscribe(
parentId, parentId,
BundleableUtil.fromNullableBundle( libraryParams == null
MediaLibraryService.LibraryParams.CREATOR, libraryParams))); ? null
: MediaLibraryService.LibraryParams.CREATOR.fromBundle(libraryParams)));
LibraryResult<Void> result = getFutureResult(future); LibraryResult<Void> result = getFutureResult(future);
return result.toBundle(); return result.toBundle();
} }
@ -720,8 +724,9 @@ public class MediaControllerProviderService extends Service {
parentId, parentId,
page, page,
pageSize, pageSize,
BundleableUtil.fromNullableBundle( libraryParams == null
MediaLibraryService.LibraryParams.CREATOR, libraryParams))); ? null
: MediaLibraryService.LibraryParams.CREATOR.fromBundle(libraryParams)));
LibraryResult<ImmutableList<MediaItem>> result = getFutureResult(future); LibraryResult<ImmutableList<MediaItem>> result = getFutureResult(future);
return result.toBundle(); return result.toBundle();
} }
@ -743,8 +748,9 @@ public class MediaControllerProviderService extends Service {
() -> () ->
browser.search( browser.search(
query, query,
BundleableUtil.fromNullableBundle( libraryParams == null
MediaLibraryService.LibraryParams.CREATOR, libraryParams))); ? null
: MediaLibraryService.LibraryParams.CREATOR.fromBundle(libraryParams)));
LibraryResult<Void> result = getFutureResult(future); LibraryResult<Void> result = getFutureResult(future);
return result.toBundle(); return result.toBundle();
} }
@ -761,8 +767,9 @@ public class MediaControllerProviderService extends Service {
query, query,
page, page,
pageSize, pageSize,
BundleableUtil.fromNullableBundle( libraryParams == null
MediaLibraryService.LibraryParams.CREATOR, libraryParams))); ? null
: MediaLibraryService.LibraryParams.CREATOR.fromBundle(libraryParams)));
LibraryResult<ImmutableList<MediaItem>> result = getFutureResult(future); LibraryResult<ImmutableList<MediaItem>> result = getFutureResult(future);
return result.toBundle(); return result.toBundle();
} }

View File

@ -79,7 +79,6 @@ import androidx.media3.common.Timeline;
import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.VideoSize; import androidx.media3.common.VideoSize;
import androidx.media3.common.text.CueGroup; import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
@ -261,9 +260,10 @@ public class MediaSessionProviderService extends Service {
private Player createMockPlayer(Bundle config) { private Player createMockPlayer(Bundle config) {
MockPlayer player = new MockPlayer.Builder().build(); MockPlayer player = new MockPlayer.Builder().build();
player.playerError = @Nullable Bundle playerErrorBundle = config.getBundle(KEY_PLAYER_ERROR);
BundleableUtil.fromNullableBundle( if (playerErrorBundle != null) {
PlaybackException.CREATOR, config.getBundle(KEY_PLAYER_ERROR), player.playerError); player.playerError = PlaybackException.CREATOR.fromBundle(playerErrorBundle);
}
player.currentPosition = config.getLong(KEY_CURRENT_POSITION, player.currentPosition); player.currentPosition = config.getLong(KEY_CURRENT_POSITION, player.currentPosition);
player.bufferedPosition = config.getLong(KEY_BUFFERED_POSITION, player.bufferedPosition); player.bufferedPosition = config.getLong(KEY_BUFFERED_POSITION, player.bufferedPosition);
player.bufferedPercentage = config.getInt(KEY_BUFFERED_PERCENTAGE, player.bufferedPercentage); player.bufferedPercentage = config.getInt(KEY_BUFFERED_PERCENTAGE, player.bufferedPercentage);
@ -280,38 +280,38 @@ public class MediaSessionProviderService extends Service {
config.getInt(KEY_CURRENT_AD_GROUP_INDEX, player.currentAdGroupIndex); config.getInt(KEY_CURRENT_AD_GROUP_INDEX, player.currentAdGroupIndex);
player.currentAdIndexInAdGroup = player.currentAdIndexInAdGroup =
config.getInt(KEY_CURRENT_AD_INDEX_IN_AD_GROUP, player.currentAdIndexInAdGroup); config.getInt(KEY_CURRENT_AD_INDEX_IN_AD_GROUP, player.currentAdIndexInAdGroup);
player.playbackParameters = @Nullable Bundle playbackParametersBundle = config.getBundle(KEY_PLAYBACK_PARAMETERS);
BundleableUtil.fromNullableBundle( if (playbackParametersBundle != null) {
PlaybackParameters.CREATOR, player.playbackParameters = PlaybackParameters.CREATOR.fromBundle(playbackParametersBundle);
config.getBundle(KEY_PLAYBACK_PARAMETERS), }
player.playbackParameters); @Nullable Bundle timelineBundle = config.getBundle(KEY_TIMELINE);
player.timeline = if (timelineBundle != null) {
BundleableUtil.fromNullableBundle( player.timeline = Timeline.CREATOR.fromBundle(timelineBundle);
Timeline.CREATOR, config.getBundle(KEY_TIMELINE), player.timeline); }
player.currentMediaItemIndex = player.currentMediaItemIndex =
config.getInt(KEY_CURRENT_MEDIA_ITEM_INDEX, player.currentMediaItemIndex); config.getInt(KEY_CURRENT_MEDIA_ITEM_INDEX, player.currentMediaItemIndex);
player.currentPeriodIndex = player.currentPeriodIndex =
config.getInt(KEY_CURRENT_PERIOD_INDEX, player.currentPeriodIndex); config.getInt(KEY_CURRENT_PERIOD_INDEX, player.currentPeriodIndex);
player.playlistMetadata = @Nullable Bundle playlistMetadataBundle = config.getBundle(KEY_PLAYLIST_METADATA);
BundleableUtil.fromNullableBundle( if (playlistMetadataBundle != null) {
MediaMetadata.CREATOR, player.playlistMetadata = MediaMetadata.CREATOR.fromBundle(playlistMetadataBundle);
config.getBundle(KEY_PLAYLIST_METADATA), }
player.playlistMetadata); @Nullable Bundle videoSizeBundle = config.getBundle(KEY_VIDEO_SIZE);
player.videoSize = if (videoSizeBundle != null) {
BundleableUtil.fromNullableBundle( player.videoSize = VideoSize.CREATOR.fromBundle(videoSizeBundle);
VideoSize.CREATOR, config.getBundle(KEY_VIDEO_SIZE), player.videoSize); }
player.volume = config.getFloat(KEY_VOLUME, player.volume); player.volume = config.getFloat(KEY_VOLUME, player.volume);
player.audioAttributes = @Nullable Bundle audioAttributesBundle = config.getBundle(KEY_AUDIO_ATTRIBUTES);
BundleableUtil.fromNullableBundle( if (audioAttributesBundle != null) {
AudioAttributes.CREATOR, player.audioAttributes = AudioAttributes.CREATOR.fromBundle(audioAttributesBundle);
config.getBundle(KEY_AUDIO_ATTRIBUTES), }
player.audioAttributes); Bundle cueGroupBundle = config.getBundle(KEY_CURRENT_CUE_GROUP);
player.cueGroup = player.cueGroup =
BundleableUtil.fromNullableBundle( cueGroupBundle == null ? CueGroup.EMPTY : CueGroup.CREATOR.fromBundle(cueGroupBundle);
CueGroup.CREATOR, config.getBundle(KEY_CURRENT_CUE_GROUP), CueGroup.EMPTY); @Nullable Bundle deviceInfoBundle = config.getBundle(KEY_DEVICE_INFO);
player.deviceInfo = if (deviceInfoBundle != null) {
BundleableUtil.fromNullableBundle( player.deviceInfo = DeviceInfo.CREATOR.fromBundle(deviceInfoBundle);
DeviceInfo.CREATOR, config.getBundle(KEY_DEVICE_INFO), player.deviceInfo); }
player.deviceVolume = config.getInt(KEY_DEVICE_VOLUME, player.deviceVolume); player.deviceVolume = config.getInt(KEY_DEVICE_VOLUME, player.deviceVolume);
player.deviceMuted = config.getBoolean(KEY_DEVICE_MUTED, player.deviceMuted); player.deviceMuted = config.getBoolean(KEY_DEVICE_MUTED, player.deviceMuted);
player.playWhenReady = config.getBoolean(KEY_PLAY_WHEN_READY, player.playWhenReady); player.playWhenReady = config.getBoolean(KEY_PLAY_WHEN_READY, player.playWhenReady);
@ -327,9 +327,10 @@ public class MediaSessionProviderService extends Service {
config.getLong(KEY_SEEK_BACK_INCREMENT_MS, player.seekBackIncrementMs); config.getLong(KEY_SEEK_BACK_INCREMENT_MS, player.seekBackIncrementMs);
player.seekForwardIncrementMs = player.seekForwardIncrementMs =
config.getLong(KEY_SEEK_FORWARD_INCREMENT_MS, player.seekForwardIncrementMs); config.getLong(KEY_SEEK_FORWARD_INCREMENT_MS, player.seekForwardIncrementMs);
player.mediaMetadata = @Nullable Bundle mediaMetadataBundle = config.getBundle(KEY_MEDIA_METADATA);
BundleableUtil.fromNullableBundle( if (mediaMetadataBundle != null) {
MediaMetadata.CREATOR, config.getBundle(KEY_MEDIA_METADATA), player.mediaMetadata); player.mediaMetadata = MediaMetadata.CREATOR.fromBundle(mediaMetadataBundle);
}
player.maxSeekToPreviousPositionMs = player.maxSeekToPreviousPositionMs =
config.getLong(KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS, player.maxSeekToPreviousPositionMs); config.getLong(KEY_MAX_SEEK_TO_PREVIOUS_POSITION_MS, player.maxSeekToPreviousPositionMs);
@Nullable @Nullable
@ -420,8 +421,9 @@ public class MediaSessionProviderService extends Service {
MockPlayer player = (MockPlayer) session.getPlayer(); MockPlayer player = (MockPlayer) session.getPlayer();
@Nullable @Nullable
PlaybackException playerError = PlaybackException playerError =
BundleableUtil.fromNullableBundle( playerErrorBundle == null
PlaybackException.CREATOR, playerErrorBundle, player.playerError); ? player.playerError
: PlaybackException.CREATOR.fromBundle(playerErrorBundle);
player.notifyPlayerError(playerError); player.notifyPlayerError(playerError);
}); });
} }
@ -780,8 +782,9 @@ public class MediaSessionProviderService extends Service {
MediaSession session = sessionMap.get(sessionId); MediaSession session = sessionMap.get(sessionId);
MockPlayer player = (MockPlayer) session.getPlayer(); MockPlayer player = (MockPlayer) session.getPlayer();
player.notifyAvailableCommandsChanged( player.notifyAvailableCommandsChanged(
BundleableUtil.fromNullableBundle( commandsBundle == null
Player.Commands.CREATOR, commandsBundle, Player.Commands.EMPTY)); ? Player.Commands.EMPTY
: Player.Commands.CREATOR.fromBundle(commandsBundle));
}); });
} }

View File

@ -61,7 +61,6 @@ import androidx.annotation.GuardedBy;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata; import androidx.media3.common.MediaMetadata;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
@ -102,6 +101,7 @@ public class MockMediaLibraryService extends MediaLibraryService {
private static boolean assertLibraryParams; private static boolean assertLibraryParams;
@GuardedBy("MockMediaLibraryService.class") @GuardedBy("MockMediaLibraryService.class")
@Nullable
private static LibraryParams expectedParams; private static LibraryParams expectedParams;
MediaLibrarySession session; MediaLibrarySession session;
@ -162,7 +162,7 @@ public class MockMediaLibraryService extends MediaLibraryService {
super.attachBaseContext(base); super.attachBaseContext(base);
} }
public static void setAssertLibraryParams(LibraryParams expectedParams) { public static void setAssertLibraryParams(@Nullable LibraryParams expectedParams) {
synchronized (MockMediaLibraryService.class) { synchronized (MockMediaLibraryService.class) {
assertLibraryParams = true; assertLibraryParams = true;
MockMediaLibraryService.expectedParams = expectedParams; MockMediaLibraryService.expectedParams = expectedParams;
@ -365,9 +365,10 @@ public class MockMediaLibraryService extends MediaLibraryService {
return Futures.immediateFuture( return Futures.immediateFuture(
new SessionResult(SessionResult.RESULT_SUCCESS, CUSTOM_ACTION_EXTRAS)); new SessionResult(SessionResult.RESULT_SUCCESS, CUSTOM_ACTION_EXTRAS));
case CUSTOM_ACTION_ASSERT_PARAMS: case CUSTOM_ACTION_ASSERT_PARAMS:
@Nullable Bundle paramsBundle = args.getBundle(CUSTOM_ACTION_ASSERT_PARAMS);
@Nullable
LibraryParams params = LibraryParams params =
BundleableUtil.fromNullableBundle( paramsBundle == null ? null : LibraryParams.CREATOR.fromBundle(paramsBundle);
LibraryParams.CREATOR, args.getBundle(CUSTOM_ACTION_ASSERT_PARAMS));
setAssertLibraryParams(params); setAssertLibraryParams(params);
return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS)); return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
default: // fall out default: // fall out

View File

@ -20,7 +20,6 @@ import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaLibraryService.LibraryParams; import androidx.media3.session.MediaLibraryService.LibraryParams;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -48,14 +47,14 @@ public class RemoteMediaBrowser extends RemoteMediaController {
/** {@link MediaBrowser} methods. */ /** {@link MediaBrowser} methods. */
public LibraryResult<MediaItem> getLibraryRoot(@Nullable LibraryParams params) public LibraryResult<MediaItem> getLibraryRoot(@Nullable LibraryParams params)
throws RemoteException { throws RemoteException {
Bundle result = binder.getLibraryRoot(controllerId, BundleableUtil.toNullableBundle(params)); Bundle result = binder.getLibraryRoot(controllerId, params == null ? null : params.toBundle());
return LibraryResult.ITEM_CREATOR.fromBundle(result); return LibraryResult.ITEM_CREATOR.fromBundle(result);
} }
public LibraryResult<Void> subscribe(String parentId, @Nullable LibraryParams params) public LibraryResult<Void> subscribe(String parentId, @Nullable LibraryParams params)
throws RemoteException { throws RemoteException {
Bundle result = Bundle result =
binder.subscribe(controllerId, parentId, BundleableUtil.toNullableBundle(params)); binder.subscribe(controllerId, parentId, params == null ? null : params.toBundle());
return LibraryResult.VOID_CREATOR.fromBundle(result); return LibraryResult.VOID_CREATOR.fromBundle(result);
} }
@ -69,7 +68,7 @@ public class RemoteMediaBrowser extends RemoteMediaController {
throws RemoteException { throws RemoteException {
Bundle result = Bundle result =
binder.getChildren( binder.getChildren(
controllerId, parentId, page, pageSize, BundleableUtil.toNullableBundle(params)); controllerId, parentId, page, pageSize, params == null ? null : params.toBundle());
return LibraryResult.ITEM_LIST_CREATOR.fromBundle(result); return LibraryResult.ITEM_LIST_CREATOR.fromBundle(result);
} }
@ -80,7 +79,7 @@ public class RemoteMediaBrowser extends RemoteMediaController {
public LibraryResult<Void> search(String query, @Nullable LibraryParams params) public LibraryResult<Void> search(String query, @Nullable LibraryParams params)
throws RemoteException { throws RemoteException {
Bundle result = binder.search(controllerId, query, BundleableUtil.toNullableBundle(params)); Bundle result = binder.search(controllerId, query, params == null ? null : params.toBundle());
return LibraryResult.VOID_CREATOR.fromBundle(result); return LibraryResult.VOID_CREATOR.fromBundle(result);
} }
@ -88,7 +87,7 @@ public class RemoteMediaBrowser extends RemoteMediaController {
String query, int page, int pageSize, @Nullable LibraryParams params) throws RemoteException { String query, int page, int pageSize, @Nullable LibraryParams params) throws RemoteException {
Bundle result = Bundle result =
binder.getSearchResult( binder.getSearchResult(
controllerId, query, page, pageSize, BundleableUtil.toNullableBundle(params)); controllerId, query, page, pageSize, params == null ? null : params.toBundle());
return LibraryResult.ITEM_LIST_CREATOR.fromBundle(result); return LibraryResult.ITEM_LIST_CREATOR.fromBundle(result);
} }

View File

@ -29,6 +29,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import androidx.annotation.Nullable;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata; import androidx.media3.common.MediaMetadata;
import androidx.media3.common.PlaybackParameters; import androidx.media3.common.PlaybackParameters;
@ -87,9 +88,10 @@ public class RemoteMediaController {
// MediaController methods // MediaController methods
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@Nullable
public SessionToken getConnectedSessionToken() throws RemoteException { public SessionToken getConnectedSessionToken() throws RemoteException {
return BundleableUtil.fromNullableBundle( @Nullable Bundle sessionTokenBundle = binder.getConnectedSessionToken(controllerId);
SessionToken.CREATOR, binder.getConnectedSessionToken(controllerId)); return sessionTokenBundle == null ? null : SessionToken.CREATOR.fromBundle(sessionTokenBundle);
} }
public void play() throws RemoteException { public void play() throws RemoteException {
@ -133,7 +135,7 @@ public class RemoteMediaController {
} }
public void setPlaybackParameters(PlaybackParameters playbackParameters) throws RemoteException { public void setPlaybackParameters(PlaybackParameters playbackParameters) throws RemoteException {
binder.setPlaybackParameters(controllerId, BundleableUtil.toNullableBundle(playbackParameters)); binder.setPlaybackParameters(controllerId, playbackParameters.toBundle());
} }
public void setPlaybackSpeed(float speed) throws RemoteException { public void setPlaybackSpeed(float speed) throws RemoteException {

View File

@ -79,7 +79,6 @@ import androidx.media3.common.Timeline;
import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.TrackSelectionParameters;
import androidx.media3.common.VideoSize; import androidx.media3.common.VideoSize;
import androidx.media3.common.text.CueGroup; import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.BundleableUtil;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.test.session.common.IRemoteMediaSession; import androidx.media3.test.session.common.IRemoteMediaSession;
@ -206,7 +205,7 @@ public class RemoteMediaSession {
public class RemoteMockPlayer { public class RemoteMockPlayer {
public void notifyPlayerError(@Nullable PlaybackException playerError) throws RemoteException { public void notifyPlayerError(@Nullable PlaybackException playerError) throws RemoteException {
binder.notifyPlayerError(sessionId, BundleableUtil.toNullableBundle(playerError)); binder.notifyPlayerError(sessionId, playerError == null ? null : playerError.toBundle());
} }
public void setPlayWhenReady( public void setPlayWhenReady(
@ -491,7 +490,9 @@ public class RemoteMediaSession {
} }
public MockPlayerConfigBuilder setPlayerError(@Nullable PlaybackException playerError) { public MockPlayerConfigBuilder setPlayerError(@Nullable PlaybackException playerError) {
bundle.putBundle(KEY_PLAYER_ERROR, BundleableUtil.toNullableBundle(playerError)); if (playerError != null) {
bundle.putBundle(KEY_PLAYER_ERROR, playerError.toBundle());
}
return this; return this;
} }