Commit af98ca66 by eguven Committed by Oliver Woodman

Refactor DashTest class

Moved DashHostedTest to top level classes. Added DashHostedTest.Builder. Move widevine offline tests to separate class with custom setUp and tearDown methods.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=146118310
parent 8f482cb2
/*
* Copyright (C) 2017 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.playbacktests.gts;
import com.google.android.exoplayer2.util.Util;
/**
* Test data for {@link DashTest} and {@link DashWidevineOfflineTest).
*/
public final class DashTestData {
// Clear content manifests.
public static final String H264_MANIFEST = "manifest-h264.mpd";
public static final String H265_MANIFEST = "manifest-h265.mpd";
public static final String VP9_MANIFEST = "manifest-vp9.mpd";
public static final String H264_23_MANIFEST = "manifest-h264-23.mpd";
public static final String H264_24_MANIFEST = "manifest-h264-24.mpd";
public static final String H264_29_MANIFEST = "manifest-h264-29.mpd";
// Widevine encrypted content manifests.
public static final String WIDEVINE_H264_MANIFEST_PREFIX = "manifest-h264-enc";
public static final String WIDEVINE_H265_MANIFEST_PREFIX = "manifest-h265-enc";
public static final String WIDEVINE_VP9_MANIFEST_PREFIX = "manifest-vp9-enc";
public static final String WIDEVINE_H264_23_MANIFEST_PREFIX = "manifest-h264-23-enc";
public static final String WIDEVINE_H264_24_MANIFEST_PREFIX = "manifest-h264-24-enc";
public static final String WIDEVINE_H264_29_MANIFEST_PREFIX = "manifest-h264-29-enc";
public static final String AAC_AUDIO_REPRESENTATION_ID = "141";
public static final String H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "avc-baseline-240";
public static final String H264_BASELINE_480P_VIDEO_REPRESENTATION_ID = "avc-baseline-480";
public static final String H264_MAIN_240P_VIDEO_REPRESENTATION_ID = "avc-main-240";
public static final String H264_MAIN_480P_VIDEO_REPRESENTATION_ID = "avc-main-480";
// The highest quality H264 format mandated by the Android CDD.
public static final String H264_CDD_FIXED = Util.SDK_INT < 23
? H264_BASELINE_480P_VIDEO_REPRESENTATION_ID : H264_MAIN_480P_VIDEO_REPRESENTATION_ID;
// Multiple H264 formats mandated by the Android CDD. Note: The CDD actually mandated main profile
// support from API level 23, but we opt to test only from 24 due to known issues on API level 23
// when switching between baseline and main profiles on certain devices.
public static final String[] H264_CDD_ADAPTIVE = Util.SDK_INT < 24
? new String[] {
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
H264_BASELINE_480P_VIDEO_REPRESENTATION_ID}
: new String[] {
H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
H264_BASELINE_480P_VIDEO_REPRESENTATION_ID,
H264_MAIN_240P_VIDEO_REPRESENTATION_ID,
H264_MAIN_480P_VIDEO_REPRESENTATION_ID};
public static final String H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID =
"avc-baseline-480-23";
public static final String H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID =
"avc-baseline-480-24";
public static final String H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID =
"avc-baseline-480-29";
public static final String H265_BASELINE_288P_VIDEO_REPRESENTATION_ID = "hevc-main-288";
public static final String H265_BASELINE_360P_VIDEO_REPRESENTATION_ID = "hevc-main-360";
// The highest quality H265 format mandated by the Android CDD.
public static final String H265_CDD_FIXED = H265_BASELINE_360P_VIDEO_REPRESENTATION_ID;
// Multiple H265 formats mandated by the Android CDD.
public static final String[] H265_CDD_ADAPTIVE =
new String[] {
H265_BASELINE_288P_VIDEO_REPRESENTATION_ID,
H265_BASELINE_360P_VIDEO_REPRESENTATION_ID};
public static final String VORBIS_AUDIO_REPRESENTATION_ID = "4";
public static final String VP9_180P_VIDEO_REPRESENTATION_ID = "0";
public static final String VP9_360P_VIDEO_REPRESENTATION_ID = "1";
// The highest quality VP9 format mandated by the Android CDD.
public static final String VP9_CDD_FIXED = VP9_360P_VIDEO_REPRESENTATION_ID;
// Multiple VP9 formats mandated by the Android CDD.
public static final String[] VP9_CDD_ADAPTIVE =
new String[] {
VP9_180P_VIDEO_REPRESENTATION_ID,
VP9_360P_VIDEO_REPRESENTATION_ID};
// Widevine encrypted content representation ids.
public static final String WIDEVINE_AAC_AUDIO_REPRESENTATION_ID = "0";
public static final String WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID = "1";
public static final String WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID = "2";
public static final String WIDEVINE_H264_MAIN_240P_VIDEO_REPRESENTATION_ID = "3";
public static final String WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID = "4";
// The highest quality H264 format mandated by the Android CDD.
public static final String WIDEVINE_H264_CDD_FIXED = Util.SDK_INT < 23
? WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID
: WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID;
// Multiple H264 formats mandated by the Android CDD. Note: The CDD actually mandated main profile
// support from API level 23, but we opt to test only from 24 due to known issues on API level 23
// when switching between baseline and main profiles on certain devices.
public static final String[] WIDEVINE_H264_CDD_ADAPTIVE = Util.SDK_INT < 24
? new String[] {
WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID}
: new String[] {
WIDEVINE_H264_BASELINE_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_BASELINE_480P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_MAIN_240P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H264_MAIN_480P_VIDEO_REPRESENTATION_ID};
public static final String WIDEVINE_H264_BASELINE_480P_23FPS_VIDEO_REPRESENTATION_ID = "2";
public static final String WIDEVINE_H264_BASELINE_480P_24FPS_VIDEO_REPRESENTATION_ID = "2";
public static final String WIDEVINE_H264_BASELINE_480P_29FPS_VIDEO_REPRESENTATION_ID = "2";
public static final String WIDEVINE_H265_BASELINE_288P_VIDEO_REPRESENTATION_ID = "1";
public static final String WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID = "2";
// The highest quality H265 format mandated by the Android CDD.
public static final String WIDEVINE_H265_CDD_FIXED =
WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID;
// Multiple H265 formats mandated by the Android CDD.
public static final String[] WIDEVINE_H265_CDD_ADAPTIVE =
new String[] {
WIDEVINE_H265_BASELINE_288P_VIDEO_REPRESENTATION_ID,
WIDEVINE_H265_BASELINE_360P_VIDEO_REPRESENTATION_ID};
public static final String WIDEVINE_VORBIS_AUDIO_REPRESENTATION_ID = "0";
public static final String WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID = "1";
public static final String WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID = "2";
// The highest quality VP9 format mandated by the Android CDD.
public static final String WIDEVINE_VP9_CDD_FIXED = VP9_360P_VIDEO_REPRESENTATION_ID;
// Multiple VP9 formats mandated by the Android CDD.
public static final String[] WIDEVINE_VP9_CDD_ADAPTIVE =
new String[] {
WIDEVINE_VP9_180P_VIDEO_REPRESENTATION_ID,
WIDEVINE_VP9_360P_VIDEO_REPRESENTATION_ID};
private DashTestData() {
}
}
/*
* Copyright (C) 2017 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.playbacktests.gts;
import android.media.MediaDrm.MediaDrmStateException;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Pair;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.drm.OfflineLicenseHelper;
import com.google.android.exoplayer2.playbacktests.util.ActionSchedule;
import com.google.android.exoplayer2.playbacktests.util.HostActivity;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import junit.framework.Assert;
/**
* Tests Widevine encrypted DASH playbacks using offline keys.
*/
public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCase2<HostActivity> {
private static final String TAG = "DashWidevineOfflineTest";
private static final String USER_AGENT = "ExoPlayerPlaybackTests";
private DashHostedTest.Builder builder;
private String widevineManifestUrl;
private DefaultHttpDataSourceFactory httpDataSourceFactory;
private OfflineLicenseHelper<FrameworkMediaCrypto> offlineLicenseHelper;
private byte[] offlineLicenseKeySetId;
public DashWidevineOfflineTest() {
super(HostActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
builder = new DashHostedTest.Builder(TAG)
.setStreamName("test_widevine_h264_fixed_offline")
.setManifestUrlForWidevine(DashTestData.WIDEVINE_H264_MANIFEST_PREFIX, MimeTypes.VIDEO_H264)
.setFullPlaybackNoSeeking(true)
.setCanIncludeAdditionalVideoFormats(false)
.setAudioVideoFormats(DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
DashTestData.WIDEVINE_H264_CDD_FIXED);
boolean useL1Widevine = DashHostedTest.isL1WidevineAvailable(MimeTypes.VIDEO_H264);
widevineManifestUrl = DashHostedTest
.getWidevineManifestUrl(DashTestData.WIDEVINE_H264_MANIFEST_PREFIX, useL1Widevine);
String widevineLicenseUrl = DashHostedTest.getWidevineLicenseUrl(useL1Widevine);
httpDataSourceFactory = new DefaultHttpDataSourceFactory(USER_AGENT);
offlineLicenseHelper = OfflineLicenseHelper.newWidevineInstance(widevineLicenseUrl,
httpDataSourceFactory);
}
@Override
protected void tearDown() throws Exception {
if (offlineLicenseKeySetId != null) {
releaseLicense();
}
if (offlineLicenseHelper != null) {
offlineLicenseHelper.releaseResources();
}
super.tearDown();
}
// Offline license tests
public void testWidevineOfflineLicense() throws Exception {
if (Util.SDK_INT < 22) {
return; // Pass.
}
downloadLicense();
builder.runTest(getActivity(), getInstrumentation());
// Renew license after playback should still work
offlineLicenseKeySetId = offlineLicenseHelper.renew(offlineLicenseKeySetId);
Assert.assertNotNull(offlineLicenseKeySetId);
}
public void testWidevineOfflineReleasedLicense() throws Throwable {
if (Util.SDK_INT < 22) {
return; // Pass.
}
downloadLicense();
releaseLicense(); // keySetId no longer valid.
try {
builder.runTest(getActivity(), getInstrumentation());
fail("Playback should fail because the license has been released.");
} catch (Throwable e) {
// Get the root cause
while (true) {
Throwable cause = e.getCause();
if (cause == null || cause == e) {
break;
}
e = cause;
}
// It should be a MediaDrmStateException instance
if (!(e instanceof MediaDrmStateException)) {
throw e;
}
}
}
public void testWidevineOfflineExpiredLicense() throws Exception {
if (Util.SDK_INT < 22) {
return; // Pass.
}
downloadLicense();
// Wait until the license expires
long licenseDuration =
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId).first;
assertTrue("License duration should be less than 30 sec. "
+ "Server settings might have changed.", licenseDuration < 30);
while (licenseDuration > 0) {
synchronized (this) {
wait(licenseDuration * 1000 + 2000);
}
long previousDuration = licenseDuration;
licenseDuration =
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId).first;
assertTrue("License duration should be decreasing.", previousDuration > licenseDuration);
}
// DefaultDrmSessionManager should renew the license and stream play fine
builder.runTest(getActivity(), getInstrumentation());
}
public void testWidevineOfflineLicenseExpiresOnPause() throws Exception {
if (Util.SDK_INT < 22) {
return; // Pass.
}
downloadLicense();
// During playback pause until the license expires then continue playback
Pair<Long, Long> licenseDurationRemainingSec =
offlineLicenseHelper.getLicenseDurationRemainingSec(offlineLicenseKeySetId);
long licenseDuration = licenseDurationRemainingSec.first;
assertTrue("License duration should be less than 30 sec. "
+ "Server settings might have changed.", licenseDuration < 30);
ActionSchedule schedule = new ActionSchedule.Builder(TAG)
.delay(3000).pause().delay(licenseDuration * 1000 + 2000).play().build();
// DefaultDrmSessionManager should renew the license and stream play fine
builder
.setActionSchedule(schedule)
.runTest(getActivity(), getInstrumentation());
}
private void downloadLicense() throws InterruptedException, DrmSessionException, IOException {
offlineLicenseKeySetId = offlineLicenseHelper.download(
httpDataSourceFactory.createDataSource(), widevineManifestUrl);
Assert.assertNotNull(offlineLicenseKeySetId);
Assert.assertTrue(offlineLicenseKeySetId.length > 0);
builder.setOfflineLicenseKeySetId(offlineLicenseKeySetId);
}
private void releaseLicense() throws DrmSessionException {
offlineLicenseHelper.release(offlineLicenseKeySetId);
offlineLicenseKeySetId = null;
}
}
......@@ -63,7 +63,8 @@ public abstract class ExoHostedTest implements HostedTest, ExoPlayer.EventListen
public static final long EXPECTED_PLAYING_TIME_MEDIA_DURATION_MS = -2;
public static final long EXPECTED_PLAYING_TIME_UNSET = -1;
private final String tag;
protected final String tag;
private final boolean failOnPlayerError;
private final long expectedPlayingTimeMs;
private final DecoderCounters videoDecoderCounters;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment