From e044235421e36d80de010690779728190abbf160 Mon Sep 17 00:00:00 2001 From: bachinger Date: Wed, 9 Mar 2022 16:58:46 +0000 Subject: [PATCH] Transform map of AdsLoader.State to a Bundle This fixes an exception thrown when parceling becasue the type can not be found (expects the AdsPlaybackState to be Serializable). Transforming the map and the ad playback states to a Bundle fixes the problem. #minor-release PiperOrigin-RevId: 433491993 --- .../ImaServerSideAdInsertionMediaSource.java | 26 ++++++++++------ .../source/ads/AdPlaybackState.java | 30 +++++++++++++++++++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java index 08814e7aa1..ad45734a95 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java @@ -325,23 +325,31 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou @Override public Bundle toBundle() { Bundle bundle = new Bundle(); - bundle.putSerializable(keyForField(FIELD_AD_PLAYBACK_STATES), adPlaybackStates); + Bundle adPlaybackStatesBundle = new Bundle(); + for (Map.Entry entry : adPlaybackStates.entrySet()) { + adPlaybackStatesBundle.putBundle(entry.getKey(), entry.getValue().toBundle()); + } + bundle.putBundle(keyForField(FIELD_AD_PLAYBACK_STATES), adPlaybackStatesBundle); return bundle; } /** Object that can restore {@link AdsLoader.State} from a {@link Bundle}. */ public static final Bundleable.Creator CREATOR = State::fromBundle; - @SuppressWarnings("unchecked") private static State fromBundle(Bundle bundle) { @Nullable - Map adPlaybackStateMap = - (Map) - bundle.getSerializable(keyForField(FIELD_AD_PLAYBACK_STATES)); - return new State( - adPlaybackStateMap != null - ? ImmutableMap.copyOf(adPlaybackStateMap) - : ImmutableMap.of()); + ImmutableMap.Builder adPlaybackStateMap = + new ImmutableMap.Builder<>(); + Bundle adPlaybackStateBundle = + checkNotNull(bundle.getBundle(keyForField(FIELD_AD_PLAYBACK_STATES))); + for (String key : adPlaybackStateBundle.keySet()) { + AdPlaybackState adPlaybackState = + AdPlaybackState.CREATOR.fromBundle( + checkNotNull(adPlaybackStateBundle.getBundle(key))); + adPlaybackStateMap.put( + key, AdPlaybackState.fromAdPlaybackState(/* adsId= */ key, adPlaybackState)); + } + return new State(adPlaybackStateMap.buildOrThrow()); } private static String keyForField(@FieldNumber int field) { diff --git a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java index 2ef624c30d..738cb3f015 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java @@ -828,6 +828,36 @@ public final class AdPlaybackState implements Bundleable { adsId, adGroups, adResumePositionUs, contentDurationUs, removedAdGroupCount); } + /** + * Returns a copy of the ad playback state with the given ads ID. + * + * @param adsId The new ads ID. + * @param adPlaybackState The ad playback state to copy. + * @return The new ad playback state. + */ + public static AdPlaybackState fromAdPlaybackState(Object adsId, AdPlaybackState adPlaybackState) { + AdGroup[] adGroups = + new AdGroup[adPlaybackState.adGroupCount - adPlaybackState.removedAdGroupCount]; + for (int i = 0; i < adGroups.length; i++) { + AdGroup adGroup = adPlaybackState.adGroups[i]; + adGroups[i] = + new AdGroup( + adGroup.timeUs, + adGroup.count, + Arrays.copyOf(adGroup.states, adGroup.states.length), + Arrays.copyOf(adGroup.uris, adGroup.uris.length), + Arrays.copyOf(adGroup.durationsUs, adGroup.durationsUs.length), + adGroup.contentResumeOffsetUs, + adGroup.isServerSideInserted); + } + return new AdPlaybackState( + adsId, + adGroups, + adPlaybackState.adResumePositionUs, + adPlaybackState.contentDurationUs, + adPlaybackState.removedAdGroupCount); + } + @Override public boolean equals(@Nullable Object o) { if (this == o) {