mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Merge pull request #1870 from colinkho:fwd-extractor-clz
PiperOrigin-RevId: 701313111
This commit is contained in:
commit
f113a78e0d
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.extractor;
|
||||||
|
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An overridable {@link Extractor} implementation which forwards all methods to another {@link
|
||||||
|
* Extractor}.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
public class ForwardingExtractor implements Extractor {
|
||||||
|
private final Extractor delegate;
|
||||||
|
|
||||||
|
public ForwardingExtractor(Extractor delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean sniff(ExtractorInput input) throws IOException {
|
||||||
|
return delegate.sniff(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SniffFailure> getSniffFailureDetails() {
|
||||||
|
return delegate.getSniffFailureDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ExtractorOutput output) {
|
||||||
|
delegate.init(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @ReadResult int read(ExtractorInput input, PositionHolder seekPosition)
|
||||||
|
throws IOException {
|
||||||
|
return delegate.read(input, seekPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seek(long position, long timeUs) {
|
||||||
|
delegate.seek(position, timeUs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
delegate.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Extractor getUnderlyingImplementation() {
|
||||||
|
return delegate.getUnderlyingImplementation();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.extractor;
|
||||||
|
|
||||||
|
import androidx.media3.common.C;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An overridable {@link ExtractorOutput} implementation which forwards all methods to another
|
||||||
|
* {@link ExtractorOutput}.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
public class ForwardingExtractorOutput implements ExtractorOutput {
|
||||||
|
private final ExtractorOutput output;
|
||||||
|
|
||||||
|
public ForwardingExtractorOutput(ExtractorOutput output) {
|
||||||
|
this.output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackOutput track(int id, @C.TrackType int type) {
|
||||||
|
return output.track(id, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endTracks() {
|
||||||
|
output.endTracks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void seekMap(SeekMap seekMap) {
|
||||||
|
output.seekMap(seekMap);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.extractor;
|
||||||
|
|
||||||
|
import static androidx.media3.test.utils.TestUtil.assertForwardingClassForwardsAllMethods;
|
||||||
|
import static androidx.media3.test.utils.TestUtil.assertForwardingClassOverridesAllMethods;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ForwardingExtractorOutputTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void overridesAllMethods() throws Exception {
|
||||||
|
assertForwardingClassOverridesAllMethods(
|
||||||
|
ExtractorOutput.class, ForwardingExtractorOutput.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forwardsAllMethods() throws Exception {
|
||||||
|
assertForwardingClassForwardsAllMethods(ExtractorOutput.class, ForwardingExtractorOutput::new);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 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.extractor;
|
||||||
|
|
||||||
|
import static androidx.media3.test.utils.TestUtil.assertForwardingClassForwardsAllMethods;
|
||||||
|
import static androidx.media3.test.utils.TestUtil.assertForwardingClassOverridesAllMethods;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ForwardingExtractorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void overridesAllMethods() throws Exception {
|
||||||
|
assertForwardingClassOverridesAllMethods(Extractor.class, ForwardingExtractor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void forwardsAllMethods() throws Exception {
|
||||||
|
assertForwardingClassForwardsAllMethods(Extractor.class, ForwardingExtractor::new);
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ package androidx.media3.test.utils;
|
|||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
@ -36,6 +38,7 @@ import androidx.media3.common.MediaMetadata;
|
|||||||
import androidx.media3.common.StreamKey;
|
import androidx.media3.common.StreamKey;
|
||||||
import androidx.media3.common.Timeline;
|
import androidx.media3.common.Timeline;
|
||||||
import androidx.media3.common.TrackGroup;
|
import androidx.media3.common.TrackGroup;
|
||||||
|
import androidx.media3.common.util.NullableType;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.database.DatabaseProvider;
|
import androidx.media3.database.DatabaseProvider;
|
||||||
@ -51,6 +54,7 @@ import androidx.media3.extractor.ExtractorInput;
|
|||||||
import androidx.media3.extractor.PositionHolder;
|
import androidx.media3.extractor.PositionHolder;
|
||||||
import androidx.media3.extractor.SeekMap;
|
import androidx.media3.extractor.SeekMap;
|
||||||
import androidx.media3.extractor.metadata.MetadataInputBuffer;
|
import androidx.media3.extractor.metadata.MetadataInputBuffer;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.BoundType;
|
import com.google.common.collect.BoundType;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
@ -63,6 +67,8 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -78,6 +84,7 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
/** Utility methods for tests. */
|
/** Utility methods for tests. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -618,6 +625,52 @@ public class TestUtil {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use reflection to assert that every method declared on {@code superType} is overridden by
|
||||||
|
* {@code forwardingType}.
|
||||||
|
*/
|
||||||
|
public static <T> void assertForwardingClassOverridesAllMethods(
|
||||||
|
Class<T> superType, Class<? extends T> forwardingType) throws NoSuchMethodException {
|
||||||
|
for (Method method : TestUtil.getPublicMethods(superType)) {
|
||||||
|
assertThat(
|
||||||
|
forwardingType
|
||||||
|
.getDeclaredMethod(method.getName(), method.getParameterTypes())
|
||||||
|
.getDeclaringClass())
|
||||||
|
.isEqualTo(forwardingType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use reflection to assert calling every method declared on {@code superType} on an instance of
|
||||||
|
* {@code forwardingType} results in the call being forwarded to the {@code superType} delegate.
|
||||||
|
*/
|
||||||
|
// The nullness checker is deliberately over-conservative and doesn't permit passing a null
|
||||||
|
// parameter to method.invoke(), even if the real method does accept null. Regardless, we expect
|
||||||
|
// the null to be passed straight to our mocked delegate, so it's OK to pass null even for
|
||||||
|
// non-null parameters. See also
|
||||||
|
// https://github.com/typetools/checker-framework/blob/c26bb695ebc572fac1e9cd2e331fc5b9d3953ec0/checker/jdk/nullness/src/java/lang/reflect/Method.java#L109
|
||||||
|
@SuppressWarnings("nullness:argument.type.incompatible")
|
||||||
|
public static <T extends @NonNull Object, F extends T>
|
||||||
|
void assertForwardingClassForwardsAllMethods(
|
||||||
|
Class<T> superType, Function<T, F> forwardingInstanceFactory)
|
||||||
|
throws InvocationTargetException, IllegalAccessException {
|
||||||
|
for (Method method : getPublicMethods(superType)) {
|
||||||
|
T delegate = mock(superType);
|
||||||
|
F forwardingInstance = forwardingInstanceFactory.apply(delegate);
|
||||||
|
@NullableType Object[] parameters = new Object[method.getParameterCount()];
|
||||||
|
for (int i = 0; i < method.getParameterCount(); i++) {
|
||||||
|
// Get a default value of the right type by creating a single-element array. This gives us
|
||||||
|
// null for object types, and the 'default' value for primitives.
|
||||||
|
parameters[i] = Array.get(Array.newInstance(method.getParameterTypes()[i], 1), 0);
|
||||||
|
}
|
||||||
|
method.invoke(forwardingInstance, parameters);
|
||||||
|
|
||||||
|
// Reflective version of verify(delegate).method(parameters), to assert the expected method
|
||||||
|
// was invoked on the delegate instance.
|
||||||
|
method.invoke(verify(delegate), parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a {@link MediaItem} that has all fields set to non-default values. */
|
/** Returns a {@link MediaItem} that has all fields set to non-default values. */
|
||||||
public static MediaItem buildFullyCustomizedMediaItem() {
|
public static MediaItem buildFullyCustomizedMediaItem() {
|
||||||
return new MediaItem.Builder()
|
return new MediaItem.Builder()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user