mirror of
https://github.com/androidx/media.git
synced 2025-05-10 00:59:51 +08:00
Implement Bundleable for Timeline.Period
PiperOrigin-RevId: 361736476
This commit is contained in:
parent
6f9dbfe0c1
commit
ae7c1091e6
@ -18,12 +18,17 @@ package com.google.android.exoplayer2;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Pair;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* A flexible representation of the structure of media. A timeline is able to represent the
|
||||
@ -412,7 +417,7 @@ public abstract class Timeline {
|
||||
* <p style="align:center"><img src="doc-files/timeline-period.svg" alt="Information defined by a
|
||||
* period">
|
||||
*/
|
||||
public static final class Period {
|
||||
public static final class Period implements Bundleable {
|
||||
|
||||
/**
|
||||
* An identifier for the period. Not necessarily unique. May be null if the ids of the period
|
||||
@ -681,6 +686,74 @@ public abstract class Timeline {
|
||||
result = 31 * result + adPlaybackState.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Bundleable implementation.
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_WINDOW_INDEX,
|
||||
FIELD_DURATION_US,
|
||||
FIELD_POSITION_IN_WINDOW_US,
|
||||
FIELD_AD_PLAYBACK_STATE
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_WINDOW_INDEX = 0;
|
||||
private static final int FIELD_DURATION_US = 1;
|
||||
private static final int FIELD_POSITION_IN_WINDOW_US = 2;
|
||||
private static final int FIELD_AD_PLAYBACK_STATE = 3;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>It omits the {@link #id} and {@link #uid} fields so these fields of an instance restored
|
||||
* by {@link #CREATOR} will always be {@code null}.
|
||||
*/
|
||||
// TODO(b/166765820): See if missing fields would be okay and add them to the Bundle otherwise.
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(keyForField(FIELD_WINDOW_INDEX), windowIndex);
|
||||
bundle.putLong(keyForField(FIELD_DURATION_US), durationUs);
|
||||
bundle.putLong(keyForField(FIELD_POSITION_IN_WINDOW_US), positionInWindowUs);
|
||||
bundle.putBundle(keyForField(FIELD_AD_PLAYBACK_STATE), adPlaybackState.toBundle());
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Object that can restore {@link Period} from a {@link Bundle}.
|
||||
*
|
||||
* <p>The {@link #id} and {@link #uid} of restored instances will always be {@code null}.
|
||||
*/
|
||||
public static final Creator<Period> CREATOR = Period::fromBundle;
|
||||
|
||||
private static Period fromBundle(Bundle bundle) {
|
||||
int windowIndex = bundle.getInt(keyForField(FIELD_WINDOW_INDEX), /* defaultValue= */ 0);
|
||||
long durationUs =
|
||||
bundle.getLong(keyForField(FIELD_DURATION_US), /* defaultValue= */ C.TIME_UNSET);
|
||||
long positionInWindowUs =
|
||||
bundle.getLong(keyForField(FIELD_POSITION_IN_WINDOW_US), /* defaultValue= */ 0);
|
||||
@Nullable
|
||||
Bundle adPlaybackStateBundle = bundle.getBundle(keyForField(FIELD_AD_PLAYBACK_STATE));
|
||||
AdPlaybackState adPlaybackState =
|
||||
adPlaybackStateBundle != null
|
||||
? AdPlaybackState.CREATOR.fromBundle(adPlaybackStateBundle)
|
||||
: AdPlaybackState.NONE;
|
||||
|
||||
Period period = new Period();
|
||||
return period.set(
|
||||
/* id= */ null,
|
||||
/* uid= */ null,
|
||||
windowIndex,
|
||||
durationUs,
|
||||
positionInWindowUs,
|
||||
adPlaybackState);
|
||||
}
|
||||
|
||||
private static String keyForField(@Period.FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
||||
/** An empty timeline. */
|
||||
|
@ -201,6 +201,22 @@ public class TimelineTest {
|
||||
assertThat(period.hashCode()).isEqualTo(otherPeriod.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundtripViaBundle_ofPeriod_yieldsEqualInstanceExceptIds() {
|
||||
Timeline.Period period = new Timeline.Period();
|
||||
period.id = new Object();
|
||||
period.uid = new Object();
|
||||
period.windowIndex = 1;
|
||||
period.durationUs = 123_000;
|
||||
period.positionInWindowUs = 4_000;
|
||||
|
||||
Timeline.Period restoredPeriod = Timeline.Period.CREATOR.fromBundle(period.toBundle());
|
||||
|
||||
period.id = null;
|
||||
period.uid = null;
|
||||
assertThat(restoredPeriod).isEqualTo(period);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Populates the deprecated window.tag property.
|
||||
private static Timeline.Window populateWindow(
|
||||
@Nullable MediaItem mediaItem, @Nullable Object tag) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user