From 8fbb971dfaf5fb2bdb9d17410228477773fb02ce Mon Sep 17 00:00:00 2001 From: gyumin Date: Thu, 4 Mar 2021 08:20:51 +0000 Subject: [PATCH] Implement Bundleable for AdGroup PiperOrigin-RevId: 360851146 --- .../source/ads/AdPlaybackState.java | 58 ++++++++++++++++++- .../source/ads/AdPlaybackStateTest.java | 44 ++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java 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 b70dd10c38..c49e025bc4 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 @@ -18,15 +18,18 @@ package com.google.android.exoplayer2.source.ads; import static java.lang.Math.max; import android.net.Uri; +import android.os.Bundle; import androidx.annotation.CheckResult; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import com.google.android.exoplayer2.Bundleable; import com.google.android.exoplayer2.C; 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; +import java.util.ArrayList; import java.util.Arrays; import org.checkerframework.checker.nullness.compatqual.NullableType; @@ -44,7 +47,7 @@ public final class AdPlaybackState { *

Instances are immutable. Call the {@code with*} methods to get new instances that have the * required changes. */ - public static final class AdGroup { + public static final class AdGroup implements Bundleable { /** The number of ads in the ad group, or {@link C#LENGTH_UNSET} if unknown. */ public final int count; @@ -230,6 +233,59 @@ public final class AdPlaybackState { Arrays.fill(durationsUs, oldDurationsUsCount, newDurationsUsCount, C.TIME_UNSET); return durationsUs; } + + // Bundleable implementation. + + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({FIELD_COUNT, FIELD_URIS, FIELD_STATES, FIELD_DURATIONS_US}) + private @interface FieldNumber {} + + private static final int FIELD_COUNT = 0; + private static final int FIELD_URIS = 1; + private static final int FIELD_STATES = 2; + private static final int FIELD_DURATIONS_US = 3; + + // putParcelableArrayList actually supports null elements. + @SuppressWarnings("nullness:argument.type.incompatible") + @Override + public Bundle toBundle() { + Bundle bundle = new Bundle(); + bundle.putInt(keyForField(FIELD_COUNT), count); + bundle.putParcelableArrayList( + keyForField(FIELD_URIS), new ArrayList<@NullableType Uri>(Arrays.asList(uris))); + bundle.putIntArray(keyForField(FIELD_STATES), states); + bundle.putLongArray(keyForField(FIELD_DURATIONS_US), durationsUs); + return bundle; + } + + /** Object that can restore {@link AdGroup} from a {@link Bundle}. */ + public static final Creator CREATOR = + new Creator() { + + // getParcelableArrayList may have null elements. + @SuppressWarnings("nullness:type.argument.type.incompatible") + @Override + public AdGroup fromBundle(Bundle bundle) { + int count = bundle.getInt(keyForField(FIELD_COUNT), /* defaultValue= */ C.LENGTH_UNSET); + @Nullable + ArrayList<@NullableType Uri> uriList = + bundle.getParcelableArrayList(keyForField(FIELD_URIS)); + @Nullable + @AdState + int[] states = bundle.getIntArray(keyForField(FIELD_STATES)); + @Nullable long[] durationsUs = bundle.getLongArray(keyForField(FIELD_DURATIONS_US)); + return new AdGroup( + count, + states == null ? new int[0] : states, + uriList == null ? new Uri[0] : uriList.toArray(new Uri[0]), + durationsUs == null ? new long[0] : durationsUs); + } + }; + + private static String keyForField(@AdGroup.FieldNumber int field) { + return Integer.toString(field, Character.MAX_RADIX); + } } /** diff --git a/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java b/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java new file mode 100644 index 0000000000..cec107859d --- /dev/null +++ b/library/common/src/test/java/com/google/android/exoplayer2/source/ads/AdPlaybackStateTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 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 com.google.android.exoplayer2.source.ads; + +import static com.google.android.exoplayer2.source.ads.AdPlaybackState.AD_STATE_AVAILABLE; +import static com.google.android.exoplayer2.source.ads.AdPlaybackState.AD_STATE_PLAYED; +import static com.google.common.truth.Truth.assertThat; + +import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Unit tests for {@link AdPlaybackState}. */ +@RunWith(AndroidJUnit4.class) +public class AdPlaybackStateTest { + + @Test + public void roundtripViaBundle_ofAdGroup_yieldsEqualInstance() { + AdPlaybackState.AdGroup adGroup = + new AdPlaybackState.AdGroup() + .withAdCount(2) + .withAdState(AD_STATE_AVAILABLE, /* index= */ 0) + .withAdState(AD_STATE_PLAYED, /* index= */ 1) + .withAdUri(Uri.parse("https://www.google.com"), /* index= */ 0) + .withAdUri(Uri.EMPTY, /* index= */ 1) + .withAdDurationsUs(new long[] {1234, 5678}); + + assertThat(AdPlaybackState.AdGroup.CREATOR.fromBundle(adGroup.toBundle())).isEqualTo(adGroup); + } +}