Add clearkey-based DRM playback emulator tests

These give some documentation-as-code for a clearkey integration with
ExoPlayer.

#exofixit

PiperOrigin-RevId: 398017708
This commit is contained in:
ibaker 2021-09-21 17:48:08 +01:00 committed by bachinger
parent e0a9540cd3
commit c927bc8358
4 changed files with 105 additions and 1 deletions

View File

@ -48,6 +48,7 @@ dependencies {
androidTestImplementation(project(modulePrefix + 'testutils')) {
exclude module: modulePrefix.substring(1) + 'library-core'
}
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:' + okhttpVersion
testImplementation 'com.squareup.okhttp3:mockwebserver:' + okhttpVersion
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
testImplementation project(modulePrefix + 'testutils')

View File

@ -19,11 +19,13 @@
package="com.google.android.exoplayer2.core.test">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-sdk/>
<application
android:allowBackup="false"
tools:ignore="MissingApplicationIcon,HardcodedDebugMode">
tools:ignore="MissingApplicationIcon,HardcodedDebugMode"
android:usesCleartextTraffic="true">
<provider
android:authorities="com.google.android.exoplayer2.core.test"
android:name="com.google.android.exoplayer2.upstream.TestContentProvider"/>

View File

@ -0,0 +1,101 @@
/*
* 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.drm;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.util.ConditionVariable;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Instrumentation tests for DRM playback. */
@RunWith(AndroidJUnit4.class)
public final class DrmPlaybackTest {
/** The license response needed to play the {@code drm/sample_fragmented_clearkey.mp4} file. */
// NOTE: Changing this response *should* make the test fail, but it seems the clearkey CDM
// implementation is quite robust. This means an 'invalid' response means it just incorrectly
// decrypts the content, resulting in invalid data fed to the decoder and no video shown on the
// screen (but no error thrown that's detectable by this test).
private static final String CLEARKEY_RESPONSE =
"{\"keys\":"
+ "[{"
+ "\"kty\":\"oct\","
+ "\"k\":\"Y8tfcYTdS2iaXF_xHuajKA\","
+ "\"kid\":\"zX65_4jzTK6wYYWwACTkwg\""
+ "}],"
+ "\"type\":\"temporary\"}";
@Test
public void clearkeyPlayback() throws Exception {
MockWebServer mockWebServer = new MockWebServer();
mockWebServer.enqueue(new MockResponse().setResponseCode(200).setBody(CLEARKEY_RESPONSE));
mockWebServer.start();
MediaItem mediaItem =
new MediaItem.Builder()
.setUri("asset:///media/drm/sample_fragmented_clearkey.mp4")
.setDrmConfiguration(
new MediaItem.DrmConfiguration.Builder(C.CLEARKEY_UUID)
.setLicenseUri(mockWebServer.url("license").toString())
.build())
.build();
AtomicReference<SimpleExoPlayer> player = new AtomicReference<>();
ConditionVariable playbackComplete = new ConditionVariable();
AtomicReference<PlaybackException> playbackException = new AtomicReference<>();
getInstrumentation()
.runOnMainSync(
() -> {
player.set(new ExoPlayer.Builder(getInstrumentation().getContext()).build());
player
.get()
.addListener(
new Player.Listener() {
@Override
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_ENDED) {
playbackComplete.open();
}
}
@Override
public void onPlayerError(PlaybackException error) {
playbackException.set(error);
playbackComplete.open();
}
});
player.get().setMediaItem(mediaItem);
player.get().prepare();
player.get().play();
});
playbackComplete.block();
getInstrumentation().runOnMainSync(() -> player.get().release());
getInstrumentation().waitForIdleSync();
assertThat(playbackException.get()).isNull();
}
}

Binary file not shown.