mirror of
https://github.com/androidx/media.git
synced 2025-05-25 13:10:00 +08:00
Make DrmConfiguration Bundleable
PiperOrigin-RevId: 533721679 (cherry picked from commit 5008417c8cd12680a3945945e00399cca05915c5)
This commit is contained in:
parent
d40f37158a
commit
992c9aa470
@ -23,6 +23,7 @@ import android.os.Bundle;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.util.Assertions;
|
||||
import androidx.media3.common.util.BundleableUtil;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@ -598,7 +599,7 @@ public final class MediaItem implements Bundleable {
|
||||
}
|
||||
|
||||
/** DRM configuration for a media item. */
|
||||
public static final class DrmConfiguration {
|
||||
public static final class DrmConfiguration implements Bundleable {
|
||||
|
||||
/** Builder for {@link DrmConfiguration}. */
|
||||
public static final class Builder {
|
||||
@ -773,7 +774,6 @@ public final class MediaItem implements Bundleable {
|
||||
}
|
||||
|
||||
public DrmConfiguration build() {
|
||||
|
||||
return new DrmConfiguration(this);
|
||||
}
|
||||
}
|
||||
@ -888,6 +888,83 @@ public final class MediaItem implements Bundleable {
|
||||
result = 31 * result + Arrays.hashCode(keySetId);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Bundleable implementation
|
||||
|
||||
private static final String FIELD_SCHEME = Util.intToStringMaxRadix(0);
|
||||
private static final String FIELD_LICENSE_URI = Util.intToStringMaxRadix(1);
|
||||
private static final String FIELD_LICENSE_REQUEST_HEADERS = Util.intToStringMaxRadix(2);
|
||||
private static final String FIELD_MULTI_SESSION = Util.intToStringMaxRadix(3);
|
||||
private static final String FIELD_PLAY_CLEAR_CONTENT_WITHOUT_KEY = Util.intToStringMaxRadix(4);
|
||||
private static final String FIELD_FORCE_DEFAULT_LICENSE_URI = Util.intToStringMaxRadix(5);
|
||||
private static final String FIELD_FORCED_SESSION_TRACK_TYPES = Util.intToStringMaxRadix(6);
|
||||
private static final String FIELD_KEY_SET_ID = Util.intToStringMaxRadix(7);
|
||||
|
||||
/** Object that can restore {@link DrmConfiguration} from a {@link Bundle}. */
|
||||
@UnstableApi
|
||||
public static final Creator<DrmConfiguration> CREATOR = DrmConfiguration::fromBundle;
|
||||
|
||||
@UnstableApi
|
||||
private static DrmConfiguration fromBundle(Bundle bundle) {
|
||||
UUID scheme = UUID.fromString(checkNotNull(bundle.getString(FIELD_SCHEME)));
|
||||
@Nullable Uri licenseUri = bundle.getParcelable(FIELD_LICENSE_URI);
|
||||
Bundle licenseMapAsBundle =
|
||||
BundleableUtil.getBundleWithDefault(bundle, FIELD_LICENSE_REQUEST_HEADERS, Bundle.EMPTY);
|
||||
ImmutableMap<String, String> licenseRequestHeaders =
|
||||
BundleableUtil.bundleToStringImmutableMap(licenseMapAsBundle);
|
||||
boolean multiSession = bundle.getBoolean(FIELD_MULTI_SESSION, false);
|
||||
boolean playClearContentWithoutKey =
|
||||
bundle.getBoolean(FIELD_PLAY_CLEAR_CONTENT_WITHOUT_KEY, false);
|
||||
boolean forceDefaultLicenseUri = bundle.getBoolean(FIELD_FORCE_DEFAULT_LICENSE_URI, false);
|
||||
ArrayList<@C.TrackType Integer> forcedSessionTrackTypesArray =
|
||||
BundleableUtil.getIntegerArrayListWithDefault(
|
||||
bundle, FIELD_FORCED_SESSION_TRACK_TYPES, new ArrayList<>());
|
||||
ImmutableList<@C.TrackType Integer> forcedSessionTrackTypes =
|
||||
ImmutableList.copyOf(forcedSessionTrackTypesArray);
|
||||
@Nullable byte[] keySetId = bundle.getByteArray(FIELD_KEY_SET_ID);
|
||||
|
||||
Builder builder = new Builder(scheme);
|
||||
return builder
|
||||
.setLicenseUri(licenseUri)
|
||||
.setLicenseRequestHeaders(licenseRequestHeaders)
|
||||
.setMultiSession(multiSession)
|
||||
.setForceDefaultLicenseUri(forceDefaultLicenseUri)
|
||||
.setPlayClearContentWithoutKey(playClearContentWithoutKey)
|
||||
.setForcedSessionTrackTypes(forcedSessionTrackTypes)
|
||||
.setKeySetId(keySetId)
|
||||
.build();
|
||||
}
|
||||
|
||||
@UnstableApi
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(FIELD_SCHEME, scheme.toString());
|
||||
if (licenseUri != null) {
|
||||
bundle.putParcelable(FIELD_LICENSE_URI, licenseUri);
|
||||
}
|
||||
if (!licenseRequestHeaders.isEmpty()) {
|
||||
bundle.putBundle(
|
||||
FIELD_LICENSE_REQUEST_HEADERS, BundleableUtil.stringMapToBundle(licenseRequestHeaders));
|
||||
}
|
||||
if (multiSession) {
|
||||
bundle.putBoolean(FIELD_MULTI_SESSION, multiSession);
|
||||
}
|
||||
if (playClearContentWithoutKey) {
|
||||
bundle.putBoolean(FIELD_PLAY_CLEAR_CONTENT_WITHOUT_KEY, playClearContentWithoutKey);
|
||||
}
|
||||
if (forceDefaultLicenseUri) {
|
||||
bundle.putBoolean(FIELD_FORCE_DEFAULT_LICENSE_URI, forceDefaultLicenseUri);
|
||||
}
|
||||
if (!forcedSessionTrackTypes.isEmpty()) {
|
||||
bundle.putIntegerArrayList(
|
||||
FIELD_FORCED_SESSION_TRACK_TYPES, new ArrayList<>(forcedSessionTrackTypes));
|
||||
}
|
||||
if (keySetId != null) {
|
||||
bundle.putByteArray(FIELD_KEY_SET_ID, keySetId);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
}
|
||||
|
||||
/** Configuration for playing back linear ads with a media item. */
|
||||
|
@ -23,9 +23,12 @@ import android.util.SparseArray;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.Bundleable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Utilities for {@link Bundleable}. */
|
||||
@UnstableApi
|
||||
@ -94,6 +97,47 @@ public final class BundleableUtil {
|
||||
return sparseArray;
|
||||
}
|
||||
|
||||
public static Bundle stringMapToBundle(Map<String, String> bundleableMap) {
|
||||
Bundle bundle = new Bundle();
|
||||
for (Map.Entry<String, String> entry : bundleableMap.entrySet()) {
|
||||
bundle.putString(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static HashMap<String, String> bundleToStringHashMap(Bundle bundle) {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
if (bundle == Bundle.EMPTY) {
|
||||
return map;
|
||||
}
|
||||
for (String key : bundle.keySet()) {
|
||||
@Nullable String value = bundle.getString(key);
|
||||
if (value != null) {
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static ImmutableMap<String, String> bundleToStringImmutableMap(Bundle bundle) {
|
||||
if (bundle == Bundle.EMPTY) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
HashMap<String, String> map = bundleToStringHashMap(bundle);
|
||||
return ImmutableMap.copyOf(map);
|
||||
}
|
||||
|
||||
public static Bundle getBundleWithDefault(Bundle bundle, String field, Bundle defaultValue) {
|
||||
@Nullable Bundle result = bundle.getBundle(field);
|
||||
return result != null ? result : defaultValue;
|
||||
}
|
||||
|
||||
public static ArrayList<Integer> getIntegerArrayListWithDefault(
|
||||
Bundle bundle, String field, ArrayList<Integer> defaultValue) {
|
||||
@Nullable ArrayList<Integer> result = bundle.getIntegerArrayList(field);
|
||||
return result != null ? result : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the application class loader to the given {@link Bundle} if no class loader is present.
|
||||
*
|
||||
|
@ -247,6 +247,25 @@ public class MediaItemTest {
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDrmConfigurationInstance_roundTripViaBundle_yieldsEqualInstance() {
|
||||
MediaItem.DrmConfiguration drmConfiguration =
|
||||
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
|
||||
.setLicenseUri(URI_STRING + "/license")
|
||||
.setLicenseRequestHeaders(ImmutableMap.of("Referer", "http://www.google.com"))
|
||||
.setMultiSession(true)
|
||||
.setForceDefaultLicenseUri(true)
|
||||
.setPlayClearContentWithoutKey(true)
|
||||
.setForcedSessionTrackTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
|
||||
.setKeySetId(new byte[] {1, 2, 3})
|
||||
.build();
|
||||
|
||||
MediaItem.DrmConfiguration drmConfigurationFromBundle =
|
||||
MediaItem.DrmConfiguration.CREATOR.fromBundle(drmConfiguration.toBundle());
|
||||
|
||||
assertThat(drmConfigurationFromBundle).isEqualTo(drmConfiguration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderSetCustomCacheKey_setsCustomCacheKey() {
|
||||
MediaItem mediaItem =
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2023 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
|
||||
*
|
||||
* https://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.common.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Unit tests for {@link BundleableUtil}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BundleableUtilTest {
|
||||
|
||||
@Test
|
||||
public void testStringMapToBundle() {
|
||||
Map<String, String> originalMap = new HashMap<>();
|
||||
originalMap.put("firstKey", "firstValue");
|
||||
originalMap.put("secondKey", "repeatedValue");
|
||||
originalMap.put("thirdKey", "repeatedValue");
|
||||
originalMap.put("", "valueOfEmptyKey");
|
||||
|
||||
Bundle mapAsBundle = BundleableUtil.stringMapToBundle(originalMap);
|
||||
Map<String, String> restoredMap = BundleableUtil.bundleToStringHashMap(mapAsBundle);
|
||||
|
||||
assertThat(restoredMap).isEqualTo(originalMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBundleWithDefault() {
|
||||
Bundle fullInnerBundle = new Bundle();
|
||||
fullInnerBundle.putString("0", "123");
|
||||
fullInnerBundle.putBoolean("1", false);
|
||||
fullInnerBundle.putInt("2", 123);
|
||||
Bundle defaultBundle = new Bundle();
|
||||
defaultBundle.putString("0", "I am default");
|
||||
Bundle outerBundle = new Bundle();
|
||||
outerBundle.putBundle("0", fullInnerBundle);
|
||||
outerBundle.putBundle("1", Bundle.EMPTY);
|
||||
outerBundle.putBundle("2", null);
|
||||
|
||||
Bundle restoredInnerBundle =
|
||||
BundleableUtil.getBundleWithDefault(outerBundle, "0", defaultBundle);
|
||||
Bundle restoredEmptyBundle =
|
||||
BundleableUtil.getBundleWithDefault(outerBundle, "1", defaultBundle);
|
||||
Bundle restoredNullBundle =
|
||||
BundleableUtil.getBundleWithDefault(outerBundle, "2", defaultBundle);
|
||||
|
||||
assertThat(restoredInnerBundle).isEqualTo(fullInnerBundle);
|
||||
assertThat(restoredEmptyBundle).isEqualTo(Bundle.EMPTY);
|
||||
assertThat(restoredNullBundle).isEqualTo(defaultBundle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetIntegerArrayListWithDefault() {
|
||||
ArrayList<Integer> normalArray = new ArrayList<>();
|
||||
normalArray.add(4);
|
||||
normalArray.add(8);
|
||||
normalArray.add(16);
|
||||
ArrayList<Integer> emptyArray = new ArrayList<>();
|
||||
ArrayList<Integer> defaultIntegerArray = new ArrayList<>();
|
||||
defaultIntegerArray.add(0);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putIntegerArrayList("0", normalArray);
|
||||
bundle.putIntegerArrayList("1", emptyArray);
|
||||
bundle.putIntegerArrayList("2", null);
|
||||
|
||||
ArrayList<Integer> restoredIntegerArray =
|
||||
BundleableUtil.getIntegerArrayListWithDefault(bundle, "0", defaultIntegerArray);
|
||||
ArrayList<Integer> restoredEmptyIntegerArray =
|
||||
BundleableUtil.getIntegerArrayListWithDefault(bundle, "1", defaultIntegerArray);
|
||||
ArrayList<Integer> restoredNullIntegerArray =
|
||||
BundleableUtil.getIntegerArrayListWithDefault(bundle, "2", defaultIntegerArray);
|
||||
|
||||
assertThat(restoredIntegerArray).isEqualTo(normalArray);
|
||||
assertThat(restoredEmptyIntegerArray).isEqualTo(emptyArray);
|
||||
assertThat(restoredNullIntegerArray).isEqualTo(defaultIntegerArray);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user