| /* |
| * Copyright (C) 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 android.mediapc.cts; |
| |
| import static android.media.MediaCodecInfo.CodecCapabilities.FEATURE_SecurePlayback; |
| import static android.media.MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL; |
| import static org.junit.Assert.assertTrue; |
| |
| import android.app.ActivityManager; |
| import android.content.Context; |
| import android.content.pm.PackageManager; |
| import android.media.MediaCodecInfo; |
| import android.media.MediaCodecList; |
| import android.media.MediaDrm; |
| import android.media.MediaFormat; |
| import android.media.UnsupportedSchemeException; |
| import android.mediapc.cts.common.PerformanceClassEvaluator; |
| import android.mediapc.cts.common.Utils; |
| import android.util.DisplayMetrics; |
| import android.util.Log; |
| import android.view.WindowManager; |
| import androidx.test.filters.SmallTest; |
| import androidx.test.platform.app.InstrumentationRegistry; |
| import com.android.compatibility.common.util.CddTest; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.UUID; |
| import org.junit.Assume; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TestName; |
| |
| /** |
| * Tests the basic aspects of the media performance class. |
| */ |
| public class PerformanceClassTest { |
| private static final String TAG = "PerformanceClassTest"; |
| public static final String[] VIDEO_CONTAINER_MEDIA_TYPES = |
| {"video/mp4", "video/webm", "video/3gpp", "video/3gpp2", "video/avi", "video/x-ms-wmv", |
| "video/x-ms-asf"}; |
| static ArrayList<String> mMimeSecureSupport = new ArrayList<>(); |
| |
| @Rule |
| public final TestName mTestName = new TestName(); |
| |
| static { |
| mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_AVC); |
| mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_HEVC); |
| mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_VP9); |
| mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_AV1); |
| } |
| |
| |
| private boolean isHandheld() { |
| // handheld nature is not exposed to package manager, for now |
| // we check for touchscreen and NOT watch and NOT tv |
| PackageManager pm = |
| InstrumentationRegistry.getInstrumentation().getContext().getPackageManager(); |
| return pm.hasSystemFeature(pm.FEATURE_TOUCHSCREEN) |
| && !pm.hasSystemFeature(pm.FEATURE_WATCH) |
| && !pm.hasSystemFeature(pm.FEATURE_TELEVISION) |
| && !pm.hasSystemFeature(pm.FEATURE_AUTOMOTIVE); |
| } |
| |
| @SmallTest |
| @Test |
| @CddTest(requirements = {"2.2.7.1/5.1/H-1-11"}) |
| public void testSecureHwDecodeSupport() { |
| ArrayList<String> noSecureHwDecoderForMimes = new ArrayList<>(); |
| for (String mime : mMimeSecureSupport) { |
| boolean isSecureHwDecoderFoundForMime = false; |
| boolean isHwDecoderFoundForMime = false; |
| MediaCodecList codecList = new MediaCodecList(MediaCodecList.ALL_CODECS); |
| MediaCodecInfo[] codecInfos = codecList.getCodecInfos(); |
| for (MediaCodecInfo info : codecInfos) { |
| if (info.isEncoder() || !info.isHardwareAccelerated() || info.isAlias()) continue; |
| try { |
| MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime); |
| if (caps != null) { |
| isHwDecoderFoundForMime = true; |
| if (caps.isFeatureSupported(FEATURE_SecurePlayback)) |
| isSecureHwDecoderFoundForMime = true; |
| } |
| } catch (Exception ignored) { |
| } |
| } |
| if (isHwDecoderFoundForMime && !isSecureHwDecoderFoundForMime) |
| noSecureHwDecoderForMimes.add(mime); |
| } |
| |
| boolean secureDecodeSupportIfHwDecoderPresent = noSecureHwDecoderForMimes.isEmpty(); |
| |
| PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); |
| PerformanceClassEvaluator.SecureCodecRequirement r5_1__H_1_11 = pce.addR5_1__H_1_11(); |
| r5_1__H_1_11.setSecureReqSatisfied(secureDecodeSupportIfHwDecoderPresent); |
| |
| pce.submitAndCheck(); |
| } |
| |
| @SmallTest |
| @Test |
| @CddTest(requirements = {"2.2.7.1/5.7/H-1-2"}) |
| public void testMediaDrmSecurityLevelHwSecureAll() throws UnsupportedSchemeException { |
| List<UUID> drmList = MediaDrm.getSupportedCryptoSchemes(); |
| List<UUID> supportedHwSecureAllSchemes = new ArrayList<>(); |
| |
| for (UUID cryptoSchemeUUID : drmList) { |
| boolean cryptoSchemeSupportedForAtleastOneMediaType = false; |
| for (String mediaType : VIDEO_CONTAINER_MEDIA_TYPES) { |
| cryptoSchemeSupportedForAtleastOneMediaType |= MediaDrm |
| .isCryptoSchemeSupported(cryptoSchemeUUID, mediaType, |
| SECURITY_LEVEL_HW_SECURE_ALL); |
| } |
| if (cryptoSchemeSupportedForAtleastOneMediaType) { |
| supportedHwSecureAllSchemes.add(cryptoSchemeUUID); |
| } |
| } |
| |
| PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); |
| PerformanceClassEvaluator.SecureCodecRequirement r5_7__H_1_2 = pce.addR5_7__H_1_2(); |
| |
| r5_7__H_1_2.setNumCryptoHwSecureAllDec(supportedHwSecureAllSchemes.size()); |
| |
| pce.submitAndCheck(); |
| } |
| |
| @SmallTest |
| @Test |
| public void testMediaPerformanceClassScope() throws Exception { |
| // if device is not of a performance class, we are done. |
| Assume.assumeTrue("not a device of a valid media performance class", Utils.isPerfClass()); |
| |
| if (Utils.isPerfClass()) { |
| assertTrue("performance class is only defined for Handheld devices", isHandheld()); |
| } |
| } |
| |
| @Test |
| @CddTest(requirements={ |
| "2.2.7.3/7.1.1.1/H-1-1", |
| "2.2.7.3/7.1.1.1/H-2-1", |
| "2.2.7.3/7.1.1.3/H-1-1", |
| "2.2.7.3/7.1.1.3/H-2-1",}) |
| public void testMinimumResolutionAndDensity() { |
| Context context = InstrumentationRegistry.getInstrumentation().getContext(); |
| |
| // Verify display DPI. We only seem to be able to get the primary display. |
| DisplayMetrics metrics = new DisplayMetrics(); |
| WindowManager windowManager = |
| (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); |
| windowManager.getDefaultDisplay().getMetrics(metrics); |
| int density = metrics.densityDpi; |
| int longPix = Math.max(metrics.widthPixels, metrics.heightPixels); |
| int shortPix = Math.min(metrics.widthPixels, metrics.heightPixels); |
| |
| Log.i(TAG, String.format("dpi=%d size=%dx%dpix", density, longPix, shortPix)); |
| |
| PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); |
| PerformanceClassEvaluator.ResolutionRequirement r7_1_1_1__h_1_1 = pce.addR7_1_1_1__H_1_1(); |
| PerformanceClassEvaluator.DensityRequirement r7_1_1_3__h_1_1 = pce.addR7_1_1_3__H_1_1(); |
| PerformanceClassEvaluator.ResolutionRequirement r7_1_1_1__h_2_1 = pce.addR7_1_1_1__H_2_1(); |
| PerformanceClassEvaluator.DensityRequirement r7_1_1_3__h_2_1 = pce.addR7_1_1_3__H_2_1(); |
| |
| r7_1_1_1__h_1_1.setLongResolution(longPix); |
| r7_1_1_1__h_2_1.setLongResolution(longPix); |
| |
| r7_1_1_1__h_1_1.setShortResolution(shortPix); |
| r7_1_1_1__h_2_1.setShortResolution(shortPix); |
| |
| r7_1_1_3__h_1_1.setDisplayDensity(density); |
| r7_1_1_3__h_2_1.setDisplayDensity(density); |
| |
| pce.submitAndCheck(); |
| } |
| |
| @Test |
| @CddTest(requirements={ |
| "2.2.7.3/7.6.1/H-1-1", |
| "2.2.7.3/7.6.1/H-2-1",}) |
| public void testMinimumMemory() { |
| Context context = InstrumentationRegistry.getInstrumentation().getContext(); |
| |
| // Verify minimum memory |
| ActivityManager activityManager = context.getSystemService(ActivityManager.class); |
| long totalMemoryMb = getTotalMemory(activityManager) / 1024 / 1024; |
| |
| Log.i(TAG, String.format("Total device memory = %,d MB", totalMemoryMb)); |
| |
| PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); |
| PerformanceClassEvaluator.MemoryRequirement r7_6_1_h_1_1 = pce.addR7_6_1__H_1_1(); |
| PerformanceClassEvaluator.MemoryRequirement r7_6_1_h_2_1 = pce.addR7_6_1__H_2_1(); |
| |
| r7_6_1_h_1_1.setPhysicalMemory(totalMemoryMb); |
| r7_6_1_h_2_1.setPhysicalMemory(totalMemoryMb); |
| |
| pce.submitAndCheck(); |
| } |
| |
| /** |
| * @return the total memory accessible by the kernel as defined by |
| * {@code ActivityManager.MemoryInfo}. |
| */ |
| private long getTotalMemory(ActivityManager activityManager) { |
| ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); |
| activityManager.getMemoryInfo(memoryInfo); |
| return memoryInfo.totalMem; |
| } |
| } |