mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Make AdsLoader.State implement Bundleable
This allows the AdsLoader.State to be stored in savedInstanceState #minor-release PiperOrigin-RevId: 429057697
This commit is contained in:
parent
ccfb126b8a
commit
899d458c7b
@ -28,17 +28,22 @@ import static androidx.media3.exoplayer.ima.ImaUtil.updateAdDurationAndPropagate
|
|||||||
import static androidx.media3.exoplayer.ima.ImaUtil.updateAdDurationInAdGroup;
|
import static androidx.media3.exoplayer.ima.ImaUtil.updateAdDurationInAdGroup;
|
||||||
import static androidx.media3.exoplayer.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState;
|
import static androidx.media3.exoplayer.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.MainThread;
|
import androidx.annotation.MainThread;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.media3.common.AdOverlayInfo;
|
import androidx.media3.common.AdOverlayInfo;
|
||||||
import androidx.media3.common.AdPlaybackState;
|
import androidx.media3.common.AdPlaybackState;
|
||||||
import androidx.media3.common.AdViewProvider;
|
import androidx.media3.common.AdViewProvider;
|
||||||
|
import androidx.media3.common.Bundleable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.Metadata;
|
import androidx.media3.common.Metadata;
|
||||||
@ -88,6 +93,10 @@ import com.google.ads.interactivemedia.v3.api.player.VideoStreamPlayer;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -285,13 +294,67 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** The state of the {@link AdsLoader}. */
|
/** The state of the {@link AdsLoader}. */
|
||||||
public static class State {
|
public static class State implements Bundleable {
|
||||||
|
|
||||||
private final ImmutableMap<String, AdPlaybackState> adPlaybackStates;
|
private final ImmutableMap<String, AdPlaybackState> adPlaybackStates;
|
||||||
|
|
||||||
private State(ImmutableMap<String, AdPlaybackState> adPlaybackStates) {
|
@VisibleForTesting
|
||||||
|
/* package */ State(ImmutableMap<String, AdPlaybackState> adPlaybackStates) {
|
||||||
this.adPlaybackStates = adPlaybackStates;
|
this.adPlaybackStates = adPlaybackStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof State)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
State state = (State) o;
|
||||||
|
return adPlaybackStates.equals(state.adPlaybackStates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return adPlaybackStates.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bundleable implementation.
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target(TYPE_USE)
|
||||||
|
@IntDef({FIELD_AD_PLAYBACK_STATES})
|
||||||
|
private @interface FieldNumber {}
|
||||||
|
|
||||||
|
private static final int FIELD_AD_PLAYBACK_STATES = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Bundle toBundle() {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putSerializable(keyForField(FIELD_AD_PLAYBACK_STATES), adPlaybackStates);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Object that can restore {@link AdsLoader.State} from a {@link Bundle}. */
|
||||||
|
public static final Bundleable.Creator<State> CREATOR = State::fromBundle;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static State fromBundle(Bundle bundle) {
|
||||||
|
@Nullable
|
||||||
|
Map<String, AdPlaybackState> adPlaybackStateMap =
|
||||||
|
(Map<String, AdPlaybackState>)
|
||||||
|
bundle.getSerializable(keyForField(FIELD_AD_PLAYBACK_STATES));
|
||||||
|
return new State(
|
||||||
|
adPlaybackStateMap != null
|
||||||
|
? ImmutableMap.copyOf(adPlaybackStateMap)
|
||||||
|
: ImmutableMap.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String keyForField(@FieldNumber int field) {
|
||||||
|
return Integer.toString(field, Character.MAX_RADIX);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ImaUtil.ServerSideAdInsertionConfiguration configuration;
|
private final ImaUtil.ServerSideAdInsertionConfiguration configuration;
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package androidx.media3.exoplayer.ima;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.media3.common.AdPlaybackState;
|
||||||
|
import androidx.media3.common.C;
|
||||||
|
import androidx.media3.exoplayer.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State;
|
||||||
|
import androidx.media3.exoplayer.source.ads.ServerSideAdInsertionUtil;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
/** Unit tests for {@link ImaServerSideAdInsertionMediaSource}. */
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ImaServerSideAdInsertionMediaSourceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void adsLoaderStateToBundle_marshallAndUnmarshalling_resultIsEqual() {
|
||||||
|
AdPlaybackState firstAdPlaybackState =
|
||||||
|
ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(
|
||||||
|
new AdPlaybackState("adsId1"),
|
||||||
|
/* fromPositionUs= */ 0,
|
||||||
|
/* contentResumeOffsetUs= */ 10,
|
||||||
|
/* adDurationsUs...= */ 5_000_000,
|
||||||
|
10_000_000,
|
||||||
|
20_000_000);
|
||||||
|
AdPlaybackState secondAdPlaybackState =
|
||||||
|
ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(
|
||||||
|
new AdPlaybackState("adsId2"),
|
||||||
|
/* fromPositionUs= */ 0,
|
||||||
|
/* contentResumeOffsetUs= */ 10,
|
||||||
|
/* adDurationsUs...= */ 10_000_000)
|
||||||
|
.withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0);
|
||||||
|
AdPlaybackState thirdAdPlaybackState =
|
||||||
|
ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(
|
||||||
|
new AdPlaybackState("adsId3"),
|
||||||
|
/* fromPositionUs= */ C.TIME_END_OF_SOURCE,
|
||||||
|
/* contentResumeOffsetUs= */ 10,
|
||||||
|
/* adDurationsUs...= */ 10_000_000);
|
||||||
|
thirdAdPlaybackState =
|
||||||
|
ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(
|
||||||
|
thirdAdPlaybackState,
|
||||||
|
/* fromPositionUs= */ 0,
|
||||||
|
/* contentResumeOffsetUs= */ 10,
|
||||||
|
/* adDurationsUs...= */ 10_000_000)
|
||||||
|
.withRemovedAdGroupCount(1);
|
||||||
|
State state =
|
||||||
|
new State(
|
||||||
|
ImmutableMap.<String, AdPlaybackState>builder()
|
||||||
|
.put("adsId1", firstAdPlaybackState)
|
||||||
|
.put("adsId2", secondAdPlaybackState)
|
||||||
|
.put("adsId3", thirdAdPlaybackState)
|
||||||
|
.buildOrThrow());
|
||||||
|
|
||||||
|
assertThat(State.CREATOR.fromBundle(state.toBundle())).isEqualTo(state);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user