Add tests to ensure DefaultRenderersFactory reflection works

Also add explicit Lint.IfChange/ThenChange rules to make it
clearer what needs to be done when changing one of the code
paths that's accessed via reflection.

PiperOrigin-RevId: 233406709
This commit is contained in:
olly 2019-02-11 15:53:57 +00:00 committed by Andrew Lewis
parent 56944caa21
commit ae12b76ac4
18 changed files with 301 additions and 5 deletions

View File

@ -38,6 +38,8 @@ dependencies {
implementation project(modulePrefix + 'library-core')
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
testImplementation project(modulePrefix + 'testutils-robolectric')
testImplementation 'junit:junit:' + junitVersion
}
ext {

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 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.
-->
<manifest package="com.google.android.exoplayer2.ext.ffmpeg"/>

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 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.ext.ffmpeg;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.DefaultRenderersFactoryAsserts;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Unit test for {@link DefaultRenderersFactoryTest} with {@link FfmpegAudioRenderer}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultRenderersFactoryTest {
@Test
public void createRenderers_instantiatesVpxRenderer() {
DefaultRenderersFactoryAsserts.assertExtensionRendererCreated(
FfmpegAudioRenderer.class, C.TRACK_TYPE_AUDIO);
}
}

View File

@ -0,0 +1 @@
manifest=src/test/AndroidManifest.xml

View File

@ -36,11 +36,12 @@ android {
}
dependencies {
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
implementation project(modulePrefix + 'library-core')
androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
androidTestImplementation project(modulePrefix + 'testutils')
androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
testImplementation project(modulePrefix + 'testutils-robolectric')
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
}
ext {

View File

@ -94,7 +94,7 @@ public final class FlacExtractor implements Extractor {
/** Constructs an instance with flags = 0. */
public FlacExtractor() {
this(0);
this(/* flags= */ 0);
}
/**

View File

@ -42,7 +42,9 @@ public class LibflacAudioRenderer extends SimpleDecoderAudioRenderer {
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output.
*/
public LibflacAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener,
public LibflacAudioRenderer(
Handler eventHandler,
AudioRendererEventListener eventListener,
AudioProcessor... audioProcessors) {
super(eventHandler, eventListener, audioProcessors);
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 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.ext.flac;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.DefaultRenderersFactoryAsserts;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Unit test for {@link DefaultRenderersFactoryTest} with {@link LibflacAudioRenderer}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultRenderersFactoryTest {
@Test
public void createRenderers_instantiatesVpxRenderer() {
DefaultRenderersFactoryAsserts.assertExtensionRendererCreated(
LibflacAudioRenderer.class, C.TRACK_TYPE_AUDIO);
}
}

View File

@ -37,6 +37,8 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
testImplementation project(modulePrefix + 'testutils-robolectric')
testImplementation 'junit:junit:' + junitVersion
androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
}

View File

@ -47,7 +47,9 @@ public final class LibopusAudioRenderer extends SimpleDecoderAudioRenderer {
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output.
*/
public LibopusAudioRenderer(Handler eventHandler, AudioRendererEventListener eventListener,
public LibopusAudioRenderer(
Handler eventHandler,
AudioRendererEventListener eventListener,
AudioProcessor... audioProcessors) {
super(eventHandler, eventListener, audioProcessors);
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 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.
-->
<manifest package="com.google.android.exoplayer2.ext.opus"/>

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 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.ext.opus;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.DefaultRenderersFactoryAsserts;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Unit test for {@link DefaultRenderersFactoryTest} with {@link LibopusAudioRenderer}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultRenderersFactoryTest {
@Test
public void createRenderers_instantiatesVpxRenderer() {
DefaultRenderersFactoryAsserts.assertExtensionRendererCreated(
LibopusAudioRenderer.class, C.TRACK_TYPE_AUDIO);
}
}

View File

@ -0,0 +1 @@
manifest=src/test/AndroidManifest.xml

View File

@ -38,6 +38,8 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
testImplementation project(modulePrefix + 'testutils-robolectric')
testImplementation 'junit:junit:' + junitVersion
androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
androidTestImplementation 'com.google.truth:truth:' + truthVersion
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2019 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.
-->
<manifest package="com.google.android.exoplayer2.ext.vp9"/>

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2019 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.ext.vp9;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.DefaultRenderersFactoryAsserts;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
/** Unit test for {@link DefaultRenderersFactoryTest} with {@link LibvpxVideoRenderer}. */
@RunWith(RobolectricTestRunner.class)
public final class DefaultRenderersFactoryTest {
@Test
public void createRenderers_instantiatesVpxRenderer() {
DefaultRenderersFactoryAsserts.assertExtensionRendererCreated(
LibvpxVideoRenderer.class, C.TRACK_TYPE_VIDEO);
}
}

View File

@ -0,0 +1 @@
manifest=src/test/AndroidManifest.xml

View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 2019 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.testutil;
import static com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
import static com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON;
import static com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER;
import static com.google.common.truth.Truth.assertThat;
import android.os.Handler;
import android.os.Looper;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.util.List;
import org.robolectric.RuntimeEnvironment;
/** Assertions for {@link DefaultRenderersFactory}. */
public final class DefaultRenderersFactoryAsserts {
/**
* Asserts that an extension renderer of type {@code clazz} is not instantiated for {@link
* DefaultRenderersFactory#EXTENSION_RENDERER_MODE_OFF}, and that it's instantiated in the correct
* position relative to other renderers of the same type for {@link
* DefaultRenderersFactory#EXTENSION_RENDERER_MODE_ON} and {@link
* DefaultRenderersFactory#EXTENSION_RENDERER_MODE_PREFER}, assuming no other extension renderers
* can be loaded.
*
* @param clazz The extension renderer class.
* @param type The type of the renderer.
*/
public static void assertExtensionRendererCreated(Class<? extends Renderer> clazz, int type) {
// In EXTENSION_RENDERER_MODE_OFF the renderer should not be created.
Renderer[] renderers = createRenderers(EXTENSION_RENDERER_MODE_OFF);
for (Renderer renderer : renderers) {
assertThat(renderer).isNotInstanceOf(clazz);
}
// In EXTENSION_RENDERER_MODE_ON the renderer should be created and last of its type.
renderers = createRenderers(EXTENSION_RENDERER_MODE_ON);
boolean found = false;
for (Renderer renderer : renderers) {
if (!found) {
if (clazz.isInstance(renderer)) {
found = true;
}
} else {
assertThat(renderer.getTrackType()).isNotEqualTo(type);
}
}
assertThat(found).isTrue();
// In EXTENSION_RENDERER_MODE_PREFER the renderer should be created and first of its type.
renderers = createRenderers(EXTENSION_RENDERER_MODE_PREFER);
found = false;
for (Renderer renderer : renderers) {
if (!found) {
if (clazz.isInstance(renderer)) {
found = true;
} else {
assertThat(renderer.getTrackType()).isNotEqualTo(type);
}
} else {
assertThat(renderer).isNotInstanceOf(clazz);
}
}
assertThat(found).isTrue();
}
private static Renderer[] createRenderers(
@DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode) {
DefaultRenderersFactory factory =
new DefaultRenderersFactory(RuntimeEnvironment.application)
.setExtensionRendererMode(extensionRendererMode);
return factory.createRenderers(
new Handler(Looper.getMainLooper()),
new VideoRendererEventListener() {},
new AudioRendererEventListener() {},
(List<Cue> cues) -> {},
(Metadata metadata) -> {},
/* drmSessionManager= */ null);
}
}