• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the Licnse.
15  */
16 
17 package android.mediapc.cts.common;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.junit.Assume.assumeTrue;
22 
23 import android.hardware.camera2.CameraMetadata;
24 import android.media.MediaFormat;
25 import android.os.Build;
26 import android.util.Log;
27 
28 import androidx.test.platform.app.InstrumentationRegistry;
29 
30 import com.android.compatibility.common.util.DeviceReportLog;
31 import com.android.cts.verifier.CtsVerifierReportLog;
32 
33 import com.google.common.base.Preconditions;
34 
35 import org.junit.rules.TestName;
36 
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.HashSet;
40 import java.util.Set;
41 
42 /**
43  * Logs a set of measurements and results for defined performance class requirements.
44  *
45  * <p> Nested classes are organized alphabetically, add[Requirement] functions are organized by
46  * their requirement number in the order they appear in the Android CDD
47  */
48 public class PerformanceClassEvaluator {
49     private static final String TAG = PerformanceClassEvaluator.class.getSimpleName();
50 
51     private final String mTestName;
52     private Set<Requirement> mRequirements;
53 
PerformanceClassEvaluator(TestName testName)54     public PerformanceClassEvaluator(TestName testName) {
55         Preconditions.checkNotNull(testName);
56         String baseTestName = testName.getMethodName() != null ? testName.getMethodName() : "";
57         this.mTestName = baseTestName.replace("{", "(").replace("}", ")");
58         this.mRequirements = new HashSet<Requirement>();
59     }
60 
getTestName()61     String getTestName() {
62         return mTestName;
63     }
64 
65     public static class AudioTap2ToneLatencyRequirement extends Requirement {
66         private static final String TAG = AudioTap2ToneLatencyRequirement.class.getSimpleName();
67 
AudioTap2ToneLatencyRequirement(String id, RequiredMeasurement<?> ... reqs)68         private AudioTap2ToneLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) {
69             super(id, reqs);
70         }
71 
setNativeLatency(double latency)72         public void setNativeLatency(double latency) {
73             this.setMeasuredValue(RequirementConstants.API_NATIVE_LATENCY, latency);
74         }
75 
setJavaLatency(double latency)76         public void setJavaLatency(double latency) {
77             this.setMeasuredValue(RequirementConstants.API_JAVA_LATENCY, latency);
78         }
79 
createR5_6__H_1_1()80         public static AudioTap2ToneLatencyRequirement createR5_6__H_1_1() {
81             RequiredMeasurement<Double> apiNativeLatency = RequiredMeasurement
82                     .<Double>builder()
83                     .setId(RequirementConstants.API_NATIVE_LATENCY)
84                     .setPredicate(RequirementConstants.DOUBLE_LTE)
85                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 80.0)
86                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
87                     .addRequiredValue(Build.VERSION_CODES.S, 100.0)
88                     .addRequiredValue(Build.VERSION_CODES.R, 100.0)
89                     .build();
90             RequiredMeasurement<Double> apiJavaLatency = RequiredMeasurement
91                     .<Double>builder()
92                     .setId(RequirementConstants.API_JAVA_LATENCY)
93                     .setPredicate(RequirementConstants.DOUBLE_LTE)
94                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 80.0)
95                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
96                     .addRequiredValue(Build.VERSION_CODES.S, 100.0)
97                     .addRequiredValue(Build.VERSION_CODES.R, 100.0)
98                     .build();
99 
100             return new AudioTap2ToneLatencyRequirement(
101                     RequirementConstants.R5_6__H_1_1,
102                     apiNativeLatency,
103                     apiJavaLatency);
104         }
105     }
106 
107     public static class Camera240FpsRequirement extends Requirement {
108         private static final String TAG = Camera240FpsRequirement.class.getSimpleName();
109 
Camera240FpsRequirement(String id, RequiredMeasurement<?> ... reqs)110         private Camera240FpsRequirement(String id, RequiredMeasurement<?> ... reqs) {
111             super(id, reqs);
112         }
113 
setRear240FpsSupported(boolean rear240FpsSupported)114         public void setRear240FpsSupported(boolean rear240FpsSupported) {
115             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED,
116                     rear240FpsSupported);
117         }
118 
119         /**
120          * [2.2.7.2/7.5/H-1-9] MUST have a rear-facing primary camera supporting 720p
121          * or 1080p @ 240fps.
122          */
create240FpsReq()123         public static Camera240FpsRequirement create240FpsReq() {
124             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
125                     .<Boolean>builder()
126                     .setId(RequirementConstants.REAR_CAMERA_240FPS_SUPPORTED)
127                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
128                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
129                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
130                     .build();
131 
132             return new Camera240FpsRequirement(RequirementConstants.R7_5__H_1_9, requirement);
133         }
134     }
135 
136     public static class CameraExtensionRequirement extends Requirement {
137         private static final String TAG =
138                 CameraExtensionRequirement.class.getSimpleName();
139 
140         public static int PRIMARY_REAR_CAMERA = 0;
141         public static int PRIMARY_FRONT_CAMERA = 1;
142 
CameraExtensionRequirement(String id, RequiredMeasurement<?> ... reqs)143         private CameraExtensionRequirement(String id, RequiredMeasurement<?> ... reqs) {
144             super(id, reqs);
145         }
146 
setCamera2NightExtensionSupported(int camera, boolean supported)147         public void setCamera2NightExtensionSupported(int camera, boolean supported) {
148             if (camera == PRIMARY_REAR_CAMERA) {
149                 this.setMeasuredValue(RequirementConstants.REAR_CAMERA2_EXTENSION_NIGHT_SUPPORTED,
150                         supported);
151             } else if (camera == PRIMARY_FRONT_CAMERA) {
152                 this.setMeasuredValue(RequirementConstants.FRONT_CAMERA2_EXTENSION_NIGHT_SUPPORTED,
153                         supported);
154             }
155         }
156 
setCameraXNightExtensionSupported(int camera, boolean supported)157         public void setCameraXNightExtensionSupported(int camera, boolean supported) {
158             if (camera == PRIMARY_REAR_CAMERA) {
159                 this.setMeasuredValue(RequirementConstants.REAR_CAMERAX_EXTENSION_NIGHT_SUPPORTED,
160                         supported);
161             } else if (camera == PRIMARY_FRONT_CAMERA) {
162                 this.setMeasuredValue(RequirementConstants.FRONT_CAMERAX_EXTENSION_NIGHT_SUPPORTED,
163                         supported);
164             }
165         }
166 
167         /**
168          * [2.2.7.2/7.5/H-1-15] MUST support Night mode extensions via both CameraX and
169          * Camera2 extensions for primary cameras.
170          */
createCameraExtensionReq()171         public static CameraExtensionRequirement createCameraExtensionReq() {
172             RequiredMeasurement<Boolean> rearCamera2NightRequirement = RequiredMeasurement
173                     .<Boolean>builder()
174                     .setId(RequirementConstants.REAR_CAMERA2_EXTENSION_NIGHT_SUPPORTED)
175                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
176                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
177                     .build();
178             RequiredMeasurement<Boolean> frontCamera2NightRequirement = RequiredMeasurement
179                     .<Boolean>builder()
180                     .setId(RequirementConstants.FRONT_CAMERA2_EXTENSION_NIGHT_SUPPORTED)
181                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
182                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
183                     .build();
184 
185             RequiredMeasurement<Boolean> rearCameraXNightRequirement = RequiredMeasurement
186                     .<Boolean>builder()
187                     .setId(RequirementConstants.REAR_CAMERAX_EXTENSION_NIGHT_SUPPORTED)
188                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
189                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
190                     .build();
191             RequiredMeasurement<Boolean> frontCameraXNightRequirement = RequiredMeasurement
192                     .<Boolean>builder()
193                     .setId(RequirementConstants.FRONT_CAMERAX_EXTENSION_NIGHT_SUPPORTED)
194                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
195                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
196                     .build();
197 
198             return new CameraExtensionRequirement(RequirementConstants.R7_5__H_1_15,
199                     rearCamera2NightRequirement, frontCamera2NightRequirement,
200                     rearCameraXNightRequirement, frontCameraXNightRequirement);
201         }
202     }
203 
204     public static class CameraLatencyRequirement extends Requirement {
205         private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
206 
CameraLatencyRequirement(String id, RequiredMeasurement<?> ... reqs)207         private CameraLatencyRequirement(String id, RequiredMeasurement<?> ... reqs) {
208             super(id, reqs);
209         }
210 
setRearCameraLatency(float latency)211         public void setRearCameraLatency(float latency) {
212             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LATENCY, latency);
213         }
214 
setFrontCameraLatency(float latency)215         public void setFrontCameraLatency(float latency) {
216             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LATENCY, latency);
217         }
218 
219         /**
220          * [2.2.7.2/7.5/H-1-5] MUST have camera2 JPEG capture latency < 1000ms for 1080p resolution
221          * as measured by the CTS camera PerformanceTest under ITS lighting conditions
222          * (3000K) for both primary cameras.
223          */
createJpegLatencyReq()224         public static CameraLatencyRequirement createJpegLatencyReq() {
225             RequiredMeasurement<Float> rearJpegLatency = RequiredMeasurement
226                     .<Float>builder()
227                     .setId(RequirementConstants.REAR_CAMERA_LATENCY)
228                     .setPredicate(RequirementConstants.FLOAT_LTE)
229                     .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
230                     .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
231                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
232                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1000.0f)
233                     .build();
234             RequiredMeasurement<Float> frontJpegLatency = RequiredMeasurement
235                     .<Float>builder()
236                     .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
237                     .setPredicate(RequirementConstants.FLOAT_LTE)
238                     .addRequiredValue(Build.VERSION_CODES.R, 1000.0f)
239                     .addRequiredValue(Build.VERSION_CODES.S, 1000.0f)
240                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1000.0f)
241                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1000.0f)
242                     .build();
243 
244             return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_5,
245                     rearJpegLatency, frontJpegLatency);
246         }
247 
248         /**
249          * [2.2.7.2/7.5/H-1-6] MUST have camera2 startup latency (open camera to first
250          * preview frame) < 600ms (S and below) or 500ms (T and above) as measured by the CTS camera
251          * PerformanceTest under ITS lighting conditions (3000K) for both primary cameras.
252          */
createLaunchLatencyReq()253         public static CameraLatencyRequirement createLaunchLatencyReq() {
254             RequiredMeasurement<Float> rearLaunchLatency = RequiredMeasurement
255                     .<Float>builder()
256                     .setId(RequirementConstants.REAR_CAMERA_LATENCY)
257                     .setPredicate(RequirementConstants.FLOAT_LTE)
258                     .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
259                     .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
260                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 500.0f)
261                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 500.0f)
262                     .build();
263             RequiredMeasurement<Float> frontLaunchLatency = RequiredMeasurement
264                     .<Float>builder()
265                     .setId(RequirementConstants.FRONT_CAMERA_LATENCY)
266                     .setPredicate(RequirementConstants.FLOAT_LTE)
267                     .addRequiredValue(Build.VERSION_CODES.R, 600.0f)
268                     .addRequiredValue(Build.VERSION_CODES.S, 600.0f)
269                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 500.0f)
270                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 500.0f)
271                     .build();
272 
273             return new CameraLatencyRequirement(RequirementConstants.R7_5__H_1_6,
274                     rearLaunchLatency, frontLaunchLatency);
275         }
276     }
277 
278     public static class CameraRawRequirement extends Requirement {
279         private static final String TAG = CameraRawRequirement.class.getSimpleName();
280 
CameraRawRequirement(String id, RequiredMeasurement<?> ... reqs)281         private CameraRawRequirement(String id, RequiredMeasurement<?> ... reqs) {
282             super(id, reqs);
283         }
284 
setRearRawSupported(boolean rearRawSupported)285         public void setRearRawSupported(boolean rearRawSupported) {
286             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED,
287                     rearRawSupported);
288         }
289 
290         /**
291          * [2.2.7.2/7.5/H-1-8] MUST support CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW and
292          * android.graphics.ImageFormat.RAW_SENSOR for the primary back camera.
293          */
createRawReq()294         public static CameraRawRequirement createRawReq() {
295             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
296                     .<Boolean>builder()
297                     .setId(RequirementConstants.REAR_CAMERA_RAW_SUPPORTED)
298                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
299                     .addRequiredValue(Build.VERSION_CODES.S, true)
300                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
301                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
302                     .build();
303 
304             return new CameraRawRequirement(RequirementConstants.R7_5__H_1_8, requirement);
305         }
306     }
307 
308     public static class CameraTimestampSourceRequirement extends Requirement {
309         private static final String TAG = CameraTimestampSourceRequirement.class.getSimpleName();
310         private static final int TIMESTAMP_REALTIME =
311                 CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME;
312 
CameraTimestampSourceRequirement(String id, RequiredMeasurement<?> ... reqs)313         private CameraTimestampSourceRequirement(String id, RequiredMeasurement<?> ... reqs) {
314             super(id, reqs);
315         }
316 
setRearCameraTimestampSource(Integer timestampSource)317         public void setRearCameraTimestampSource(Integer timestampSource) {
318             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE,
319                     timestampSource);
320         }
321 
setFrontCameraTimestampSource(Integer timestampSource)322         public void setFrontCameraTimestampSource(Integer timestampSource) {
323             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE,
324                     timestampSource);
325         }
326         /**
327          * [2.2.7.2/7.5/H-1-4] MUST support CameraMetadata.SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME
328          * for both primary cameras.
329          */
createTimestampSourceReq()330         public static CameraTimestampSourceRequirement createTimestampSourceReq() {
331             RequiredMeasurement<Integer> rearTimestampSource = RequiredMeasurement
332                     .<Integer>builder()
333                     .setId(RequirementConstants.REAR_CAMERA_TIMESTAMP_SOURCE)
334                     .setPredicate(RequirementConstants.INTEGER_EQ)
335                     .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
336                     .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
337                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
338                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, TIMESTAMP_REALTIME)
339                     .build();
340             RequiredMeasurement<Integer> frontTimestampSource = RequiredMeasurement
341                     .<Integer>builder()
342                     .setId(RequirementConstants.FRONT_CAMERA_TIMESTAMP_SOURCE)
343                     .setPredicate(RequirementConstants.INTEGER_EQ)
344                     .addRequiredValue(Build.VERSION_CODES.R, TIMESTAMP_REALTIME)
345                     .addRequiredValue(Build.VERSION_CODES.S, TIMESTAMP_REALTIME)
346                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, TIMESTAMP_REALTIME)
347                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, TIMESTAMP_REALTIME)
348                     .build();
349 
350             return new CameraTimestampSourceRequirement(RequirementConstants.R7_5__H_1_4,
351                     rearTimestampSource, frontTimestampSource);
352         }
353     }
354 
355     public static class CodecInitLatencyRequirement extends Requirement {
356 
357         private static final String TAG = CodecInitLatencyRequirement.class.getSimpleName();
358 
CodecInitLatencyRequirement(String id, RequiredMeasurement<?>... reqs)359         private CodecInitLatencyRequirement(String id, RequiredMeasurement<?>... reqs) {
360             super(id, reqs);
361         }
362 
setCodecInitLatencyMs(long codecInitLatencyMs)363         public void setCodecInitLatencyMs(long codecInitLatencyMs) {
364             this.setMeasuredValue(RequirementConstants.CODEC_INIT_LATENCY, codecInitLatencyMs);
365         }
366 
367         /**
368          * [2.2.7.1/5.1/H-1-7] MUST have a codec initialization latency of 65(R) / 50(S) / 40(T)
369          * ms or less for a 1080p or smaller video encoding session for all hardware video
370          * encoders when under load. Load here is defined as a concurrent 1080p to 720p
371          * video-only transcoding session using hardware video codecs together with the 1080p
372          * audio-video recording initialization. For Dolby vision codec, the codec initialization
373          * latency MUST be 50 ms or less.
374          */
createR5_1__H_1_7(String mediaType)375         public static CodecInitLatencyRequirement createR5_1__H_1_7(String mediaType) {
376             long latency = mediaType.equals(MediaFormat.MIMETYPE_VIDEO_DOLBY_VISION) ? 50L : 40L;
377             RequiredMeasurement<Long> codec_init_latency =
378                 RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
379                         .setPredicate(RequirementConstants.LONG_LTE)
380                         .addRequiredValue(Build.VERSION_CODES.R, 65L)
381                         .addRequiredValue(Build.VERSION_CODES.S, 50L)
382                         .addRequiredValue(Build.VERSION_CODES.TIRAMISU, latency)
383                         .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, latency)
384                         .build();
385 
386             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_7,
387                 codec_init_latency);
388         }
389 
390         /**
391          * [2.2.7.1/5.1/H-1-8] MUST have a codec initialization latency of 50(R) / 40(S) / 30(T)
392          * ms or less for a 128 kbps or lower bitrate audio encoding session for all audio
393          * encoders when under load. Load here is defined as a concurrent 1080p to 720p
394          * video-only transcoding session using hardware video codecs together with the 1080p
395          * audio-video recording initialization.
396          */
createR5_1__H_1_8()397         public static CodecInitLatencyRequirement createR5_1__H_1_8() {
398             RequiredMeasurement<Long> codec_init_latency =
399                 RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
400                         .setPredicate(RequirementConstants.LONG_LTE)
401                         .addRequiredValue(Build.VERSION_CODES.R, 50L)
402                         .addRequiredValue(Build.VERSION_CODES.S, 40L)
403                         .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L)
404                         .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 30L)
405                         .build();
406 
407             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_8,
408                 codec_init_latency);
409         }
410 
411         /**
412          * [2.2.7.1/5.1/H-1-12] Codec initialization latency of 40ms or less for a 1080p or
413          * smaller video decoding session for all hardware video encoders when under load. Load
414          * here is defined as a concurrent 1080p to 720p video-only transcoding session using
415          * hardware video codecs together with the 1080p audio-video recording initialization.
416          */
createR5_1__H_1_12()417         public static CodecInitLatencyRequirement createR5_1__H_1_12() {
418             RequiredMeasurement<Long> codec_init_latency =
419                 RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
420                         .setPredicate(RequirementConstants.LONG_LTE)
421                         .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40L)
422                         .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 40L)
423                         .build();
424 
425             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_12,
426                     codec_init_latency);
427         }
428 
429         /**
430          * [2.2.7.1/5.1/H-1-13] Codec initialization latency of 30ms or less for a 128kbps or
431          * lower bitrate audio decoding session for all audio encoders when under load. Load here
432          * is defined as a concurrent 1080p to 720p video-only transcoding session using hardware
433          * video codecs together with the 1080p audio-video recording initialization.
434          */
createR5_1__H_1_13()435         public static CodecInitLatencyRequirement createR5_1__H_1_13() {
436             RequiredMeasurement<Long> codec_init_latency =
437                 RequiredMeasurement.<Long>builder().setId(RequirementConstants.CODEC_INIT_LATENCY)
438                         .setPredicate(RequirementConstants.LONG_LTE)
439                         .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L)
440                         .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 30L)
441                         .build();
442 
443             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_13,
444                     codec_init_latency);
445         }
446     }
447 
448     // used for requirements [2.2.7.1/5.1/H-1-1], [2.2.7.1/5.1/H-1-2], [2.2.7.1/5.1/H-1-3],
449     // [2.2.7.1/5.1/H-1-4], [2.2.7.1/5.1/H-1-5], [2.2.7.1/5.1/H-1-6], [2.2.7.1/5.1/H-1-9],
450     // [2.2.7.1/5.1/H-1-10]
451     public static class ConcurrentCodecRequirement extends Requirement {
452         private static final String TAG = ConcurrentCodecRequirement.class.getSimpleName();
453         // allowed tolerance in measured fps vs expected fps in percentage, i.e. codecs achieving
454         // fps that is greater than (FPS_TOLERANCE_FACTOR * expectedFps) will be considered as
455         // passing the test
456         private static final double FPS_TOLERANCE_FACTOR = 0.95;
457         private static final double FPS_30_TOLERANCE = 30.0 * FPS_TOLERANCE_FACTOR;
458         static final int REQUIRED_MIN_CONCURRENT_INSTANCES = 6;
459         static final int REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9 = 2;
460 
ConcurrentCodecRequirement(String id, RequiredMeasurement<?> ... reqs)461         private ConcurrentCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
462             super(id, reqs);
463         }
464 
setConcurrentInstances(int concurrentInstances)465         public void setConcurrentInstances(int concurrentInstances) {
466             this.setMeasuredValue(RequirementConstants.CONCURRENT_SESSIONS,
467                     concurrentInstances);
468         }
469 
setConcurrentFps(double achievedFps)470         public void setConcurrentFps(double achievedFps) {
471             this.setMeasuredValue(RequirementConstants.CONCURRENT_FPS, achievedFps);
472         }
473 
474         // copied from android.mediapc.cts.getReqMinConcurrentInstances due to build issues on aosp
getReqMinConcurrentInstances(int performanceClass, String mimeType1, String mimeType2, int resolution)475         public static int getReqMinConcurrentInstances(int performanceClass, String mimeType1,
476             String mimeType2, int resolution) {
477             ArrayList<String> MEDIAPC_CONCURRENT_CODECS_R = new ArrayList<>(
478                 Arrays.asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC));
479             ArrayList<String> MEDIAPC_CONCURRENT_CODECS = new ArrayList<>(Arrays
480                 .asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
481                     MediaFormat.MIMETYPE_VIDEO_VP9, MediaFormat.MIMETYPE_VIDEO_AV1));
482 
483             if (performanceClass >= Build.VERSION_CODES.TIRAMISU) {
484                 return resolution >= 1080 ? REQUIRED_MIN_CONCURRENT_INSTANCES : 0;
485             } else if (performanceClass == Build.VERSION_CODES.S) {
486                 if (resolution >= 1080) {
487                     return 0;
488                 }
489                 if (MEDIAPC_CONCURRENT_CODECS.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS
490                     .contains(mimeType2)) {
491                     if (MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType1)
492                         || MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType2)) {
493                         return REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9;
494                     } else {
495                         return REQUIRED_MIN_CONCURRENT_INSTANCES;
496                     }
497                 } else {
498                     return 0;
499                 }
500             } else if (performanceClass == Build.VERSION_CODES.R) {
501                 if (resolution >= 1080) {
502                     return 0;
503                 }
504                 if (MEDIAPC_CONCURRENT_CODECS_R.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS_R
505                     .contains(mimeType2)) {
506                     return REQUIRED_MIN_CONCURRENT_INSTANCES;
507                 } else {
508                     return 0;
509                 }
510             } else {
511                 return 0;
512             }
513         }
514 
getReqMinConcurrentFps(int performanceClass, String mimeType1, String mimeType2, int resolution)515         private static double getReqMinConcurrentFps(int performanceClass, String mimeType1,
516             String mimeType2, int resolution) {
517             return FPS_30_TOLERANCE * getReqMinConcurrentInstances(performanceClass, mimeType1,
518                 mimeType2, resolution);
519         }
520 
521         /**
522          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
523          * a requirement for tests ran with a resolution of 720p
524          */
create720p(String requirementId, RequiredMeasurement<?> measure)525         private static ConcurrentCodecRequirement create720p(String requirementId,
526                 RequiredMeasurement<?> measure) {
527             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
528                     .setId(RequirementConstants.TEST_RESOLUTION)
529                     .setPredicate(RequirementConstants.INTEGER_EQ)
530                     .addRequiredValue(Build.VERSION_CODES.R, 720)
531                     .build();
532 
533             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
534                     testResolution);
535             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 720);
536             return req;
537         }
538 
539         /**
540          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
541          * a requirement for tests ran with a resolution of 1080p
542          */
create1080p(String requirementId, RequiredMeasurement<?> measure)543         private static ConcurrentCodecRequirement create1080p(String requirementId,
544                 RequiredMeasurement<?> measure) {
545             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
546                     .setId(RequirementConstants.TEST_RESOLUTION)
547                     .setPredicate(RequirementConstants.INTEGER_EQ)
548                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
549                     .build();
550 
551             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
552                     testResolution);
553             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 1080);
554             return req;
555         }
556 
557         /**
558          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
559          * a requirement for tests ran with a resolution of 4k
560          */
create4k(String requirementId, RequiredMeasurement<?> measure)561         private static ConcurrentCodecRequirement create4k(String requirementId,
562                 RequiredMeasurement<?> measure) {
563             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
564                     .setId(RequirementConstants.TEST_RESOLUTION)
565                     .setPredicate(RequirementConstants.INTEGER_EQ)
566                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
567                     .build();
568 
569             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
570                     testResolution);
571             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION,  2160);
572             return req;
573         }
574 
575         /**
576          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
577          * sessions that can be run concurrently in any codec combination via the
578          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
579          * .getSupportedPerformancePoints() methods.
580          */
createR5_1__H_1_1_720p(String mimeType1, String mimeType2, int resolution)581         public static ConcurrentCodecRequirement createR5_1__H_1_1_720p(String mimeType1,
582                 String mimeType2, int resolution) {
583             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
584                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
585                     .setPredicate(RequirementConstants.INTEGER_GTE)
586                     .addRequiredValue(Build.VERSION_CODES.R,
587                         getReqMinConcurrentInstances(
588                                 Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
589                     .addRequiredValue(Build.VERSION_CODES.S,
590                         getReqMinConcurrentInstances(
591                                 Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
592                     .build();
593 
594             return create720p(RequirementConstants.R5_1__H_1_1, maxInstances);
595         }
596 
597         /**
598          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
599          * sessions that can be run concurrently in any codec combination via the
600          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
601          * .getSupportedPerformancePoints() methods.
602          */
createR5_1__H_1_1_1080p()603         public static ConcurrentCodecRequirement createR5_1__H_1_1_1080p() {
604             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
605                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
606                     .setPredicate(RequirementConstants.INTEGER_GTE)
607                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
608                     .build();
609 
610             return create1080p(RequirementConstants.R5_1__H_1_1, maxInstances);
611         }
612 
613         /**
614          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
615          * sessions that can be run concurrently in any codec combination via the
616          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
617          * .getSupportedPerformancePoints() methods.
618          */
createR5_1__H_1_1_4k()619         public static ConcurrentCodecRequirement createR5_1__H_1_1_4k() {
620             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
621                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
622                     .setPredicate(RequirementConstants.INTEGER_GTE)
623                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
624                     .build();
625 
626             return create4k(RequirementConstants.R5_1__H_1_1, maxInstances);
627         }
628 
629         /**
630          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
631          * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
632          * resolution@30 fps.
633          */
createR5_1__H_1_2_720p(String mimeType1, String mimeType2, int resolution)634         public static ConcurrentCodecRequirement createR5_1__H_1_2_720p(String mimeType1,
635             String mimeType2, int resolution) {
636             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
637                     .setId(RequirementConstants.CONCURRENT_FPS)
638                     .setPredicate(RequirementConstants.DOUBLE_GTE)
639                     .addRequiredValue(Build.VERSION_CODES.R,
640                         getReqMinConcurrentFps(
641                                 Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
642                     .addRequiredValue(Build.VERSION_CODES.S,
643                         getReqMinConcurrentFps(
644                                 Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
645                     .build();
646 
647             return create720p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
648         }
649 
650         /**
651          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
652          * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
653          * resolution@30 fps.
654          */
createR5_1__H_1_2_1080p()655         public static ConcurrentCodecRequirement createR5_1__H_1_2_1080p() {
656             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
657                     .setId(RequirementConstants.CONCURRENT_FPS)
658                     .setPredicate(RequirementConstants.DOUBLE_GTE)
659                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE)
660                     .build();
661 
662             return create1080p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
663         }
664 
665         /**
666          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
667          * HEVC, VP9, AV1 or later) in any codec combination running concurrently with 3 sessions
668          * at 1080p resolution@30 fps and 3 sessions at 4k(U) resolution@30fps.
669          */
createR5_1__H_1_2_4k()670         public static ConcurrentCodecRequirement createR5_1__H_1_2_4k() {
671             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
672                     .setId(RequirementConstants.CONCURRENT_FPS)
673                     .setPredicate(RequirementConstants.DOUBLE_GTE)
674                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6 * FPS_30_TOLERANCE)
675                     .build();
676 
677             return create4k(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
678         }
679 
680         /**
681          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
682          * sessions that can be run concurrently in any codec combination via the
683          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
684          * .getSupportedPerformancePoints() methods.
685          */
createR5_1__H_1_3_720p(String mimeType1, String mimeType2, int resolution)686         public static ConcurrentCodecRequirement createR5_1__H_1_3_720p(String mimeType1,
687             String mimeType2, int resolution) {
688             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
689                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
690                     .setPredicate(RequirementConstants.INTEGER_GTE)
691                     .addRequiredValue(Build.VERSION_CODES.R,
692                         getReqMinConcurrentInstances(
693                                 Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
694                     .addRequiredValue(Build.VERSION_CODES.S,
695                         getReqMinConcurrentInstances(
696                                 Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
697                     .build();
698 
699             return create720p(RequirementConstants.R5_1__H_1_3, maxInstances);
700         }
701 
702         /**
703          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
704          * sessions that can be run concurrently in any codec combination via the
705          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
706          * .getSupportedPerformancePoints() methods.
707          */
createR5_1__H_1_3_1080p()708         public static ConcurrentCodecRequirement createR5_1__H_1_3_1080p() {
709             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
710                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
711                     .setPredicate(RequirementConstants.INTEGER_GTE)
712                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
713                     .build();
714 
715             return create1080p(RequirementConstants.R5_1__H_1_3, maxInstances);
716         }
717 
718         /**
719          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
720          * sessions that can be run concurrently in any codec combination via the
721          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
722          * .getSupportedPerformancePoints() methods.
723          */
createR5_1__H_1_3_4K()724         public static ConcurrentCodecRequirement createR5_1__H_1_3_4K() {
725             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
726                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
727                     .setPredicate(RequirementConstants.INTEGER_GTE)
728                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
729                     .build();
730 
731             return create4k(RequirementConstants.R5_1__H_1_3, maxInstances);
732         }
733 
734         /**
735          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
736          * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
737          * resolution@30 fps.
738          */
createR5_1__H_1_4_720p()739         public static ConcurrentCodecRequirement createR5_1__H_1_4_720p() {
740             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
741                     .setId(RequirementConstants.CONCURRENT_FPS)
742                     .setPredicate(RequirementConstants.DOUBLE_GTE)
743                     // Requirement not asserted since encoder test runs in byte buffer mode
744                     .addRequiredValue(Build.VERSION_CODES.R, 0.0)
745                     .addRequiredValue(Build.VERSION_CODES.S, 0.0)
746                     .build();
747 
748             return create720p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
749         }
750 
751         /**
752          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
753          * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
754          * resolution@30 fps.
755          */
createR5_1__H_1_4_1080p()756         public static ConcurrentCodecRequirement createR5_1__H_1_4_1080p() {
757             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
758                     .setId(RequirementConstants.CONCURRENT_FPS)
759                     .setPredicate(RequirementConstants.DOUBLE_GTE)
760                     // Requirement not asserted since encoder test runs in byte buffer mode
761                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 0.0)
762                     .build();
763 
764             return create1080p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
765         }
766 
767         /**
768          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
769          * HEVC, VP9* or later) in any codec combination running concurrently at 4k(U)
770          * resolution@30 fps.
771          */
createR5_1__H_1_4_4k()772         public static ConcurrentCodecRequirement createR5_1__H_1_4_4k() {
773             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
774                     .setId(RequirementConstants.CONCURRENT_FPS)
775                     .setPredicate(RequirementConstants.DOUBLE_GTE)
776                     // Requirement not asserted since encoder test runs in byte buffer mode
777                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 0.0)
778                     .build();
779 
780             return create4k(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
781         }
782 
783         /**
784          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
785          * decoder sessions that can be run concurrently in any codec combination via the
786          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
787          * .getSupportedPerformancePoints() methods.
788          */
createR5_1__H_1_5_720p(String mimeType1, String mimeType2, int resolution)789         public static ConcurrentCodecRequirement createR5_1__H_1_5_720p(String mimeType1,
790             String mimeType2, int resolution) {
791             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
792                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
793                     .setPredicate(RequirementConstants.INTEGER_GTE)
794                     .addRequiredValue(Build.VERSION_CODES.R,
795                         getReqMinConcurrentInstances(
796                                 Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
797                     .addRequiredValue(Build.VERSION_CODES.S,
798                         getReqMinConcurrentInstances(
799                                 Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
800                     .build();
801 
802             return create720p(RequirementConstants.R5_1__H_1_5, maxInstances);
803         }
804 
805         /**
806          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
807          * decoder sessions that can be run concurrently in any codec combination via the
808          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
809          * .getSupportedPerformancePoints() methods.
810          */
createR5_1__H_1_5_1080p()811         public static ConcurrentCodecRequirement createR5_1__H_1_5_1080p() {
812             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
813                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
814                     .setPredicate(RequirementConstants.INTEGER_GTE)
815                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
816                     .build();
817 
818             return create1080p(RequirementConstants.R5_1__H_1_5, maxInstances);
819         }
820 
821         /**
822          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
823          * decoder sessions that can be run concurrently in any codec combination via the
824          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
825          * .getSupportedPerformancePoints() methods.
826          */
createR5_1__H_1_5_4k()827         public static ConcurrentCodecRequirement createR5_1__H_1_5_4k() {
828             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
829                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
830                     .setPredicate(RequirementConstants.INTEGER_GTE)
831                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
832                     .build();
833 
834             return create4k(RequirementConstants.R5_1__H_1_5, maxInstances);
835         }
836 
837         /**
838          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
839          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
840          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
841          */
createR5_1__H_1_6_720p(String mimeType1, String mimeType2, int resolution)842         public static ConcurrentCodecRequirement createR5_1__H_1_6_720p(String mimeType1,
843             String mimeType2, int resolution) {
844             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
845                     .setId(RequirementConstants.CONCURRENT_FPS)
846                     .setPredicate(RequirementConstants.DOUBLE_GTE)
847                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
848                     .addRequiredValue(Build.VERSION_CODES.R,
849                         getReqMinConcurrentFps(
850                                 Build.VERSION_CODES.R, mimeType1, mimeType2, resolution)
851                             / 2)
852                     .addRequiredValue(Build.VERSION_CODES.S,
853                         getReqMinConcurrentFps(
854                                 Build.VERSION_CODES.S, mimeType1, mimeType2, resolution)
855                             / 2)
856                     .build();
857 
858             return create720p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
859         }
860 
861         /**
862          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
863          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
864          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
865          */
createR5_1__H_1_6_1080p()866         public static ConcurrentCodecRequirement createR5_1__H_1_6_1080p() {
867             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
868                     .setId(RequirementConstants.CONCURRENT_FPS)
869                     .setPredicate(RequirementConstants.DOUBLE_GTE)
870                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
871                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE / 2)
872                     .build();
873 
874             return create1080p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
875         }
876 
877         /**
878          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
879          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
880          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
881          */
createR5_1__H_1_6_4k()882         public static ConcurrentCodecRequirement createR5_1__H_1_6_4k() {
883             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
884                     .setId(RequirementConstants.CONCURRENT_FPS)
885                     .setPredicate(RequirementConstants.DOUBLE_GTE)
886                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
887                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
888                             6 * FPS_30_TOLERANCE / 2)
889                     .build();
890 
891             return create4k(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
892         }
893 
894         /**
895          * [2.2.7.1/5.1/H-1-9] Support 2 instances of secure hardware video decoder sessions
896          * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
897          * resolution@30fps.
898          */
createR5_1__H_1_9_1080p()899         public static ConcurrentCodecRequirement createR5_1__H_1_9_1080p() {
900             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
901                     .setId(RequirementConstants.CONCURRENT_FPS)
902                     .setPredicate(RequirementConstants.DOUBLE_GTE)
903                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 2 * FPS_30_TOLERANCE)
904                     .build();
905 
906             return create1080p(RequirementConstants.R5_1__H_1_9, reqConcurrentFps);
907         }
908 
909         /**
910          * [2.2.7.1/5.1/H-1-9] Support 2 instances of secure hardware video decoder sessions
911          * (AVC, HEVC, VP9, AV1 or later) in any codec combination running concurrently at 4k
912          * resolution@30 fps.
913          */
createR5_1__H_1_9_4k()914         public static ConcurrentCodecRequirement createR5_1__H_1_9_4k() {
915             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
916                     .setId(RequirementConstants.CONCURRENT_FPS)
917                     .setPredicate(RequirementConstants.DOUBLE_GTE)
918                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2 * FPS_30_TOLERANCE)
919                     .build();
920 
921             return create4k(RequirementConstants.R5_1__H_1_9, reqConcurrentFps);
922         }
923 
924         /**
925          * [2.2.7.1/5.1/H-1-10] Support 3 instances of non-secure hardware video decoder sessions
926          * together with 1 instance of secure hardware video decoder session (4 instances total)
927          * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
928          * resolution@30fps.
929          */
createR5_1__H_1_10_1080p()930         public static ConcurrentCodecRequirement createR5_1__H_1_10_1080p() {
931             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
932                     .setId(RequirementConstants.CONCURRENT_FPS)
933                     .setPredicate(RequirementConstants.DOUBLE_GTE)
934                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 4 * FPS_30_TOLERANCE)
935                     .build();
936 
937             return create1080p(RequirementConstants.R5_1__H_1_10, reqConcurrentFps);
938         }
939 
940         /**
941          * [2.2.7.1/5.1/H-1-10] Support 3 instances of non-secure hardware video decoder sessions
942          * together with 1 instance of secure hardware video decoder session (4 instances total)
943          * (AVC, HEVC, VP9, AV1 or later) in any codec combination running concurrently with 3
944          * sessions at 4K resolution@30 fps which includes one secure decoder session and 1
945          * session at 1080p resolution@30fps.
946          */
createR5_1__H_1_10_4k()947         public static ConcurrentCodecRequirement createR5_1__H_1_10_4k() {
948             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
949                     .setId(RequirementConstants.CONCURRENT_FPS)
950                     .setPredicate(RequirementConstants.DOUBLE_GTE)
951                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 4 * FPS_30_TOLERANCE)
952                     .build();
953 
954             return create4k(RequirementConstants.R5_1__H_1_10, reqConcurrentFps);
955         }
956 
957         /**
958          * [2.2.7.1/5.1/H-1-19] Support 3 instances of hardware video decoder and hardware video
959          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
960          * at 4k(U) @30fps resolution for 10-bit with at most one encoder session.
961          */
createR5_1__H_1_19()962         public static ConcurrentCodecRequirement createR5_1__H_1_19() {
963             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
964                     .setId(RequirementConstants.CONCURRENT_FPS)
965                     .setPredicate(RequirementConstants.DOUBLE_GTE)
966                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
967                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
968                             3 * FPS_30_TOLERANCE / 2)
969                     .build();
970 
971             return create4k(RequirementConstants.R5_1__H_1_19, reqConcurrentFps);
972         }
973     }
974 
975     public static class ConcurrentRearFrontRequirement extends Requirement {
976         private static final String TAG = ConcurrentRearFrontRequirement.class.getSimpleName();
977 
ConcurrentRearFrontRequirement(String id, RequiredMeasurement<?> ... reqs)978         private ConcurrentRearFrontRequirement(String id, RequiredMeasurement<?> ... reqs) {
979             super(id, reqs);
980         }
981 
setConcurrentRearFrontSupported(boolean concurrentRearFrontSupported)982         public void setConcurrentRearFrontSupported(boolean concurrentRearFrontSupported) {
983             this.setMeasuredValue(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED,
984                     concurrentRearFrontSupported);
985         }
986 
987         /**
988          * [2.2.7.2/7.5/H-1-11] MUST implement concurrent front-back streaming on primary cameras.
989          */
createConcurrentRearFrontReq()990         public static ConcurrentRearFrontRequirement createConcurrentRearFrontReq() {
991             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
992                     .<Boolean>builder()
993                     .setId(RequirementConstants.CONCURRENT_REAR_FRONT_SUPPORTED)
994                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
995                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
996                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
997                     .build();
998 
999             return new ConcurrentRearFrontRequirement(RequirementConstants.R7_5__H_1_11,
1000                     requirement);
1001         }
1002     }
1003 
1004     // used for requirements [7.1.1.3/H-1-1], [7.1.1.3/H-2-1]
1005     public static class DensityRequirement extends Requirement {
1006         private static final String TAG = DensityRequirement.class.getSimpleName();
1007 
DensityRequirement(String id, RequiredMeasurement<?> ... reqs)1008         private DensityRequirement(String id, RequiredMeasurement<?> ... reqs) {
1009             super(id, reqs);
1010         }
1011 
setDisplayDensity(int displayDensity)1012         public void setDisplayDensity(int displayDensity) {
1013             this.<Integer>setMeasuredValue(RequirementConstants.DISPLAY_DENSITY, displayDensity);
1014         }
1015 
1016         /**
1017          * [7.1.1.3/H-1-1] MUST have screen density of at least 400 dpi.
1018          */
createR7_1_1_3__H_1_1()1019         public static DensityRequirement createR7_1_1_3__H_1_1() {
1020             RequiredMeasurement<Integer> display_density = RequiredMeasurement
1021                     .<Integer>builder()
1022                     .setId(RequirementConstants.DISPLAY_DENSITY)
1023                     .setPredicate(RequirementConstants.INTEGER_GTE)
1024                     .addRequiredValue(Build.VERSION_CODES.R, 400)
1025                     .build();
1026 
1027             return new DensityRequirement(RequirementConstants.R7_1_1_3__H_1_1, display_density);
1028         }
1029 
1030         /**
1031          * [7.1.1.3/H-2-1] MUST have screen density of at least 400 dpi.
1032          */
createR7_1_1_3__H_2_1()1033         public static DensityRequirement createR7_1_1_3__H_2_1() {
1034             RequiredMeasurement<Integer> display_density = RequiredMeasurement
1035                     .<Integer>builder()
1036                     .setId(RequirementConstants.DISPLAY_DENSITY)
1037                     .setPredicate(RequirementConstants.INTEGER_GTE)
1038                     .addRequiredValue(Build.VERSION_CODES.S, 400)
1039                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 400)
1040                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 400)
1041                     .build();
1042 
1043             return new DensityRequirement(RequirementConstants.R7_1_1_3__H_2_1, display_density);
1044         }
1045     }
1046 
1047     public static class DynamicRangeTenBitsRequirement extends Requirement {
1048         private static final String TAG =
1049                 DynamicRangeTenBitsRequirement.class.getSimpleName();
1050 
1051         public static int PRIMARY_REAR_CAMERA = 0;
1052         public static int PRIMARY_FRONT_CAMERA = 1;
1053 
DynamicRangeTenBitsRequirement(String id, RequiredMeasurement<?> ... reqs)1054         private DynamicRangeTenBitsRequirement(String id, RequiredMeasurement<?> ... reqs) {
1055             super(id, reqs);
1056         }
1057 
setDynamicRangeTenBitsSupported(int camera, boolean supported)1058         public void setDynamicRangeTenBitsSupported(int camera, boolean supported) {
1059             if (camera == PRIMARY_REAR_CAMERA) {
1060                 this.setMeasuredValue(RequirementConstants.REAR_CAMERA_DYNAMIC_TENBITS_SUPPORTED,
1061                         supported);
1062             } else if (camera == PRIMARY_FRONT_CAMERA) {
1063                 this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_DYNAMIC_TENBITS_SUPPORTED,
1064                         supported);
1065             }
1066         }
1067 
1068         /**
1069          * [2.2.7.2/7.5/H-1-16] MUST support DYNAMIC_RANGE_TEN_BIT capability for
1070          * the primary cameras.
1071          */
createDynamicRangeTenBitsReq()1072         public static DynamicRangeTenBitsRequirement createDynamicRangeTenBitsReq() {
1073             RequiredMeasurement<Boolean> rearDynamicRangeTenBitsRequirement = RequiredMeasurement
1074                     .<Boolean>builder()
1075                     .setId(RequirementConstants.REAR_CAMERA_DYNAMIC_TENBITS_SUPPORTED)
1076                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1077                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1078                     .build();
1079             RequiredMeasurement<Boolean> frontDynamicRangeTenBitsRequirement = RequiredMeasurement
1080                     .<Boolean>builder()
1081                     .setId(RequirementConstants.FRONT_CAMERA_DYNAMIC_TENBITS_SUPPORTED)
1082                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1083                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1084                     .build();
1085             return new DynamicRangeTenBitsRequirement(RequirementConstants.R7_5__H_1_16,
1086                     rearDynamicRangeTenBitsRequirement, frontDynamicRangeTenBitsRequirement);
1087         }
1088     }
1089 
1090     public static class ExtYuvTargetRequirement extends Requirement {
1091         private static final String TAG = ExtYuvTargetRequirement.class.getSimpleName();
1092 
ExtYuvTargetRequirement(String id, RequiredMeasurement<?> ... reqs)1093         private ExtYuvTargetRequirement(String id, RequiredMeasurement<?> ... reqs) {
1094             super(id, reqs);
1095         }
1096 
setExtYuvTargetSupport(boolean extensionSupported)1097         public void setExtYuvTargetSupport(boolean extensionSupported) {
1098             this.setMeasuredValue(RequirementConstants.EXT_YUV_EXTENSION, extensionSupported);
1099         }
1100 
1101         /**
1102          * [5.12/H-1-3] MUST checks for EXT_YUV_target extension support.
1103          */
createExtensionReq()1104         public static ExtYuvTargetRequirement createExtensionReq() {
1105             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1106                     .<Boolean>builder()
1107                     .setId(RequirementConstants.EXT_YUV_EXTENSION)
1108                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1109                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1110                     .build();
1111 
1112             return new ExtYuvTargetRequirement(RequirementConstants.R5_12__H_1_3, requirement);
1113         }
1114     }
1115 
1116     public static class FaceDetectionRequirement extends Requirement {
1117         private static final String TAG =
1118                 FaceDetectionRequirement.class.getSimpleName();
1119 
1120         public static int PRIMARY_REAR_CAMERA = 0;
1121         public static int PRIMARY_FRONT_CAMERA = 1;
1122 
FaceDetectionRequirement(String id, RequiredMeasurement<?> ... reqs)1123         private FaceDetectionRequirement(String id, RequiredMeasurement<?> ... reqs) {
1124             super(id, reqs);
1125         }
1126 
setFaceDetectionSupported(int camera, boolean supported)1127         public void setFaceDetectionSupported(int camera, boolean supported) {
1128             if (camera == PRIMARY_REAR_CAMERA) {
1129                 this.setMeasuredValue(RequirementConstants.REAR_CAMERA_FACE_DETECTION_SUPPORTED,
1130                         supported);
1131             } else if (camera == PRIMARY_FRONT_CAMERA) {
1132                 this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_FACE_DETECTION_SUPPORTED,
1133                         supported);
1134             }
1135         }
1136 
1137         /**
1138          * [2.2.7.2/7.5/H-1-17] MUST support face detection capability
1139          * (STATISTICS_FACE_DETECT_MODE_SIMPLE or STATISTICS_FACE_DETECT_MODE_FULL) for the primary
1140          * cameras.
1141          */
createFaceDetectionReq()1142         public static FaceDetectionRequirement createFaceDetectionReq() {
1143             RequiredMeasurement<Boolean> rearFaceDetectionRequirement = RequiredMeasurement
1144                     .<Boolean>builder()
1145                     .setId(RequirementConstants.REAR_CAMERA_FACE_DETECTION_SUPPORTED)
1146                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1147                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1148                     .build();
1149             RequiredMeasurement<Boolean> frontFaceDetectionRequirement = RequiredMeasurement
1150                     .<Boolean>builder()
1151                     .setId(RequirementConstants.FRONT_CAMERA_FACE_DETECTION_SUPPORTED)
1152                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1153                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1154                     .build();
1155             return new FaceDetectionRequirement(RequirementConstants.R7_5__H_1_17,
1156                     rearFaceDetectionRequirement, frontFaceDetectionRequirement);
1157         }
1158     }
1159 
1160     // used for requirements [8.2/H-1-1], [8.2/H-1-2], [8.2/H-1-3], [8.2/H-1-4]
1161     public static class FileSystemRequirement extends Requirement {
1162 
1163         private static final String TAG = FileSystemRequirement.class.getSimpleName();
1164 
FileSystemRequirement(String id, RequiredMeasurement<?>... reqs)1165         private FileSystemRequirement(String id, RequiredMeasurement<?>... reqs) {
1166             super(id, reqs);
1167         }
1168         /**
1169          * Set the Filesystem I/O Rate in MB/s.
1170          */
setFilesystemIoRate(double filesystemIoRate)1171         public void setFilesystemIoRate(double filesystemIoRate) {
1172             this.setMeasuredValue(RequirementConstants.FILESYSTEM_IO_RATE, filesystemIoRate);
1173         }
1174 
1175         /**
1176          * [8.2/H-1-1] MUST ensure a sequential write performance of at least 100(R) / 125(S &
1177          * above) MB/s.
1178          */
createR8_2__H_1_1()1179         public static FileSystemRequirement createR8_2__H_1_1() {
1180             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1181                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1182                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1183                     .addRequiredValue(Build.VERSION_CODES.R, 100.0)
1184                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 125.0)
1185                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 150.0)
1186                     .build();
1187 
1188             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_1, filesystem_io_rate);
1189         }
1190 
1191         /**
1192          * [8.2/H-2-1] MUST ensure a sequential write performance of at least 125 MB/s.
1193          */
createR8_2__H_2_1()1194         public static FileSystemRequirement createR8_2__H_2_1() {
1195             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1196                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1197                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1198                     .addRequiredValue(Build.VERSION_CODES.S, 125.0)
1199                     .build();
1200 
1201             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_1, filesystem_io_rate);
1202         }
1203 
1204         /**
1205          * [8.2/H-1-2] MUST ensure a random write performance of at least 10 MB/s
1206          */
createR8_2__H_1_2()1207         public static FileSystemRequirement createR8_2__H_1_2() {
1208             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1209                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1210                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1211                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 10.0)
1212                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 10.0)
1213                     .build();
1214 
1215             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_2, filesystem_io_rate);
1216         }
1217 
1218         /**
1219          * [8.2/H-2-2] MUST ensure a random write performance of at least 10 MB/s.
1220          */
createR8_2__H_2_2()1221         public static FileSystemRequirement createR8_2__H_2_2() {
1222             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1223                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1224                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1225                     .addRequiredValue(Build.VERSION_CODES.S, 10.0)
1226                     .build();
1227 
1228             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_2, filesystem_io_rate);
1229         }
1230 
1231         /**
1232          * [8.2/H-1-3] MUST ensure a sequential read performance of at least 200(R) / 250(S &
1233          * above) MB/s.
1234          */
createR8_2__H_1_3()1235         public static FileSystemRequirement createR8_2__H_1_3() {
1236             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1237                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1238                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1239                     .addRequiredValue(Build.VERSION_CODES.R, 200.0)
1240                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 250.0)
1241                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 250.0)
1242                     .build();
1243 
1244             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_3, filesystem_io_rate);
1245         }
1246 
1247         /**
1248          * [8.2/H-2-3] MUST ensure a sequential read performance of at least 250 MB/s.
1249          */
createR8_2__H_2_3()1250         public static FileSystemRequirement createR8_2__H_2_3() {
1251             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1252                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1253                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1254                     .addRequiredValue(Build.VERSION_CODES.S, 250.0)
1255                     .build();
1256 
1257             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_3, filesystem_io_rate);
1258         }
1259 
1260         /**
1261          * [8.2/H-1-4] MUST ensure a random read performance of at least 25(R) / 40(S & above) MB/s.
1262          */
createR8_2__H_1_4()1263         public static FileSystemRequirement createR8_2__H_1_4() {
1264             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1265                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1266                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1267                     .addRequiredValue(Build.VERSION_CODES.R, 25.0)
1268                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40.0)
1269                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 100.0)
1270                     .build();
1271 
1272             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_4, filesystem_io_rate);
1273         }
1274 
1275         /**
1276          * [8.2/H-2-4] MUST ensure a random read performance of at least 40 MB/s.
1277          */
createR8_2__H_2_4()1278         public static FileSystemRequirement createR8_2__H_2_4() {
1279             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
1280                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
1281                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1282                     .addRequiredValue(Build.VERSION_CODES.S, 40.0)
1283                     .build();
1284 
1285             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_4, filesystem_io_rate);
1286         }
1287     }
1288 
1289     // used for requirements [2.2.7.1/5.3/H-1-1], [2.2.7.1/5.3/H-1-2]
1290     public static class FrameDropRequirement extends Requirement {
1291         private static final String TAG = FrameDropRequirement.class.getSimpleName();
1292 
FrameDropRequirement(String id, RequiredMeasurement<?>... reqs)1293         private FrameDropRequirement(String id, RequiredMeasurement<?>... reqs) {
1294             super(id, reqs);
1295         }
1296 
setFramesDropped(int framesDropped)1297         public void setFramesDropped(int framesDropped) {
1298             this.setMeasuredValue(RequirementConstants.FRAMES_DROPPED, framesDropped);
1299         }
1300 
setFrameRate(double frameRate)1301         public void setFrameRate(double frameRate) {
1302             this.setMeasuredValue(RequirementConstants.FRAME_RATE, frameRate);
1303         }
1304 
setTestResolution(int res)1305         public void setTestResolution(int res) {
1306             this.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, res);
1307         }
1308 
1309         /**
1310          * [2.2.7.1/5.3/H-1-1] MUST NOT drop more than 1 frames in 10 seconds (i.e less than 0.333
1311          * percent frame drop) for a 1080p 30 fps video session under load. Load is defined as a
1312          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1313          * as well as a 128 kbps AAC audio playback.
1314          */
createR5_3__H_1_1_R()1315         public static FrameDropRequirement createR5_3__H_1_1_R() {
1316             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1317                     .<Integer>builder()
1318                     .setId(RequirementConstants.FRAMES_DROPPED)
1319                     .setPredicate(RequirementConstants.INTEGER_LTE)
1320                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1321                     .addRequiredValue(Build.VERSION_CODES.R, 3)
1322                     .build();
1323 
1324             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1325                     .<Double>builder()
1326                     .setId(RequirementConstants.FRAME_RATE)
1327                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1328                     .addRequiredValue(Build.VERSION_CODES.R, 30.0)
1329                     .build();
1330 
1331             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1332                     .setId(RequirementConstants.TEST_RESOLUTION)
1333                     .setPredicate(RequirementConstants.INTEGER_EQ)
1334                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1335                     .build();
1336 
1337             return new FrameDropRequirement(
1338                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1339         }
1340 
1341         /**
1342          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 1 frame in 10 seconds during a video
1343          * resolution change in a 30 fps video session under load. Load is defined as a
1344          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1345          * as well as a 128Kbps AAC audio playback.
1346          */
createR5_3__H_1_2_R()1347         public static FrameDropRequirement createR5_3__H_1_2_R() {
1348             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1349                     .<Integer>builder()
1350                     .setId(RequirementConstants.FRAMES_DROPPED)
1351                     .setPredicate(RequirementConstants.INTEGER_LTE)
1352                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1353                     .addRequiredValue(Build.VERSION_CODES.R, 3)
1354                     .build();
1355 
1356             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1357                     .<Double>builder()
1358                     .setId(RequirementConstants.FRAME_RATE)
1359                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1360                     .addRequiredValue(Build.VERSION_CODES.R, 30.0)
1361                     .build();
1362 
1363             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1364                     .setId(RequirementConstants.TEST_RESOLUTION)
1365                     .setPredicate(RequirementConstants.INTEGER_EQ)
1366                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1367                     .build();
1368 
1369             return new FrameDropRequirement(
1370                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1371         }
1372 
1373         /**
1374          * [2.2.7.1/5.3/H-1-1] MUST NOT drop more than 2(S) / 1(T) frames in 10 seconds for a
1375          * 1080p 60 fps video session under load. Load is defined as a concurrent 1080p to 720p
1376          * video-only transcoding session using hardware video codecs, as well as a 128 kbps AAC
1377          * audio playback.
1378          */
createR5_3__H_1_1_ST()1379         public static FrameDropRequirement createR5_3__H_1_1_ST() {
1380             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1381                     .<Integer>builder()
1382                     .setId(RequirementConstants.FRAMES_DROPPED)
1383                     .setPredicate(RequirementConstants.INTEGER_LTE)
1384                     // MUST NOT drop more than 2 frame in 10 seconds so 6 frames for 30 seconds
1385                     .addRequiredValue(Build.VERSION_CODES.S, 6)
1386                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1387                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 3)
1388                     .build();
1389 
1390             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1391                     .<Double>builder()
1392                     .setId(RequirementConstants.FRAME_RATE)
1393                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1394                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 60.0)
1395                     .build();
1396 
1397             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1398                     .setId(RequirementConstants.TEST_RESOLUTION)
1399                     .setPredicate(RequirementConstants.INTEGER_EQ)
1400                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1401                     .build();
1402 
1403             return new FrameDropRequirement(
1404                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1405         }
1406 
1407         /**
1408          * [2.2.7.1/5.3/H-1-1] MUST NOT drop more than 1 frame in 10 seconds for a
1409          * 4k 60 fps video session under load. Load is defined as a concurrent 1080p to 720p
1410          * video-only transcoding session using hardware video codecs, as well as a 128 kbps AAC
1411          * audio playback.
1412          */
createR5_3__H_1_1_U()1413         public static FrameDropRequirement createR5_3__H_1_1_U() {
1414             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1415                     .<Integer>builder()
1416                     .setId(RequirementConstants.FRAMES_DROPPED)
1417                     .setPredicate(RequirementConstants.INTEGER_LTE)
1418                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1419                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 3)
1420                     .build();
1421 
1422             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1423                     .<Double>builder()
1424                     .setId(RequirementConstants.FRAME_RATE)
1425                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1426                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 60.0)
1427                     .build();
1428 
1429             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1430                     .setId(RequirementConstants.TEST_RESOLUTION)
1431                     .setPredicate(RequirementConstants.INTEGER_EQ)
1432                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
1433                     .build();
1434 
1435             return new FrameDropRequirement(
1436                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1437         }
1438 
1439         /**
1440          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 2(S) / 1(T) frames in 10 seconds during a
1441          * video resolution change in a 60 fps video session under load. Load is defined as a
1442          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1443          * as well as a 128Kbps AAC audio playback.
1444          */
createR5_3__H_1_2_ST()1445         public static FrameDropRequirement createR5_3__H_1_2_ST() {
1446             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1447                     .<Integer>builder()
1448                     .setId(RequirementConstants.FRAMES_DROPPED)
1449                     .setPredicate(RequirementConstants.INTEGER_LTE)
1450                     // MUST NOT drop more than 2 frame in 10 seconds so 6 frames for 30 seconds
1451                     .addRequiredValue(Build.VERSION_CODES.S, 6)
1452                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1453                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 3)
1454                     .build();
1455 
1456             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1457                     .<Double>builder()
1458                     .setId(RequirementConstants.FRAME_RATE)
1459                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1460                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 60.0)
1461                     .build();
1462 
1463             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1464                     .setId(RequirementConstants.TEST_RESOLUTION)
1465                     .setPredicate(RequirementConstants.INTEGER_EQ)
1466                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1467                     .build();
1468 
1469             return new FrameDropRequirement(
1470                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1471         }
1472 
1473         /**
1474          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 1 frames in 10 seconds during a
1475          * video resolution change in a 4k 60 fps video session under load. Load is defined as a
1476          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1477          * as well as a 128Kbps AAC audio playback.
1478          */
createR5_3__H_1_2_U()1479         public static FrameDropRequirement createR5_3__H_1_2_U() {
1480             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1481                     .<Integer>builder()
1482                     .setId(RequirementConstants.FRAMES_DROPPED)
1483                     .setPredicate(RequirementConstants.INTEGER_LTE)
1484                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1485                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 3)
1486                     .build();
1487 
1488             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1489                     .<Double>builder()
1490                     .setId(RequirementConstants.FRAME_RATE)
1491                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1492                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 60.0)
1493                     .build();
1494 
1495             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1496                     .setId(RequirementConstants.TEST_RESOLUTION)
1497                     .setPredicate(RequirementConstants.INTEGER_EQ)
1498                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
1499                     .build();
1500 
1501             return new FrameDropRequirement(
1502                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1503         }
1504     }
1505 
1506     public static class LogicalMultiCameraRequirement extends Requirement {
1507         private static final String TAG =
1508                 LogicalMultiCameraRequirement.class.getSimpleName();
1509 
LogicalMultiCameraRequirement(String id, RequiredMeasurement<?> ... reqs)1510         private LogicalMultiCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
1511             super(id, reqs);
1512         }
1513 
setRearLogicalMultiCameraReqMet(boolean reqMet)1514         public void setRearLogicalMultiCameraReqMet(boolean reqMet) {
1515             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
1516                     reqMet);
1517         }
1518 
setFrontLogicalMultiCameraReqMet(boolean reqMet)1519         public void setFrontLogicalMultiCameraReqMet(boolean reqMet) {
1520             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET,
1521                     reqMet);
1522         }
1523 
1524         /**
1525          * [2.2.7.2/7.5/H-1-13] MUST support LOGICAL_MULTI_CAMERA capability for the primary
1526          * cameras if there are greater than 1 RGB cameras facing the same direction.
1527          */
createLogicalMultiCameraReq()1528         public static LogicalMultiCameraRequirement createLogicalMultiCameraReq() {
1529             RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
1530                     .<Boolean>builder()
1531                     .setId(RequirementConstants.REAR_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
1532                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1533                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1534                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1535                     .build();
1536             RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
1537                     .<Boolean>builder()
1538                     .setId(RequirementConstants.FRONT_CAMERA_LOGICAL_MULTI_CAMERA_REQ_MET)
1539                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1540                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1541                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1542                     .build();
1543 
1544             return new LogicalMultiCameraRequirement(RequirementConstants.R7_5__H_1_13,
1545                     rearRequirement, frontRequirement);
1546         }
1547     }
1548 
1549     // used for requirements [7.6.1/H-1-1], [7.6.1/H-2-1]
1550     public static class MemoryRequirement extends Requirement {
1551         private static final String TAG = MemoryRequirement.class.getSimpleName();
1552 
MemoryRequirement(String id, RequiredMeasurement<?> ... reqs)1553         private MemoryRequirement(String id, RequiredMeasurement<?> ... reqs) {
1554             super(id, reqs);
1555         }
1556 
setPhysicalMemory(long physicalMemory)1557         public void setPhysicalMemory(long physicalMemory) {
1558             this.<Long>setMeasuredValue(RequirementConstants.PHYSICAL_MEMORY, physicalMemory);
1559         }
1560 
1561         /**
1562          * [7.6.1/H-1-1] MUST have at least 6 GB of physical memory.
1563          */
createR7_6_1__H_1_1()1564         public static MemoryRequirement createR7_6_1__H_1_1() {
1565             RequiredMeasurement<Long> physical_memory = RequiredMeasurement
1566                     .<Long>builder()
1567                     .setId(RequirementConstants.PHYSICAL_MEMORY)
1568                     .setPredicate(RequirementConstants.LONG_GTE)
1569                     // Media performance requires 6 GB minimum RAM, but keeping the following to
1570                     // 5 GB as activityManager.getMemoryInfo() returns around 5.4 GB on a 6 GB
1571                     // device.
1572                     .addRequiredValue(Build.VERSION_CODES.R, 5L * 1024L)
1573                     .build();
1574 
1575             return new MemoryRequirement(RequirementConstants.R7_6_1__H_1_1, physical_memory);
1576         }
1577 
1578         /**
1579          * [7.6.1/H-2-1] MUST have at least 6/8 GB of physical memory.
1580          */
createR7_6_1__H_2_1()1581         public static MemoryRequirement createR7_6_1__H_2_1() {
1582             RequiredMeasurement<Long> physical_memory = RequiredMeasurement
1583                     .<Long>builder()
1584                     .setId(RequirementConstants.PHYSICAL_MEMORY)
1585                     .setPredicate(RequirementConstants.LONG_GTE)
1586                     // Media performance requires 6/8 GB minimum RAM, but keeping the following to
1587                     // 5/7 GB as activityManager.getMemoryInfo() returns around 5.4 GB on a 6 GB
1588                     // device.
1589                     .addRequiredValue(Build.VERSION_CODES.S, 5L * 1024L)
1590                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 7L * 1024L)
1591                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 7L * 1024L)
1592                     .build();
1593 
1594             return new MemoryRequirement(RequirementConstants.R7_6_1__H_2_1, physical_memory);
1595         }
1596     }
1597 
1598     public static class PreviewStabilizationRequirement extends Requirement {
1599         private static final String TAG =
1600                 PreviewStabilizationRequirement.class.getSimpleName();
1601 
PreviewStabilizationRequirement(String id, RequiredMeasurement<?> ... reqs)1602         private PreviewStabilizationRequirement(String id, RequiredMeasurement<?> ... reqs) {
1603             super(id, reqs);
1604         }
1605 
setRearPreviewStabilizationSupported(boolean supported)1606         public void setRearPreviewStabilizationSupported(boolean supported) {
1607             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
1608                     supported);
1609         }
1610 
setFrontPreviewStabilizationSupported(boolean supported)1611         public void setFrontPreviewStabilizationSupported(boolean supported) {
1612             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED,
1613                     supported);
1614         }
1615 
1616         /**
1617          * [2.2.7.2/7.5/H-1-12] MUST support CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION
1618          * for both primary front and primary back camera.
1619          */
createPreviewStabilizationReq()1620         public static PreviewStabilizationRequirement createPreviewStabilizationReq() {
1621             RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
1622                     .<Boolean>builder()
1623                     .setId(RequirementConstants.REAR_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
1624                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1625                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1626                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1627                     .build();
1628             RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
1629                     .<Boolean>builder()
1630                     .setId(RequirementConstants.FRONT_CAMERA_PREVIEW_STABILIZATION_SUPPORTED)
1631                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1632                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1633                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1634                     .build();
1635 
1636             return new PreviewStabilizationRequirement(RequirementConstants.R7_5__H_1_12,
1637                     rearRequirement, frontRequirement);
1638         }
1639     }
1640 
1641     public static class PrimaryCameraRequirement extends Requirement {
1642         private static final long MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION = 12000000;
1643         private static final long MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION = 5000000;
1644         private static final long MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION = 4000000;
1645         private static final String TAG = PrimaryCameraRequirement.class.getSimpleName();
1646 
PrimaryCameraRequirement(String id, RequiredMeasurement<?> ... reqs)1647         private PrimaryCameraRequirement(String id, RequiredMeasurement<?> ... reqs) {
1648             super(id, reqs);
1649         }
1650 
setPrimaryCameraSupported(boolean hasPrimaryCamera)1651         public void setPrimaryCameraSupported(boolean hasPrimaryCamera) {
1652             this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_AVAILABLE,
1653                     hasPrimaryCamera);
1654         }
1655 
setResolution(long resolution)1656         public void setResolution(long resolution) {
1657             this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_RESOLUTION,
1658                     resolution);
1659         }
1660 
setVideoSizeReqSatisfied(boolean videoSizeReqSatisfied)1661         public void setVideoSizeReqSatisfied(boolean videoSizeReqSatisfied) {
1662             this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED,
1663                     videoSizeReqSatisfied);
1664         }
1665 
setVideoFps(double videoFps)1666         public void setVideoFps(double videoFps) {
1667             this.setMeasuredValue(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS, videoFps);
1668         }
1669 
1670         /**
1671          * [2.2.7.2/7.5/H-1-1] MUST have a primary rear facing camera with a resolution of at
1672          * least 12 megapixels supporting video capture at 4k@30fps
1673          */
createRearPrimaryCamera()1674         public static PrimaryCameraRequirement createRearPrimaryCamera() {
1675             RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
1676                     .<Boolean>builder()
1677                     .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
1678                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1679                     .addRequiredValue(Build.VERSION_CODES.R, true)
1680                     .addRequiredValue(Build.VERSION_CODES.S, true)
1681                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1682                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1683                     .build();
1684 
1685             RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
1686                     .<Long>builder()
1687                     .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
1688                     .setPredicate(RequirementConstants.LONG_GTE)
1689                     .addRequiredValue(Build.VERSION_CODES.R, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
1690                     .addRequiredValue(Build.VERSION_CODES.S, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
1691                     .addRequiredValue(
1692                             Build.VERSION_CODES.TIRAMISU, MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
1693                     .addRequiredValue(
1694                             Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
1695                             MIN_BACK_SENSOR_PERF_CLASS_RESOLUTION)
1696                     .build();
1697 
1698             RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
1699                     .<Boolean>builder()
1700                     .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
1701                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1702                     .addRequiredValue(Build.VERSION_CODES.R, true)
1703                     .addRequiredValue(Build.VERSION_CODES.S, true)
1704                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1705                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1706                     .build();
1707 
1708             RequiredMeasurement<Double> videoFps = RequiredMeasurement
1709                     .<Double>builder()
1710                     .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
1711                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1712                     .addRequiredValue(Build.VERSION_CODES.R, 29.9)
1713                     .addRequiredValue(Build.VERSION_CODES.S, 29.9)
1714                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
1715                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 29.9)
1716                     .build();
1717 
1718             return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_1,
1719                     hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
1720                     videoFps);
1721         }
1722 
1723         /**
1724          * [2.2.7.2/7.5/H-1-2] MUST have a primary front facing camera with a resolution of
1725          * at least 4 megapixels supporting video capture at 1080p@30fps.
1726          */
createFrontPrimaryCamera()1727         public static PrimaryCameraRequirement createFrontPrimaryCamera() {
1728             RequiredMeasurement<Boolean> hasPrimaryCamera = RequiredMeasurement
1729                     .<Boolean>builder()
1730                     .setId(RequirementConstants.PRIMARY_CAMERA_AVAILABLE)
1731                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1732                     .addRequiredValue(Build.VERSION_CODES.R, true)
1733                     .addRequiredValue(Build.VERSION_CODES.S, true)
1734                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1735                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1736                     .build();
1737 
1738             RequiredMeasurement<Long> cameraResolution = RequiredMeasurement
1739                     .<Long>builder()
1740                     .setId(RequirementConstants.PRIMARY_CAMERA_RESOLUTION)
1741                     .setPredicate(RequirementConstants.LONG_GTE)
1742                     .addRequiredValue(
1743                             Build.VERSION_CODES.R, MIN_FRONT_SENSOR_R_PERF_CLASS_RESOLUTION)
1744                     .addRequiredValue(
1745                             Build.VERSION_CODES.S, MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
1746                     .addRequiredValue(
1747                             Build.VERSION_CODES.TIRAMISU, MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
1748                     .addRequiredValue(
1749                             Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
1750                             MIN_FRONT_SENSOR_S_PERF_CLASS_RESOLUTION)
1751                     .build();
1752 
1753             RequiredMeasurement<Boolean> videoSizeReqSatisfied = RequiredMeasurement
1754                     .<Boolean>builder()
1755                     .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_SIZE_REQ_SATISFIED)
1756                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1757                     .addRequiredValue(Build.VERSION_CODES.R, true)
1758                     .addRequiredValue(Build.VERSION_CODES.S, true)
1759                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1760                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1761                     .build();
1762 
1763             RequiredMeasurement<Double> videoFps = RequiredMeasurement
1764                     .<Double>builder()
1765                     .setId(RequirementConstants.PRIMARY_CAMERA_VIDEO_FPS)
1766                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1767                     .addRequiredValue(Build.VERSION_CODES.R, 29.9)
1768                     .addRequiredValue(Build.VERSION_CODES.S, 29.9)
1769                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 29.9)
1770                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 29.9)
1771                     .build();
1772 
1773             return new PrimaryCameraRequirement(RequirementConstants.R7_5__H_1_2,
1774                     hasPrimaryCamera, cameraResolution, videoSizeReqSatisfied,
1775                     videoFps);
1776         }
1777     }
1778 
1779     // used for requirements [7.1.1.1/H-1-1], [7.1.1.1/H-2-1]
1780     public static class ResolutionRequirement extends Requirement {
1781         private static final String TAG = ResolutionRequirement.class.getSimpleName();
1782 
ResolutionRequirement(String id, RequiredMeasurement<?> ... reqs)1783         private ResolutionRequirement(String id, RequiredMeasurement<?> ... reqs) {
1784             super(id, reqs);
1785         }
1786 
setLongResolution(int longResolution)1787         public void setLongResolution(int longResolution) {
1788             this.<Integer>setMeasuredValue(RequirementConstants.LONG_RESOLUTION, longResolution);
1789         }
1790 
setShortResolution(int shortResolution)1791         public void setShortResolution(int shortResolution) {
1792             this.<Integer>setMeasuredValue(RequirementConstants.SHORT_RESOLUTION, shortResolution);
1793         }
1794 
1795         /**
1796          * [7.1.1.1/H-1-1] MUST have screen resolution of at least 1080p.
1797          */
createR7_1_1_1__H_1_1()1798         public static ResolutionRequirement createR7_1_1_1__H_1_1() {
1799             RequiredMeasurement<Integer> long_resolution = RequiredMeasurement
1800                     .<Integer>builder()
1801                     .setId(RequirementConstants.LONG_RESOLUTION)
1802                     .setPredicate(RequirementConstants.INTEGER_GTE)
1803                     .addRequiredValue(Build.VERSION_CODES.R, 1920)
1804                     .build();
1805             RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
1806                     .<Integer>builder()
1807                     .setId(RequirementConstants.SHORT_RESOLUTION)
1808                     .setPredicate(RequirementConstants.INTEGER_GTE)
1809                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1810                     .build();
1811 
1812             return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_1_1, long_resolution,
1813                 short_resolution);
1814         }
1815 
1816         /**
1817          * [7.1.1.1/H-2-1] MUST have screen resolution of at least 1080p.
1818          */
createR7_1_1_1__H_2_1()1819         public static ResolutionRequirement createR7_1_1_1__H_2_1() {
1820             RequiredMeasurement<Integer> long_resolution = RequiredMeasurement
1821                     .<Integer>builder()
1822                     .setId(RequirementConstants.LONG_RESOLUTION)
1823                     .setPredicate(RequirementConstants.INTEGER_GTE)
1824                     .addRequiredValue(Build.VERSION_CODES.S, 1920)
1825                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1920)
1826                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1920)
1827                     .build();
1828             RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
1829                     .<Integer>builder()
1830                     .setId(RequirementConstants.SHORT_RESOLUTION)
1831                     .setPredicate(RequirementConstants.INTEGER_GTE)
1832                     .addRequiredValue(Build.VERSION_CODES.S, 1080)
1833                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1834                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1080)
1835                     .build();
1836 
1837             return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_2_1, long_resolution,
1838                 short_resolution);
1839         }
1840     }
1841 
1842     // used for requirements [2.2.7.1/5.1/H-1-11], [2.2.7.1/5.7/H-1-2]
1843     public static class SecureCodecRequirement extends Requirement {
1844         private static final String TAG = SecureCodecRequirement.class.getSimpleName();
1845 
SecureCodecRequirement(String id, RequiredMeasurement<?> ... reqs)1846         private SecureCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
1847             super(id, reqs);
1848         }
1849 
setSecureReqSatisfied(boolean secureReqSatisfied)1850         public void setSecureReqSatisfied(boolean secureReqSatisfied) {
1851             this.setMeasuredValue(RequirementConstants.SECURE_REQ_SATISFIED, secureReqSatisfied);
1852         }
1853 
setNumCryptoHwSecureAllDec(int numCryptoHwSecureAllDec)1854         public void setNumCryptoHwSecureAllDec(int numCryptoHwSecureAllDec) {
1855             this.setMeasuredValue(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT,
1856                     numCryptoHwSecureAllDec);
1857         }
1858 
1859         /**
1860          * [2.2.7.1/5.7/H-1-2] MUST support MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL with the below
1861          * content decryption capabilities.
1862          */
createR5_7__H_1_2()1863         public static SecureCodecRequirement createR5_7__H_1_2() {
1864             RequiredMeasurement<Integer> hw_secure_all = RequiredMeasurement.<Integer>builder()
1865                     .setId(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT)
1866                     .setPredicate(RequirementConstants.INTEGER_GTE)
1867                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1868                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1869                     .build();
1870 
1871             return new SecureCodecRequirement(RequirementConstants.R5_7__H_1_2, hw_secure_all);
1872         }
1873 
1874         /**
1875          * [2.2.7.1/5.1/H-1-11] Must support secure decoder when a corresponding AVC/VP9/HEVC or AV1
1876          * hardware decoder is available
1877          */
createR5_1__H_1_11()1878         public static SecureCodecRequirement createR5_1__H_1_11() {
1879             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1880                     .<Boolean>builder()
1881                     .setId(RequirementConstants.SECURE_REQ_SATISFIED)
1882                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1883                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1884                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1885                     .build();
1886 
1887             return new SecureCodecRequirement(RequirementConstants.R5_1__H_1_11, requirement);
1888         }
1889     }
1890 
1891     public static class StreamUseCaseRequirement extends Requirement {
1892         private static final String TAG =
1893                 StreamUseCaseRequirement.class.getSimpleName();
1894 
StreamUseCaseRequirement(String id, RequiredMeasurement<?> ... reqs)1895         private StreamUseCaseRequirement(String id, RequiredMeasurement<?> ... reqs) {
1896             super(id, reqs);
1897         }
1898 
setRearStreamUseCaseSupported(boolean supported)1899         public void setRearStreamUseCaseSupported(boolean supported) {
1900             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED,
1901                     supported);
1902         }
1903 
setFrontStreamUseCaseSupported(boolean supported)1904         public void setFrontStreamUseCaseSupported(boolean supported) {
1905             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED,
1906                     supported);
1907         }
1908 
1909         /**
1910          * [2.2.7.2/7.5/H-1-14] MUST support STREAM_USE_CASE capability for both primary
1911          * front and primary back camera.
1912          */
createStreamUseCaseReq()1913         public static StreamUseCaseRequirement createStreamUseCaseReq() {
1914             RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
1915                     .<Boolean>builder()
1916                     .setId(RequirementConstants.REAR_CAMERA_STREAM_USECASE_SUPPORTED)
1917                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1918                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1919                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1920                     .build();
1921             RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
1922                     .<Boolean>builder()
1923                     .setId(RequirementConstants.FRONT_CAMERA_STREAM_USECASE_SUPPORTED)
1924                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1925                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1926                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1927                     .build();
1928 
1929             return new StreamUseCaseRequirement(RequirementConstants.R7_5__H_1_14,
1930                     rearRequirement, frontRequirement);
1931         }
1932     }
1933 
1934     public static class VideoCodecRequirement extends Requirement {
1935         private static final String TAG = VideoCodecRequirement.class.getSimpleName();
1936 
VideoCodecRequirement(String id, RequiredMeasurement<?> ... reqs)1937         private VideoCodecRequirement(String id, RequiredMeasurement<?> ... reqs) {
1938             super(id, reqs);
1939         }
1940 
setAv1DecoderReq(boolean av1DecoderReqSatisfied)1941         public void setAv1DecoderReq(boolean av1DecoderReqSatisfied) {
1942             this.setMeasuredValue(RequirementConstants.AV1_DEC_REQ, av1DecoderReqSatisfied);
1943         }
1944 
set4kHwDecoders(int num4kHwDecoders)1945         public void set4kHwDecoders(int num4kHwDecoders) {
1946             this.setMeasuredValue(RequirementConstants.NUM_4k_HW_DEC, num4kHwDecoders);
1947         }
1948 
set4kHwEncoders(int num4kHwEncoders)1949         public void set4kHwEncoders(int num4kHwEncoders) {
1950             this.setMeasuredValue(RequirementConstants.NUM_4k_HW_ENC, num4kHwEncoders);
1951         }
1952 
setAVIFDecoderReq(boolean avifDecoderReqSatisfied)1953         public void setAVIFDecoderReq(boolean avifDecoderReqSatisfied) {
1954             this.setMeasuredValue(RequirementConstants.AVIF_DEC_REQ, avifDecoderReqSatisfied);
1955         }
1956 
setAv1EncResolution(int resolution)1957         public void setAv1EncResolution(int resolution) {
1958             this.setMeasuredValue(RequirementConstants.AV1_ENC_RESOLUTION, resolution);
1959         }
1960 
setAv1EncFps(double fps)1961         public void setAv1EncFps(double fps) {
1962             this.setMeasuredValue(RequirementConstants.AV1_ENC_FPS, fps);
1963         }
1964 
setAv1EncBitrate(int bitrate)1965         public void setAv1EncBitrate(int bitrate) {
1966             this.setMeasuredValue(RequirementConstants.AV1_ENC_BITRATE, bitrate);
1967         }
1968 
setColorFormatSupportReq(boolean colorFormatSupported)1969         public void setColorFormatSupportReq(boolean colorFormatSupported) {
1970             this.setMeasuredValue(RequirementConstants.RGBA_1010102_COLOR_FORMAT_REQ,
1971                     colorFormatSupported);
1972         }
1973 
1974         /**
1975          * [2.2.7.1/5.1/H-1-15] Must have at least 1 HW video decoder supporting 4K60
1976          */
createR4k60HwDecoder()1977         public static VideoCodecRequirement createR4k60HwDecoder() {
1978             RequiredMeasurement<Integer> requirement = RequiredMeasurement
1979                     .<Integer>builder()
1980                     .setId(RequirementConstants.NUM_4k_HW_DEC)
1981                     .setPredicate(RequirementConstants.INTEGER_GTE)
1982                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1983                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1984                     .build();
1985 
1986             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_15, requirement);
1987         }
1988 
1989         /**
1990          * [2.2.7.1/5.1/H-1-16] Must have at least 1 HW video encoder supporting 4K60
1991          */
createR4k60HwEncoder()1992         public static VideoCodecRequirement createR4k60HwEncoder() {
1993             RequiredMeasurement<Integer> requirement = RequiredMeasurement
1994                     .<Integer>builder()
1995                     .setId(RequirementConstants.NUM_4k_HW_ENC)
1996                     .setPredicate(RequirementConstants.INTEGER_GTE)
1997                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1998                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1999                     .build();
2000 
2001             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_16, requirement);
2002         }
2003 
2004         /**
2005          * [2.2.7.1/5.1/H-1-14] AV1 Hardware decoder: Main 10, Level 4.1, Film Grain
2006          */
createRAV1DecoderReq()2007         public static VideoCodecRequirement createRAV1DecoderReq() {
2008             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
2009                     .<Boolean>builder()
2010                     .setId(RequirementConstants.AV1_DEC_REQ)
2011                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
2012                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
2013                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
2014                     .build();
2015 
2016             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_14, requirement);
2017         }
2018 
2019         /**
2020          * [5.1/H-1-17] MUST have at least 1 Hw image decoder supporting AVIF Baseline profile.
2021          */
createRAVIFDecoderReq()2022         public static VideoCodecRequirement createRAVIFDecoderReq() {
2023             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
2024                     .<Boolean>builder()
2025                     .setId(RequirementConstants.AVIF_DEC_REQ)
2026                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
2027                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
2028                     .build();
2029 
2030             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_17, requirement);
2031         }
2032 
2033         /**
2034          * [2.2.7.1/5.1/H-1-18] MUST support AV1 encoder which can encode up to 480p resolution
2035          * at 30fps and 1Mbps.
2036          */
createRAV1EncoderReq()2037         public static VideoCodecRequirement createRAV1EncoderReq() {
2038             RequiredMeasurement<Integer> resolution = RequiredMeasurement
2039                     .<Integer>builder()
2040                     .setId(RequirementConstants.AV1_ENC_RESOLUTION)
2041                     .setPredicate(RequirementConstants.INTEGER_GTE)
2042                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 480)
2043                     .build();
2044 
2045             RequiredMeasurement<Double> fps = RequiredMeasurement
2046                     .<Double>builder()
2047                     .setId(RequirementConstants.AV1_ENC_FPS)
2048                     .setPredicate(RequirementConstants.DOUBLE_GTE)
2049                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 30.0)
2050                     .build();
2051 
2052             RequiredMeasurement<Integer> bitrate = RequiredMeasurement
2053                     .<Integer>builder()
2054                     .setId(RequirementConstants.AV1_ENC_BITRATE)
2055                     .setPredicate(RequirementConstants.INTEGER_GTE)
2056                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
2057                     .build();
2058 
2059             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_18, resolution, fps,
2060                     bitrate);
2061         }
2062 
2063         /**
2064          * [5.12/H-1-2] MUST support RGBA_1010102 color format for all hardware AV1 and HEVC
2065          * encoders present on the device.
2066          */
createColorFormatSupportReq()2067         public static VideoCodecRequirement createColorFormatSupportReq() {
2068             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
2069                     .<Boolean>builder()
2070                     .setId(RequirementConstants.RGBA_1010102_COLOR_FORMAT_REQ)
2071                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
2072                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
2073                     .build();
2074 
2075             return new VideoCodecRequirement(RequirementConstants.R5_12__H_1_2, requirement);
2076         }
2077     }
2078 
2079     public static class UltraWideZoomRatioRequirement extends Requirement {
2080         private static final String TAG =
2081                 UltraWideZoomRatioRequirement.class.getSimpleName();
2082 
UltraWideZoomRatioRequirement(String id, RequiredMeasurement<?> ... reqs)2083         private UltraWideZoomRatioRequirement(String id, RequiredMeasurement<?> ... reqs) {
2084             super(id, reqs);
2085         }
2086 
setRearUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet)2087         public void setRearUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
2088             this.setMeasuredValue(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
2089                     ultrawideZoomRatioReqMet);
2090         }
2091 
setFrontUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet)2092         public void setFrontUltraWideZoomRatioReqMet(boolean ultrawideZoomRatioReqMet) {
2093             this.setMeasuredValue(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET,
2094                     ultrawideZoomRatioReqMet);
2095         }
2096 
2097         /**
2098          * [2.2.7.2/7.5/H-1-10] MUST have min ZOOM_RATIO < 1.0 for the primary cameras if
2099          * there is an ultrawide RGB camera facing the same direction.
2100          */
createUltrawideZoomRatioReq()2101         public static UltraWideZoomRatioRequirement createUltrawideZoomRatioReq() {
2102             RequiredMeasurement<Boolean> rearRequirement = RequiredMeasurement
2103                     .<Boolean>builder()
2104                     .setId(RequirementConstants.REAR_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
2105                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
2106                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
2107                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
2108                     .build();
2109             RequiredMeasurement<Boolean> frontRequirement = RequiredMeasurement
2110                     .<Boolean>builder()
2111                     .setId(RequirementConstants.FRONT_CAMERA_ULTRAWIDE_ZOOMRATIO_REQ_MET)
2112                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
2113                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
2114                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
2115                     .build();
2116 
2117             return new UltraWideZoomRatioRequirement(RequirementConstants.R7_5__H_1_10,
2118                     rearRequirement, frontRequirement);
2119         }
2120     }
2121 
addRequirement(R req)2122     public <R extends Requirement> R addRequirement(R req) {
2123         if (!this.mRequirements.add(req)) {
2124             throw new IllegalStateException("Requirement " + req.id() + " already added");
2125         }
2126         return req;
2127     }
2128 
addR5_1__H_1_1_720p(String mimeType1, String mimeType2, int resolution)2129     public ConcurrentCodecRequirement addR5_1__H_1_1_720p(String mimeType1, String mimeType2,
2130         int resolution) {
2131         return this.addRequirement(
2132             ConcurrentCodecRequirement.createR5_1__H_1_1_720p(mimeType1, mimeType2, resolution));
2133     }
2134 
addR5_1__H_1_1_1080p()2135     public ConcurrentCodecRequirement addR5_1__H_1_1_1080p() {
2136         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_1_1080p());
2137     }
2138 
addR5_1__H_1_1_4k()2139     public ConcurrentCodecRequirement addR5_1__H_1_1_4k() {
2140         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_1_4k());
2141     }
2142 
addR5_1__H_1_2_720p(String mimeType1, String mimeType2, int resolution)2143     public ConcurrentCodecRequirement addR5_1__H_1_2_720p(String mimeType1, String mimeType2,
2144         int resolution) {
2145         return this.addRequirement(
2146             ConcurrentCodecRequirement.createR5_1__H_1_2_720p(mimeType1, mimeType2, resolution));
2147     }
2148 
addR5_1__H_1_2_1080p()2149     public ConcurrentCodecRequirement addR5_1__H_1_2_1080p() {
2150         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_2_1080p());
2151     }
2152 
addR5_1__H_1_2_4k()2153     public ConcurrentCodecRequirement addR5_1__H_1_2_4k() {
2154         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_2_4k());
2155     }
2156 
addR5_1__H_1_3_720p(String mimeType1, String mimeType2, int resolution)2157     public ConcurrentCodecRequirement addR5_1__H_1_3_720p(String mimeType1, String mimeType2,
2158         int resolution) {
2159         return this.addRequirement(
2160             ConcurrentCodecRequirement.createR5_1__H_1_3_720p(mimeType1, mimeType2, resolution));
2161     }
2162 
addR5_1__H_1_3_1080p()2163     public ConcurrentCodecRequirement addR5_1__H_1_3_1080p() {
2164         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_3_1080p());
2165     }
2166 
addR5_1__H_1_3_4k()2167     public ConcurrentCodecRequirement addR5_1__H_1_3_4k() {
2168         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_3_4K());
2169     }
2170 
addR5_1__H_1_4_720p()2171     public ConcurrentCodecRequirement addR5_1__H_1_4_720p() {
2172         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_720p());
2173     }
2174 
addR5_1__H_1_4_1080p()2175     public ConcurrentCodecRequirement addR5_1__H_1_4_1080p() {
2176         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_1080p());
2177     }
2178 
addR5_1__H_1_4_4k()2179     public ConcurrentCodecRequirement addR5_1__H_1_4_4k() {
2180         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_4k());
2181     }
2182 
addR5_1__H_1_5_720p(String mimeType1, String mimeType2, int resolution)2183     public ConcurrentCodecRequirement addR5_1__H_1_5_720p(String mimeType1, String mimeType2,
2184         int resolution) {
2185         return this.addRequirement(
2186             ConcurrentCodecRequirement.createR5_1__H_1_5_720p(mimeType1, mimeType2, resolution));
2187     }
2188 
addR5_1__H_1_5_1080p()2189     public ConcurrentCodecRequirement addR5_1__H_1_5_1080p() {
2190         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_5_1080p());
2191     }
2192 
addR5_1__H_1_5_4k()2193     public ConcurrentCodecRequirement addR5_1__H_1_5_4k() {
2194         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_5_4k());
2195     }
2196 
addR5_1__H_1_6_720p(String mimeType1, String mimeType2, int resolution)2197     public ConcurrentCodecRequirement addR5_1__H_1_6_720p(String mimeType1, String mimeType2,
2198         int resolution) {
2199         return this.addRequirement(
2200             ConcurrentCodecRequirement.createR5_1__H_1_6_720p(mimeType1, mimeType2, resolution));
2201     }
2202 
addR5_1__H_1_6_1080p()2203     public ConcurrentCodecRequirement addR5_1__H_1_6_1080p() {
2204         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_6_1080p());
2205     }
2206 
addR5_1__H_1_6_4k()2207     public ConcurrentCodecRequirement addR5_1__H_1_6_4k() {
2208         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_6_4k());
2209     }
2210 
addR5_1__H_1_7(String mediaType)2211     public CodecInitLatencyRequirement addR5_1__H_1_7(String mediaType) {
2212         return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_7(mediaType));
2213     }
2214 
addR5_1__H_1_8()2215     public CodecInitLatencyRequirement addR5_1__H_1_8() {
2216         return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_8());
2217     }
2218 
addR5_1__H_1_9_1080p()2219     public ConcurrentCodecRequirement addR5_1__H_1_9_1080p() {
2220         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_9_1080p());
2221     }
2222 
addR5_1__H_1_9_4k()2223     public ConcurrentCodecRequirement addR5_1__H_1_9_4k() {
2224         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_9_4k());
2225     }
2226 
addR5_1__H_1_10_1080p()2227     public ConcurrentCodecRequirement addR5_1__H_1_10_1080p() {
2228         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10_1080p());
2229     }
2230 
addR5_1__H_1_10_4k()2231     public ConcurrentCodecRequirement addR5_1__H_1_10_4k() {
2232         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10_4k());
2233     }
addR5_1__H_1_11()2234     public SecureCodecRequirement addR5_1__H_1_11() {
2235         return this.addRequirement(SecureCodecRequirement.createR5_1__H_1_11());
2236     }
2237 
addR5_1__H_1_12()2238     public CodecInitLatencyRequirement addR5_1__H_1_12() {
2239         return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_12());
2240     }
2241 
addR5_1__H_1_13()2242     public CodecInitLatencyRequirement addR5_1__H_1_13() {
2243         return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_13());
2244     }
2245 
2246     /* Adds requirement 5.1/H-1-14 */
addRAV1DecoderReq()2247     public VideoCodecRequirement addRAV1DecoderReq() {
2248         return this.addRequirement(VideoCodecRequirement.createRAV1DecoderReq());
2249     }
2250 
2251     /* Adds requirement 5.1/H-1-15 */
addR4k60HwDecoder()2252     public VideoCodecRequirement addR4k60HwDecoder() {
2253         return this.addRequirement(VideoCodecRequirement.createR4k60HwDecoder());
2254     }
2255 
2256     /* Adds requirement 5.1/H-1-16 */
addR4k60HwEncoder()2257     public VideoCodecRequirement addR4k60HwEncoder() {
2258         return this.addRequirement(VideoCodecRequirement.createR4k60HwEncoder());
2259     }
2260 
2261     /* Adds requirement 5.1/H-1-17 */
addRAVIFDecoderReq()2262     public VideoCodecRequirement addRAVIFDecoderReq() {
2263         return this.addRequirement(VideoCodecRequirement.createRAVIFDecoderReq());
2264     }
2265 
2266     /* Adds requirement 5.1/H-1-18 */
addRAV1EncoderReq()2267     public VideoCodecRequirement addRAV1EncoderReq() {
2268         return this.addRequirement(VideoCodecRequirement.createRAV1EncoderReq());
2269     }
2270 
addR5_1__H_1_19()2271     public ConcurrentCodecRequirement addR5_1__H_1_19() {
2272         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_19());
2273     }
2274 
2275 
addR5_3__H_1_1_R()2276     public FrameDropRequirement addR5_3__H_1_1_R() {
2277         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_R());
2278     }
2279 
addR5_3__H_1_1_ST()2280     public FrameDropRequirement addR5_3__H_1_1_ST() {
2281         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_ST());
2282     }
2283 
addR5_3__H_1_1_U()2284     public FrameDropRequirement addR5_3__H_1_1_U() {
2285         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_U());
2286     }
2287 
addR5_3__H_1_2_R()2288     public FrameDropRequirement addR5_3__H_1_2_R() {
2289         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_R());
2290     }
2291 
addR5_3__H_1_2_ST()2292     public FrameDropRequirement addR5_3__H_1_2_ST() {
2293         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_ST());
2294     }
2295 
addR5_3__H_1_2_U()2296     public FrameDropRequirement addR5_3__H_1_2_U() {
2297         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_U());
2298     }
2299 
2300 
addR5_6__H_1_1()2301     public AudioTap2ToneLatencyRequirement addR5_6__H_1_1() {
2302         return this.addRequirement(AudioTap2ToneLatencyRequirement.createR5_6__H_1_1());
2303     }
2304 
2305 
addR5_7__H_1_2()2306     public SecureCodecRequirement addR5_7__H_1_2() {
2307         return this.addRequirement(SecureCodecRequirement.createR5_7__H_1_2());
2308     }
2309 
2310 
2311     /* Adds requirement 5.12/H-1-2 */
addColorFormatSupportReq()2312     public VideoCodecRequirement addColorFormatSupportReq() {
2313         return this.addRequirement(VideoCodecRequirement.createColorFormatSupportReq());
2314     }
2315 
2316     /* Adds requirement 5.12/H-1-3 */
addExtYUVSupportReq()2317     public ExtYuvTargetRequirement addExtYUVSupportReq() {
2318         return this.addRequirement(ExtYuvTargetRequirement.createExtensionReq());
2319     }
2320 
2321 
2322     /* Adds requirement 7.5/H-1-1 */
addPrimaryRearCameraReq()2323     public PrimaryCameraRequirement addPrimaryRearCameraReq() {
2324         return this.addRequirement(PrimaryCameraRequirement.createRearPrimaryCamera());
2325     }
2326 
2327     /* Adds requirement 7.5/H-1-2 */
addPrimaryFrontCameraReq()2328     public PrimaryCameraRequirement addPrimaryFrontCameraReq() {
2329         return this.addRequirement(PrimaryCameraRequirement.createFrontPrimaryCamera());
2330     }
2331 
addR7_5__H_1_4()2332     public CameraTimestampSourceRequirement addR7_5__H_1_4() {
2333         return this.addRequirement(CameraTimestampSourceRequirement.createTimestampSourceReq());
2334     }
2335 
addR7_5__H_1_5()2336     public CameraLatencyRequirement addR7_5__H_1_5() {
2337         return this.addRequirement(CameraLatencyRequirement.createJpegLatencyReq());
2338     }
2339 
addR7_5__H_1_6()2340     public CameraLatencyRequirement addR7_5__H_1_6() {
2341         return this.addRequirement(CameraLatencyRequirement.createLaunchLatencyReq());
2342     }
2343 
addR7_5__H_1_8()2344     public CameraRawRequirement addR7_5__H_1_8() {
2345         return this.addRequirement(CameraRawRequirement.createRawReq());
2346     }
2347 
addR7_5__H_1_9()2348     public Camera240FpsRequirement addR7_5__H_1_9() {
2349         return this.addRequirement(Camera240FpsRequirement.create240FpsReq());
2350     }
2351 
addR7_5__H_1_10()2352     public UltraWideZoomRatioRequirement addR7_5__H_1_10() {
2353         return this.addRequirement(UltraWideZoomRatioRequirement.createUltrawideZoomRatioReq());
2354     }
2355 
addR7_5__H_1_11()2356     public ConcurrentRearFrontRequirement addR7_5__H_1_11() {
2357         return this.addRequirement(ConcurrentRearFrontRequirement.createConcurrentRearFrontReq());
2358     }
2359 
addR7_5__H_1_12()2360     public PreviewStabilizationRequirement addR7_5__H_1_12() {
2361         return this.addRequirement(PreviewStabilizationRequirement.createPreviewStabilizationReq());
2362     }
2363 
addR7_5__H_1_13()2364     public LogicalMultiCameraRequirement addR7_5__H_1_13() {
2365         return this.addRequirement(LogicalMultiCameraRequirement.createLogicalMultiCameraReq());
2366     }
2367 
addR7_5__H_1_14()2368     public StreamUseCaseRequirement addR7_5__H_1_14() {
2369         return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq());
2370     }
2371 
addR7_5__H_1_15()2372     public CameraExtensionRequirement addR7_5__H_1_15() {
2373         return this.addRequirement(CameraExtensionRequirement.createCameraExtensionReq());
2374     }
2375 
addR7_5__H_1_16()2376     public DynamicRangeTenBitsRequirement addR7_5__H_1_16() {
2377         return this.addRequirement(DynamicRangeTenBitsRequirement.createDynamicRangeTenBitsReq());
2378     }
2379 
addR7_5__H_1_17()2380     public FaceDetectionRequirement addR7_5__H_1_17() {
2381         return this.addRequirement(FaceDetectionRequirement.createFaceDetectionReq());
2382     }
2383 
2384 
addR7_1_1_1__H_1_1()2385     public ResolutionRequirement addR7_1_1_1__H_1_1() {
2386         return this.<ResolutionRequirement>addRequirement(
2387             ResolutionRequirement.createR7_1_1_1__H_1_1());
2388     }
2389 
addR7_1_1_3__H_1_1()2390     public DensityRequirement addR7_1_1_3__H_1_1() {
2391         return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__H_1_1());
2392     }
2393 
addR7_6_1__H_1_1()2394     public MemoryRequirement addR7_6_1__H_1_1() {
2395         return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_1_1());
2396     }
2397 
addR7_1_1_1__H_2_1()2398     public ResolutionRequirement addR7_1_1_1__H_2_1() {
2399         return this.<ResolutionRequirement>addRequirement(
2400             ResolutionRequirement.createR7_1_1_1__H_2_1());
2401     }
2402 
addR7_1_1_3__H_2_1()2403     public DensityRequirement addR7_1_1_3__H_2_1() {
2404         return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__H_2_1());
2405     }
2406 
addR7_6_1__H_2_1()2407     public MemoryRequirement addR7_6_1__H_2_1() {
2408         return this.<MemoryRequirement>addRequirement(MemoryRequirement.createR7_6_1__H_2_1());
2409     }
2410 
2411 
addR8_2__H_1_1()2412     public FileSystemRequirement addR8_2__H_1_1() {
2413         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_1());
2414     }
2415 
addR8_2__H_2_1()2416     public FileSystemRequirement addR8_2__H_2_1() {
2417         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_1());
2418     }
2419 
addR8_2__H_1_2()2420     public FileSystemRequirement addR8_2__H_1_2() {
2421         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_2());
2422     }
2423 
addR8_2__H_2_2()2424     public FileSystemRequirement addR8_2__H_2_2() {
2425         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_2());
2426     }
2427 
addR8_2__H_1_3()2428     public FileSystemRequirement addR8_2__H_1_3() {
2429         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_3());
2430     }
2431 
addR8_2__H_2_3()2432     public FileSystemRequirement addR8_2__H_2_3() {
2433         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_3());
2434     }
2435 
addR8_2__H_1_4()2436     public FileSystemRequirement addR8_2__H_1_4() {
2437         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_4());
2438     }
2439 
addR8_2__H_2_4()2440     public FileSystemRequirement addR8_2__H_2_4() {
2441         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_4());
2442     }
2443 
2444 
2445     private enum SubmitType {
2446         TRADEFED, VERIFIER
2447     }
2448 
submitAndCheck()2449     public void submitAndCheck() {
2450         boolean perfClassMet = submit(SubmitType.TRADEFED);
2451 
2452         // check performance class
2453         assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass());
2454         assertThat(perfClassMet).isTrue();
2455     }
2456 
submitAndVerify()2457     public void submitAndVerify() {
2458         boolean perfClassMet = submit(SubmitType.VERIFIER);
2459 
2460         if (!perfClassMet && Utils.isPerfClass()) {
2461             Log.w(TAG, "Device did not meet specified performance class: " + Utils.getPerfClass());
2462         }
2463     }
2464 
submit(SubmitType type)2465     private boolean submit(SubmitType type) {
2466         boolean perfClassMet = true;
2467         for (Requirement req: this.mRequirements) {
2468             switch (type) {
2469                 case VERIFIER:
2470                     CtsVerifierReportLog verifierLog = new CtsVerifierReportLog(
2471                             RequirementConstants.REPORT_LOG_NAME, req.id());
2472                     perfClassMet &= req.writeLogAndCheck(verifierLog, this.mTestName);
2473                     verifierLog.submit();
2474                     break;
2475 
2476                 case TRADEFED:
2477                 default:
2478                     DeviceReportLog tradefedLog = new DeviceReportLog(
2479                             RequirementConstants.REPORT_LOG_NAME, req.id());
2480                     perfClassMet &= req.writeLogAndCheck(tradefedLog, this.mTestName);
2481                     tradefedLog.submit(InstrumentationRegistry.getInstrumentation());
2482                     break;
2483             }
2484         }
2485         this.mRequirements.clear(); // makes sure report isn't submitted twice
2486         return perfClassMet;
2487     }
2488 }
2489