mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Add ContentMetadataInternal helper class
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=192596362
This commit is contained in:
parent
7d0067e298
commit
8809193266
7 changed files with 120 additions and 87 deletions
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.upstream.cache;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
|
@ -34,19 +50,22 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
|
|||
0, 0, 0, 2, // version
|
||||
0, 0, 0, 0, // flags
|
||||
0, 0, 0, 2, // number_of_CachedContent
|
||||
0, 0, 0, 1, // cache_id
|
||||
0, 0, 0, 5, // cache_id 5
|
||||
0, 5, 65, 66, 67, 68, 69, // cache_key "ABCDE"
|
||||
0, 0, 0, 1, // metadata count
|
||||
0, 0, 0, 2, // metadata count
|
||||
0, 9, 101, 120, 111, 95, 114, 101, 100, 105, 114, // "exo_redir"
|
||||
0, 0, 0, 5, // value length
|
||||
97, 98, 99, 100, 101, // Redirected Uri "abcde"
|
||||
0, 7, 101, 120, 111, 95, 108, 101, 110, // "exo_len"
|
||||
0, 0, 0, 8, // value length
|
||||
0, 0, 0, 0, 0, 0, 0, 10, // original_content_length
|
||||
0, 0, 0, 0, // cache_id
|
||||
0, 0, 0, 2, // cache_id 2
|
||||
0, 5, 75, 76, 77, 78, 79, // cache_key "KLMNO"
|
||||
0, 0, 0, 1, // metadata count
|
||||
0, 7, 101, 120, 111, 95, 108, 101, 110, // "exo_len"
|
||||
0, 0, 0, 8, // value length
|
||||
0, 0, 0, 0, 0, 0, 10, 0, // original_content_length
|
||||
(byte) 0x42, (byte) 0x4A, (byte) 0x4F, (byte) 0x6F // hashcode_of_CachedContent_array
|
||||
0x12, 0x15, 0x66, (byte) 0x8A // hashcode_of_CachedContent_array
|
||||
};
|
||||
private CachedContentIndex index;
|
||||
private File cacheDir;
|
||||
|
|
@ -124,10 +143,14 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
|
|||
|
||||
index.load();
|
||||
assertThat(index.getAll()).hasSize(2);
|
||||
|
||||
assertThat(index.assignIdForKey("ABCDE")).isEqualTo(5);
|
||||
assertThat(index.getContentLength("ABCDE")).isEqualTo(10);
|
||||
ContentMetadata metadata = index.get("ABCDE").getMetadata();
|
||||
assertThat(ContentMetadataInternal.getContentLength(metadata)).isEqualTo(10);
|
||||
|
||||
assertThat(index.assignIdForKey("KLMNO")).isEqualTo(2);
|
||||
assertThat(index.getContentLength("KLMNO")).isEqualTo(2560);
|
||||
ContentMetadata metadata2 = index.get("KLMNO").getMetadata();
|
||||
assertThat(ContentMetadataInternal.getContentLength(metadata2)).isEqualTo(2560);
|
||||
}
|
||||
|
||||
public void testLoadV2() throws Exception {
|
||||
|
|
@ -137,26 +160,15 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
|
|||
|
||||
index.load();
|
||||
assertThat(index.getAll()).hasSize(2);
|
||||
assertThat(index.assignIdForKey("ABCDE")).isEqualTo(1);
|
||||
assertThat(index.getContentLength("ABCDE")).isEqualTo(10);
|
||||
assertThat(index.assignIdForKey("KLMNO")).isEqualTo(0);
|
||||
assertThat(index.getContentLength("KLMNO")).isEqualTo(2560);
|
||||
}
|
||||
|
||||
public void testStore() throws Exception {
|
||||
index.getOrAdd("KLMNO");
|
||||
index.setContentLength("KLMNO", 2560);
|
||||
index.getOrAdd("ABCDE");
|
||||
index.setContentLength("ABCDE", 10);
|
||||
assertThat(index.assignIdForKey("ABCDE")).isEqualTo(5);
|
||||
ContentMetadata metadata = index.get("ABCDE").getMetadata();
|
||||
assertThat(ContentMetadataInternal.getContentLength(metadata)).isEqualTo(10);
|
||||
assertThat(ContentMetadataInternal.getRedirectedUri(metadata)).isEqualTo(Uri.parse("abcde"));
|
||||
|
||||
index.store();
|
||||
|
||||
FileInputStream fos = new FileInputStream(new File(cacheDir, CachedContentIndex.FILE_NAME));
|
||||
byte[] buffer = Util.toByteArray(fos);
|
||||
|
||||
// TODO: The order of the CachedContent stored in index file isn't defined so this test may fail
|
||||
// on a different implementation of the underlying set
|
||||
assertThat(buffer).isEqualTo(testIndexV2File);
|
||||
assertThat(index.assignIdForKey("KLMNO")).isEqualTo(2);
|
||||
ContentMetadata metadata2 = index.get("KLMNO").getMetadata();
|
||||
assertThat(ContentMetadataInternal.getContentLength(metadata2)).isEqualTo(2560);
|
||||
}
|
||||
|
||||
public void testAssignIdForKeyAndGetKeyForId() throws Exception {
|
||||
|
|
@ -171,13 +183,6 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
|
|||
assertThat(index.assignIdForKey(key2)).isEqualTo(id2);
|
||||
}
|
||||
|
||||
public void testSetGetContentLength() throws Exception {
|
||||
final String key1 = "key1";
|
||||
assertThat(index.getContentLength(key1)).isEqualTo(C.LENGTH_UNSET);
|
||||
index.setContentLength(key1, 10);
|
||||
assertThat(index.getContentLength(key1)).isEqualTo(10);
|
||||
}
|
||||
|
||||
public void testGetNewId() throws Exception {
|
||||
SparseArray<String> idToKey = new SparseArray<>();
|
||||
assertThat(CachedContentIndex.getNewId(idToKey)).isEqualTo(0);
|
||||
|
|
@ -276,8 +281,13 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
|
|||
|
||||
private void assertStoredAndLoadedEqual(CachedContentIndex index, CachedContentIndex index2)
|
||||
throws IOException {
|
||||
index.getOrAdd("key1");
|
||||
index.getOrAdd("key2");
|
||||
ContentMetadataMutations mutations1 = new ContentMetadataMutations();
|
||||
ContentMetadataInternal.setContentLength(mutations1, 2560);
|
||||
index.getOrAdd("KLMNO").applyMetadataMutations(mutations1);
|
||||
ContentMetadataMutations mutations2 = new ContentMetadataMutations();
|
||||
ContentMetadataInternal.setContentLength(mutations2, 10);
|
||||
ContentMetadataInternal.setRedirectedUri(mutations2, Uri.parse("abcde"));
|
||||
index.getOrAdd("ABCDE").applyMetadataMutations(mutations2);
|
||||
index.store();
|
||||
|
||||
index2.load();
|
||||
|
|
|
|||
|
|
@ -422,9 +422,9 @@ public final class CacheDataSource implements DataSource {
|
|||
ContentMetadataMutations mutations = new ContentMetadataMutations();
|
||||
boolean isRedirected = !uri.equals(actualUri);
|
||||
if (isRedirected) {
|
||||
mutations.set(ContentMetadata.METADATA_NAME_REDIRECTED_URI, actualUri.toString());
|
||||
ContentMetadataInternal.setRedirectedUri(mutations, actualUri);
|
||||
} else {
|
||||
mutations.remove(ContentMetadata.METADATA_NAME_REDIRECTED_URI);
|
||||
ContentMetadataInternal.removeRedirectedUri(mutations);
|
||||
}
|
||||
try {
|
||||
cache.applyContentMetadataMutations(key, mutations);
|
||||
|
|
@ -437,9 +437,9 @@ public final class CacheDataSource implements DataSource {
|
|||
}
|
||||
|
||||
private static Uri loadRedirectedUriOrReturnGivenUri(Cache cache, String key, Uri uri) {
|
||||
ContentMetadata metadata = cache.getContentMetadata(key);
|
||||
String redirection = metadata.get(ContentMetadata.METADATA_NAME_REDIRECTED_URI, (String) null);
|
||||
return redirection == null ? uri : Uri.parse(redirection);
|
||||
ContentMetadata contentMetadata = cache.getContentMetadata(key);
|
||||
Uri redirectedUri = ContentMetadataInternal.getRedirectedUri(contentMetadata);
|
||||
return redirectedUri == null ? uri : redirectedUri;
|
||||
}
|
||||
|
||||
private static boolean isCausedByPositionOutOfRange(IOException e) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.upstream.cache;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache.CacheException;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.io.DataInputStream;
|
||||
|
|
@ -56,7 +55,9 @@ import java.util.TreeSet;
|
|||
CachedContent cachedContent = new CachedContent(id, key);
|
||||
if (version < VERSION_METADATA_INTRODUCED) {
|
||||
long length = input.readLong();
|
||||
cachedContent.setLength(length);
|
||||
ContentMetadataMutations mutations = new ContentMetadataMutations();
|
||||
ContentMetadataInternal.setContentLength(mutations, length);
|
||||
cachedContent.applyMetadataMutations(mutations);
|
||||
} else {
|
||||
cachedContent.metadata = DefaultContentMetadata.readFromStream(input);
|
||||
}
|
||||
|
|
@ -101,20 +102,7 @@ import java.util.TreeSet;
|
|||
public boolean applyMetadataMutations(ContentMetadataMutations mutations) {
|
||||
DefaultContentMetadata oldMetadata = metadata;
|
||||
metadata = metadata.copyWithMutationsApplied(mutations);
|
||||
return metadata.equals(oldMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the original stream, or {@link C#LENGTH_UNSET} if the length is unknown.
|
||||
*/
|
||||
public long getLength() {
|
||||
return metadata.get(ContentMetadata.METADATA_NAME_LENGTH, C.LENGTH_UNSET);
|
||||
}
|
||||
|
||||
/** Sets the length of the content. */
|
||||
public void setLength(long length) {
|
||||
applyMetadataMutations(
|
||||
new ContentMetadataMutations().set(ContentMetadata.METADATA_NAME_LENGTH, length));
|
||||
return !metadata.equals(oldMetadata);
|
||||
}
|
||||
|
||||
/** Returns whether the content is locked. */
|
||||
|
|
@ -232,7 +220,7 @@ import java.util.TreeSet;
|
|||
int result = id;
|
||||
result = 31 * result + key.hashCode();
|
||||
if (version < VERSION_METADATA_INTRODUCED) {
|
||||
long length = getLength();
|
||||
long length = ContentMetadataInternal.getContentLength(metadata);
|
||||
result = 31 * result + (int) (length ^ (length >>> 32));
|
||||
} else {
|
||||
result = 31 * result + metadata.hashCode();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.upstream.cache;
|
|||
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache.CacheException;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.AtomicFile;
|
||||
|
|
@ -197,27 +196,6 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
return keyToContent.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content length for the given key. A new {@link CachedContent} is added if there isn't
|
||||
* one already with the given key.
|
||||
*/
|
||||
public void setContentLength(String key, long length) {
|
||||
CachedContent cachedContent = getOrAdd(key);
|
||||
if (cachedContent.getLength() != length) {
|
||||
cachedContent.setLength(length);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content length for the given key if one set, or {@link
|
||||
* com.google.android.exoplayer2.C#LENGTH_UNSET} otherwise.
|
||||
*/
|
||||
public long getContentLength(String key) {
|
||||
CachedContent cachedContent = get(key);
|
||||
return cachedContent == null ? C.LENGTH_UNSET : cachedContent.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies {@code mutations} to the {@link ContentMetadata} for the given key. A new {@link
|
||||
* CachedContent} is added if there isn't one already with the given key.
|
||||
|
|
|
|||
|
|
@ -25,10 +25,6 @@ public interface ContentMetadata {
|
|||
|
||||
/** Prefix of internal metadata names. */
|
||||
String INTERNAL_METADATA_NAME_PREFIX = "exo_";
|
||||
/** Name of internal metadata to hold redirected URI. */
|
||||
String METADATA_NAME_REDIRECTED_URI = INTERNAL_METADATA_NAME_PREFIX + "redir";
|
||||
/** Name of internal metadata to hold content length. */
|
||||
String METADATA_NAME_LENGTH = INTERNAL_METADATA_NAME_PREFIX + "len";
|
||||
|
||||
/**
|
||||
* Returns a metadata value.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.upstream.cache;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
||||
/** Helper classes to easily access and modify internal metadata values. */
|
||||
/*package*/ final class ContentMetadataInternal {
|
||||
|
||||
private static final String PREFIX = ContentMetadata.INTERNAL_METADATA_NAME_PREFIX;
|
||||
private static final String METADATA_NAME_REDIRECTED_URI = PREFIX + "redir";
|
||||
private static final String METADATA_NAME_CONTENT_LENGTH = PREFIX + "len";
|
||||
|
||||
/** Returns the content length metadata, or {@link C#LENGTH_UNSET} if not set. */
|
||||
public static long getContentLength(ContentMetadata contentMetadata) {
|
||||
return contentMetadata.get(METADATA_NAME_CONTENT_LENGTH, C.LENGTH_UNSET);
|
||||
}
|
||||
|
||||
/** Adds a mutation to set content length metadata value. */
|
||||
public static void setContentLength(ContentMetadataMutations mutations, long length) {
|
||||
mutations.set(METADATA_NAME_CONTENT_LENGTH, length);
|
||||
}
|
||||
|
||||
/** Adds a mutation to remove content length metadata value. */
|
||||
public static void removeContentLength(ContentMetadataMutations mutations) {
|
||||
mutations.remove(METADATA_NAME_CONTENT_LENGTH);
|
||||
}
|
||||
|
||||
/** Returns the redirected uri metadata, or {@code null} if not set. */
|
||||
public @Nullable static Uri getRedirectedUri(ContentMetadata contentMetadata) {
|
||||
String redirectedUri = contentMetadata.get(METADATA_NAME_REDIRECTED_URI, (String) null);
|
||||
return redirectedUri == null ? null : Uri.parse(redirectedUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a mutation to set redirected uri metadata value. Passing {@code null} as {@code uri} isn't
|
||||
* allowed.
|
||||
*/
|
||||
public static void setRedirectedUri(ContentMetadataMutations mutations, Uri uri) {
|
||||
mutations.set(METADATA_NAME_REDIRECTED_URI, uri.toString());
|
||||
}
|
||||
|
||||
/** Adds a mutation to remove redirected uri metadata value. */
|
||||
public static void removeRedirectedUri(ContentMetadataMutations mutations) {
|
||||
mutations.remove(METADATA_NAME_REDIRECTED_URI);
|
||||
}
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ public final class SimpleCache implements Cache {
|
|||
return;
|
||||
}
|
||||
// Check if the span conflicts with the set content length
|
||||
long length = cachedContent.getLength();
|
||||
long length = ContentMetadataInternal.getContentLength(cachedContent.getMetadata());
|
||||
if (length != C.LENGTH_UNSET) {
|
||||
Assertions.checkState((span.position + span.length) <= length);
|
||||
}
|
||||
|
|
@ -298,15 +298,14 @@ public final class SimpleCache implements Cache {
|
|||
|
||||
@Override
|
||||
public synchronized void setContentLength(String key, long length) throws CacheException {
|
||||
Assertions.checkState(!released);
|
||||
index.setContentLength(key, length);
|
||||
index.store();
|
||||
ContentMetadataMutations mutations = new ContentMetadataMutations();
|
||||
ContentMetadataInternal.setContentLength(mutations, length);
|
||||
applyContentMetadataMutations(key, mutations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getContentLength(String key) {
|
||||
Assertions.checkState(!released);
|
||||
return index.getContentLength(key);
|
||||
return ContentMetadataInternal.getContentLength(getContentMetadata(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in a new issue