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 License.
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.media.MediaFormat;
24 import android.mediapc.cts.common.CameraRequirement.*;
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.R, 100.0)
86                     .addRequiredValue(Build.VERSION_CODES.S, 100.0)
87                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
88                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 80.0)
89                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 80.0)
90                     .build();
91             RequiredMeasurement<Double> apiJavaLatency = RequiredMeasurement
92                     .<Double>builder()
93                     .setId(RequirementConstants.API_JAVA_LATENCY)
94                     .setPredicate(RequirementConstants.DOUBLE_LTE)
95                     .addRequiredValue(Build.VERSION_CODES.R, 100.0)
96                     .addRequiredValue(Build.VERSION_CODES.S, 100.0)
97                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 80.0)
98                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 80.0)
99                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 80.0)
100                     .build();
101 
102             return new AudioTap2ToneLatencyRequirement(
103                     RequirementConstants.R5_6__H_1_1,
104                     apiNativeLatency,
105                     apiJavaLatency);
106         }
107     }
108 
109     public static class CodecInitLatencyRequirement extends Requirement {
110 
111         private static final String TAG = CodecInitLatencyRequirement.class.getSimpleName();
112 
CodecInitLatencyRequirement(String id, RequiredMeasurement<?>... reqs)113         private CodecInitLatencyRequirement(String id, RequiredMeasurement<?>... reqs) {
114             super(id, reqs);
115         }
116 
setCodecInitLatencyMs(long codecInitLatencyMs)117         public void setCodecInitLatencyMs(long codecInitLatencyMs) {
118             this.setMeasuredValue(RequirementConstants.CODEC_INIT_LATENCY, codecInitLatencyMs);
119         }
120 
121         /**
122          * [2.2.7.1/5.1/H-1-7] MUST have a codec initialization latency of 65(R) / 50(S) / 40(T)
123          * ms or less for a 1080p or smaller video encoding session for all hardware video
124          * encoders when under load. Load here is defined as a concurrent 1080p to 720p
125          * video-only transcoding session using hardware video codecs together with the 1080p
126          * audio-video recording initialization. For Dolby vision codec, the codec initialization
127          * latency MUST be 50 ms or less.
128          */
createR5_1__H_1_7(String mediaType)129         public static CodecInitLatencyRequirement createR5_1__H_1_7(String mediaType) {
130             long latency = mediaType.equals(MediaFormat.MIMETYPE_VIDEO_DOLBY_VISION) ? 50L : 40L;
131             RequiredMeasurement<Long> codec_init_latency =
132                     RequiredMeasurement.<Long>builder().setId(
133                                     RequirementConstants.CODEC_INIT_LATENCY)
134                             .setPredicate(RequirementConstants.LONG_LTE)
135                             .addRequiredValue(Build.VERSION_CODES.R, 65L)
136                             .addRequiredValue(Build.VERSION_CODES.S, 50L)
137                             .addRequiredValue(Build.VERSION_CODES.TIRAMISU, latency)
138                             .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, latency)
139                             .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, latency)
140                             .build();
141 
142             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_7,
143                     codec_init_latency);
144         }
145 
146         /**
147          * [2.2.7.1/5.1/H-1-8] MUST have a codec initialization latency of 50(R) / 40(S) / 30(T)
148          * ms or less for a 128 kbps or lower bitrate audio encoding session for all audio
149          * encoders when under load. Load here is defined as a concurrent 1080p to 720p
150          * video-only transcoding session using hardware video codecs together with the 1080p
151          * audio-video recording initialization.
152          */
createR5_1__H_1_8()153         public static CodecInitLatencyRequirement createR5_1__H_1_8() {
154             RequiredMeasurement<Long> codec_init_latency =
155                     RequiredMeasurement.<Long>builder().setId(
156                                     RequirementConstants.CODEC_INIT_LATENCY)
157                             .setPredicate(RequirementConstants.LONG_LTE)
158                             .addRequiredValue(Build.VERSION_CODES.R, 50L)
159                             .addRequiredValue(Build.VERSION_CODES.S, 40L)
160                             .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 30L)
161                             .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 30L)
162                             .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 30L)
163                             .build();
164 
165             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_8,
166                     codec_init_latency);
167         }
168 
169         /**
170          * [2.2.7.1/5.1/H-1-12] Codec initialization latency of 40ms or less for a 1080p or
171          * smaller video decoding session for all hardware video encoders when under load. Load
172          * here is defined as a concurrent 1080p to 720p video-only transcoding session using
173          * hardware video codecs together with the 1080p audio-video recording initialization.
174          */
createR5_1__H_1_12()175         public static CodecInitLatencyRequirement createR5_1__H_1_12() {
176             RequiredMeasurement<Long> codec_init_latency =
177                     RequiredMeasurement.<Long>builder().setId(
178                                     RequirementConstants.CODEC_INIT_LATENCY)
179                             .setPredicate(RequirementConstants.LONG_LTE)
180                             .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40L)
181                             .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 40L)
182                             .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 40L)
183                             .build();
184 
185             return new CodecInitLatencyRequirement(RequirementConstants.R5_1__H_1_12,
186                     codec_init_latency);
187         }
188     }
189 
190     // 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],
191     // [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],
192     // [2.2.7.1/5.1/H-1-10]
193     public static class ConcurrentCodecRequirement extends Requirement {
194         private static final String TAG = ConcurrentCodecRequirement.class.getSimpleName();
195         // allowed tolerance in measured fps vs expected fps in percentage, i.e. codecs achieving
196         // fps that is greater than (FPS_TOLERANCE_FACTOR * expectedFps) will be considered as
197         // passing the test
198         private static final double FPS_TOLERANCE_FACTOR = 0.95;
199         private static final double FPS_30_TOLERANCE = 30.0 * FPS_TOLERANCE_FACTOR;
200         static final int REQUIRED_MIN_CONCURRENT_INSTANCES = 6;
201         static final int REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9 = 2;
202 
ConcurrentCodecRequirement(String id, RequiredMeasurement<?>... reqs)203         private ConcurrentCodecRequirement(String id, RequiredMeasurement<?>... reqs) {
204             super(id, reqs);
205         }
206 
setConcurrentInstances(int concurrentInstances)207         public void setConcurrentInstances(int concurrentInstances) {
208             this.setMeasuredValue(RequirementConstants.CONCURRENT_SESSIONS,
209                     concurrentInstances);
210         }
211 
setConcurrentFps(double achievedFps)212         public void setConcurrentFps(double achievedFps) {
213             this.setMeasuredValue(RequirementConstants.CONCURRENT_FPS, achievedFps);
214         }
215 
setFrameDropsPerSecond(double fdps)216         public void setFrameDropsPerSecond(double fdps) {
217             this.setMeasuredValue(RequirementConstants.FRAMES_DROPPED_PER_SECOND, fdps);
218         }
219 
220         // copied from android.mediapc.cts.getReqMinConcurrentInstances due to build issues on aosp
getReqMinConcurrentInstances(int performanceClass, String mimeType1, String mimeType2, int resolution)221         public static int getReqMinConcurrentInstances(int performanceClass, String mimeType1,
222                 String mimeType2, int resolution) {
223             ArrayList<String> MEDIAPC_CONCURRENT_CODECS_R = new ArrayList<>(
224                     Arrays.asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC));
225             ArrayList<String> MEDIAPC_CONCURRENT_CODECS = new ArrayList<>(Arrays
226                     .asList(MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
227                             MediaFormat.MIMETYPE_VIDEO_VP9, MediaFormat.MIMETYPE_VIDEO_AV1));
228 
229             if (performanceClass >= Build.VERSION_CODES.TIRAMISU) {
230                 return resolution >= 1080 ? REQUIRED_MIN_CONCURRENT_INSTANCES : 0;
231             } else if (performanceClass == Build.VERSION_CODES.S) {
232                 if (resolution >= 1080) {
233                     return 0;
234                 }
235                 if (MEDIAPC_CONCURRENT_CODECS.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS
236                         .contains(mimeType2)) {
237                     if (MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType1)
238                             || MediaFormat.MIMETYPE_VIDEO_VP9.equalsIgnoreCase(mimeType2)) {
239                         return REQUIRED_MIN_CONCURRENT_INSTANCES_FOR_VP9;
240                     } else {
241                         return REQUIRED_MIN_CONCURRENT_INSTANCES;
242                     }
243                 } else {
244                     return 0;
245                 }
246             } else if (performanceClass == Build.VERSION_CODES.R) {
247                 if (resolution >= 1080) {
248                     return 0;
249                 }
250                 if (MEDIAPC_CONCURRENT_CODECS_R.contains(mimeType1) && MEDIAPC_CONCURRENT_CODECS_R
251                         .contains(mimeType2)) {
252                     return REQUIRED_MIN_CONCURRENT_INSTANCES;
253                 } else {
254                     return 0;
255                 }
256             } else {
257                 return 0;
258             }
259         }
260 
getReqMinConcurrentFps(int performanceClass, String mimeType1, String mimeType2, int resolution)261         private static double getReqMinConcurrentFps(int performanceClass, String mimeType1,
262                 String mimeType2, int resolution) {
263             return FPS_30_TOLERANCE * getReqMinConcurrentInstances(performanceClass, mimeType1,
264                     mimeType2, resolution);
265         }
266 
267         /**
268          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
269          * a requirement for tests ran with a resolution of 720p
270          */
create720p(String requirementId, RequiredMeasurement<?> measure)271         private static ConcurrentCodecRequirement create720p(String requirementId,
272                 RequiredMeasurement<?> measure) {
273             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
274                     .setId(RequirementConstants.TEST_RESOLUTION)
275                     .setPredicate(RequirementConstants.INTEGER_EQ)
276                     .addRequiredValue(Build.VERSION_CODES.R, 720)
277                     .build();
278 
279             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
280                     testResolution);
281             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 720);
282             return req;
283         }
284 
285         /**
286          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
287          * a requirement for tests ran with a resolution of 1080p
288          */
create1080p(String requirementId, RequiredMeasurement<?> measure)289         private static ConcurrentCodecRequirement create1080p(String requirementId,
290                 RequiredMeasurement<?> measure) {
291             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
292                     .setId(RequirementConstants.TEST_RESOLUTION)
293                     .setPredicate(RequirementConstants.INTEGER_EQ)
294                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
295                     .build();
296 
297             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
298                     testResolution);
299             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 1080);
300             return req;
301         }
302 
303         /**
304          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
305          * a requirement for tests ran with a resolution of 4k
306          */
create4k(String requirementId, RequiredMeasurement<?> measure)307         private static ConcurrentCodecRequirement create4k(String requirementId,
308                 RequiredMeasurement<?> measure) {
309             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
310                     .setId(RequirementConstants.TEST_RESOLUTION)
311                     .setPredicate(RequirementConstants.INTEGER_EQ)
312                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
313                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 2160)
314                     .build();
315 
316             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(requirementId, measure,
317                     testResolution);
318             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, 2160);
319             return req;
320         }
321 
322         /**
323          * Helper method used to create ConcurrentCodecRequirements, builds and fills out the
324          * a requirement for tests ran with a resolution of 4k
325          */
create4k(String requirementId, RequiredMeasurement<?> measure1, RequiredMeasurement<?> measure2)326         private static ConcurrentCodecRequirement create4k(String requirementId,
327                 RequiredMeasurement<?> measure1, RequiredMeasurement<?> measure2) {
328             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
329                     .setId(RequirementConstants.TEST_RESOLUTION)
330                     .setPredicate(RequirementConstants.INTEGER_EQ)
331                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
332                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 2160)
333                     .build();
334 
335             ConcurrentCodecRequirement req = new ConcurrentCodecRequirement(
336                     requirementId, testResolution, measure1, measure2);
337             req.setMeasuredValue(RequirementConstants.TEST_RESOLUTION,  2160);
338             return req;
339         }
340 
341         /**
342          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
343          * sessions that can be run concurrently in any codec combination via the
344          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
345          * .getSupportedPerformancePoints() methods.
346          */
createR5_1__H_1_1_720p(String mimeType1, String mimeType2, int resolution)347         public static ConcurrentCodecRequirement createR5_1__H_1_1_720p(String mimeType1,
348                 String mimeType2, int resolution) {
349             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
350                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
351                     .setPredicate(RequirementConstants.INTEGER_GTE)
352                     .addRequiredValue(Build.VERSION_CODES.R,
353                             getReqMinConcurrentInstances(
354                                     Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
355                     .addRequiredValue(Build.VERSION_CODES.S,
356                             getReqMinConcurrentInstances(
357                                     Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
358                     .build();
359 
360             return create720p(RequirementConstants.R5_1__H_1_1, maxInstances);
361         }
362 
363         /**
364          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
365          * sessions that can be run concurrently in any codec combination via the
366          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
367          * .getSupportedPerformancePoints() methods.
368          */
createR5_1__H_1_1_1080p()369         public static ConcurrentCodecRequirement createR5_1__H_1_1_1080p() {
370             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
371                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
372                     .setPredicate(RequirementConstants.INTEGER_GTE)
373                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
374                     .build();
375 
376             return create1080p(RequirementConstants.R5_1__H_1_1, maxInstances);
377         }
378 
379         /**
380          * [2.2.7.1/5.1/H-1-1] MUST advertise the maximum number of hardware video decoder
381          * sessions that can be run concurrently in any codec combination via the
382          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
383          * .getSupportedPerformancePoints() methods.
384          */
createR5_1__H_1_1_4k()385         public static ConcurrentCodecRequirement createR5_1__H_1_1_4k() {
386             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
387                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
388                     .setPredicate(RequirementConstants.INTEGER_GTE)
389                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
390                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 6)
391                     .build();
392 
393             return create4k(RequirementConstants.R5_1__H_1_1, maxInstances);
394         }
395 
396         /**
397          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
398          * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
399          * resolution@30 fps.
400          */
createR5_1__H_1_2_720p(String mimeType1, String mimeType2, int resolution)401         public static ConcurrentCodecRequirement createR5_1__H_1_2_720p(String mimeType1,
402                 String mimeType2, int resolution) {
403             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
404                     .setId(RequirementConstants.CONCURRENT_FPS)
405                     .setPredicate(RequirementConstants.DOUBLE_GTE)
406                     .addRequiredValue(Build.VERSION_CODES.R,
407                             getReqMinConcurrentFps(
408                                     Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
409                     .addRequiredValue(Build.VERSION_CODES.S,
410                             getReqMinConcurrentFps(
411                                     Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
412                     .build();
413 
414             return create720p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
415         }
416 
417         /**
418          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
419          * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
420          * resolution@30 fps.
421          */
createR5_1__H_1_2_1080p()422         public static ConcurrentCodecRequirement createR5_1__H_1_2_1080p() {
423             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
424                     .setId(RequirementConstants.CONCURRENT_FPS)
425                     .setPredicate(RequirementConstants.DOUBLE_GTE)
426                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE)
427                     .build();
428 
429             return create1080p(RequirementConstants.R5_1__H_1_2, reqConcurrentFps);
430         }
431 
432         /**
433          * [2.2.7.1/5.1/H-1-2] MUST support 6 instances of hardware video decoder sessions (AVC,
434          * HEVC, VP9, AV1 or later) in any codec combination running concurrently with 3 sessions
435          * at 1080p resolution@30 fps and 3 sessions at 4k(U) resolution@30fps.
436          */
createR5_1__H_1_2_4k()437         public static ConcurrentCodecRequirement createR5_1__H_1_2_4k() {
438             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
439                     .setId(RequirementConstants.CONCURRENT_FPS)
440                     .setPredicate(RequirementConstants.DOUBLE_GTE)
441                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6 * FPS_30_TOLERANCE)
442                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 6 * FPS_30_TOLERANCE)
443                     .build();
444             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
445             // 1 frame dropped per second.
446             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
447                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
448                     .setPredicate(RequirementConstants.DOUBLE_LTE)
449                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
450                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
451                     .build();
452 
453             return create4k(RequirementConstants.R5_1__H_1_2, reqConcurrentFps, frameDropsPerSec);
454         }
455 
456         /**
457          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
458          * sessions that can be run concurrently in any codec combination via the
459          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
460          * .getSupportedPerformancePoints() methods.
461          */
createR5_1__H_1_3_720p(String mimeType1, String mimeType2, int resolution)462         public static ConcurrentCodecRequirement createR5_1__H_1_3_720p(String mimeType1,
463                 String mimeType2, int resolution) {
464             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
465                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
466                     .setPredicate(RequirementConstants.INTEGER_GTE)
467                     .addRequiredValue(Build.VERSION_CODES.R,
468                             getReqMinConcurrentInstances(
469                                     Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
470                     .addRequiredValue(Build.VERSION_CODES.S,
471                             getReqMinConcurrentInstances(
472                                     Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
473                     .build();
474 
475             return create720p(RequirementConstants.R5_1__H_1_3, maxInstances);
476         }
477 
478         /**
479          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
480          * sessions that can be run concurrently in any codec combination via the
481          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
482          * .getSupportedPerformancePoints() methods.
483          */
createR5_1__H_1_3_1080p()484         public static ConcurrentCodecRequirement createR5_1__H_1_3_1080p() {
485             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
486                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
487                     .setPredicate(RequirementConstants.INTEGER_GTE)
488                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
489                     .build();
490 
491             return create1080p(RequirementConstants.R5_1__H_1_3, maxInstances);
492         }
493 
494         /**
495          * [2.2.7.1/5.1/H-1-3] MUST advertise the maximum number of hardware video encoder
496          * sessions that can be run concurrently in any codec combination via the
497          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
498          * .getSupportedPerformancePoints() methods.
499          */
createR5_1__H_1_3_4K()500         public static ConcurrentCodecRequirement createR5_1__H_1_3_4K() {
501             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
502                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
503                     .setPredicate(RequirementConstants.INTEGER_GTE)
504                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
505                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 6)
506                     .build();
507 
508             return create4k(RequirementConstants.R5_1__H_1_3, maxInstances);
509         }
510 
511         /**
512          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
513          * HEVC, VP9* or later) in any codec combination running concurrently at 720p(R,S)
514          * resolution@30 fps.
515          */
createR5_1__H_1_4_720p()516         public static ConcurrentCodecRequirement createR5_1__H_1_4_720p() {
517             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
518                     .setId(RequirementConstants.CONCURRENT_FPS)
519                     .setPredicate(RequirementConstants.DOUBLE_GTE)
520                     // Requirement not asserted since encoder test runs in byte buffer mode
521                     .addRequiredValue(Build.VERSION_CODES.R, 0.0)
522                     .addRequiredValue(Build.VERSION_CODES.S, 0.0)
523                     .build();
524 
525             return create720p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
526         }
527 
528         /**
529          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
530          * HEVC, VP9* or later) in any codec combination running concurrently at 1080p(T)
531          * resolution@30 fps.
532          */
createR5_1__H_1_4_1080p()533         public static ConcurrentCodecRequirement createR5_1__H_1_4_1080p() {
534             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
535                     .setId(RequirementConstants.CONCURRENT_FPS)
536                     .setPredicate(RequirementConstants.DOUBLE_GTE)
537                     // Requirement not asserted since encoder test runs in byte buffer mode
538                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 0.0)
539                     .build();
540 
541             return create1080p(RequirementConstants.R5_1__H_1_4, reqConcurrentFps);
542         }
543 
544         /**
545          * [2.2.7.1/5.1/H-1-4] MUST support 6 instances of hardware video encoder sessions (AVC,
546          * HEVC, VP9* or later) in any codec combination running concurrently at 4k(U)
547          * resolution@30 fps.
548          */
createR5_1__H_1_4_4k()549         public static ConcurrentCodecRequirement createR5_1__H_1_4_4k() {
550             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
551                     .setId(RequirementConstants.CONCURRENT_FPS)
552                     .setPredicate(RequirementConstants.DOUBLE_GTE)
553                     // Requirement not asserted since encoder test runs in byte buffer mode
554                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 0.0)
555                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 0.0)
556                     .build();
557             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
558             // 1 frame dropped per second.
559             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
560                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
561                     .setPredicate(RequirementConstants.DOUBLE_LTE)
562                     // MUST NOT drop more than 1 frame per second
563                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
564                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
565                     .build();
566 
567             return create4k(RequirementConstants.R5_1__H_1_4, reqConcurrentFps, frameDropsPerSec);
568         }
569 
570         /**
571          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
572          * decoder sessions that can be run concurrently in any codec combination via the
573          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
574          * .getSupportedPerformancePoints() methods.
575          */
createR5_1__H_1_5_720p(String mimeType1, String mimeType2, int resolution)576         public static ConcurrentCodecRequirement createR5_1__H_1_5_720p(String mimeType1,
577                 String mimeType2, int resolution) {
578             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
579                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
580                     .setPredicate(RequirementConstants.INTEGER_GTE)
581                     .addRequiredValue(Build.VERSION_CODES.R,
582                             getReqMinConcurrentInstances(
583                                     Build.VERSION_CODES.R, mimeType1, mimeType2, resolution))
584                     .addRequiredValue(Build.VERSION_CODES.S,
585                             getReqMinConcurrentInstances(
586                                     Build.VERSION_CODES.S, mimeType1, mimeType2, resolution))
587                     .build();
588 
589             return create720p(RequirementConstants.R5_1__H_1_5, maxInstances);
590         }
591 
592         /**
593          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
594          * decoder sessions that can be run concurrently in any codec combination via the
595          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
596          * .getSupportedPerformancePoints() methods.
597          */
createR5_1__H_1_5_1080p()598         public static ConcurrentCodecRequirement createR5_1__H_1_5_1080p() {
599             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
600                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
601                     .setPredicate(RequirementConstants.INTEGER_GTE)
602                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6)
603                     .build();
604 
605             return create1080p(RequirementConstants.R5_1__H_1_5, maxInstances);
606         }
607 
608         /**
609          * [2.2.7.1/5.1/H-1-5] MUST advertise the maximum number of hardware video encoder and
610          * decoder sessions that can be run concurrently in any codec combination via the
611          * CodecCapabilities.getMaxSupportedInstances() and VideoCapabilities
612          * .getSupportedPerformancePoints() methods.
613          */
createR5_1__H_1_5_4k()614         public static ConcurrentCodecRequirement createR5_1__H_1_5_4k() {
615             RequiredMeasurement<Integer> maxInstances = RequiredMeasurement.<Integer>builder()
616                     .setId(RequirementConstants.CONCURRENT_SESSIONS)
617                     .setPredicate(RequirementConstants.INTEGER_GTE)
618                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 6)
619                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 6)
620                     .build();
621 
622             return create4k(RequirementConstants.R5_1__H_1_5, maxInstances);
623         }
624 
625         /**
626          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
627          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
628          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
629          */
createR5_1__H_1_6_720p(String mimeType1, String mimeType2, int resolution)630         public static ConcurrentCodecRequirement createR5_1__H_1_6_720p(String mimeType1,
631                 String mimeType2, int resolution) {
632             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
633                     .setId(RequirementConstants.CONCURRENT_FPS)
634                     .setPredicate(RequirementConstants.DOUBLE_GTE)
635                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
636                     .addRequiredValue(Build.VERSION_CODES.R,
637                             getReqMinConcurrentFps(
638                                     Build.VERSION_CODES.R, mimeType1, mimeType2, resolution)
639                                     / 2)
640                     .addRequiredValue(Build.VERSION_CODES.S,
641                             getReqMinConcurrentFps(
642                                     Build.VERSION_CODES.S, mimeType1, mimeType2, resolution)
643                                     / 2)
644                     .build();
645 
646             return create720p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
647         }
648 
649         /**
650          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
651          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
652          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
653          */
createR5_1__H_1_6_1080p()654         public static ConcurrentCodecRequirement createR5_1__H_1_6_1080p() {
655             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
656                     .setId(RequirementConstants.CONCURRENT_FPS)
657                     .setPredicate(RequirementConstants.DOUBLE_GTE)
658                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
659                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 6 * FPS_30_TOLERANCE / 2)
660                     .build();
661 
662             return create1080p(RequirementConstants.R5_1__H_1_6, reqConcurrentFps);
663         }
664 
665         /**
666          * [2.2.7.1/5.1/H-1-6] Support 6 instances of hardware video decoder and hardware video
667          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
668          * at 720p(R,S) /1080p(T) /4k(U) @30fps resolution.
669          */
createR5_1__H_1_6_4k()670         public static ConcurrentCodecRequirement createR5_1__H_1_6_4k() {
671             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
672                     .setId(RequirementConstants.CONCURRENT_FPS)
673                     .setPredicate(RequirementConstants.DOUBLE_GTE)
674                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
675                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
676                             6 * FPS_30_TOLERANCE / 2)
677                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM,
678                             6 * FPS_30_TOLERANCE / 2)
679                     .build();
680             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
681             // 1 frame dropped per second.
682             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
683                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
684                     .setPredicate(RequirementConstants.DOUBLE_LTE)
685                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
686                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
687                     .build();
688 
689             return create4k(RequirementConstants.R5_1__H_1_6, reqConcurrentFps, frameDropsPerSec);
690         }
691 
692         /**
693          * [2.2.7.1/5.1/H-1-9] Support 2 instances of secure hardware video decoder sessions
694          * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
695          * resolution@30fps.
696          */
createR5_1__H_1_9_1080p()697         public static ConcurrentCodecRequirement createR5_1__H_1_9_1080p() {
698             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
699                     .setId(RequirementConstants.CONCURRENT_FPS)
700                     .setPredicate(RequirementConstants.DOUBLE_GTE)
701                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 2 * FPS_30_TOLERANCE)
702                     .build();
703 
704             return create1080p(RequirementConstants.R5_1__H_1_9, reqConcurrentFps);
705         }
706 
707         /**
708          * [2.2.7.1/5.1/H-1-9] Support 2 instances of secure hardware video decoder sessions
709          * (AVC, HEVC, VP9, AV1 or later) in any codec combination running concurrently at 4k
710          * resolution@30 fps.
711          */
createR5_1__H_1_9_4k()712         public static ConcurrentCodecRequirement createR5_1__H_1_9_4k() {
713             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
714                     .setId(RequirementConstants.CONCURRENT_FPS)
715                     .setPredicate(RequirementConstants.DOUBLE_GTE)
716                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2 * FPS_30_TOLERANCE)
717                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 2 * FPS_30_TOLERANCE)
718                     .build();
719             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
720             // 1 frame dropped per second.
721             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
722                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
723                     .setPredicate(RequirementConstants.DOUBLE_LTE)
724                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
725                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
726                     .build();
727 
728             return create4k(RequirementConstants.R5_1__H_1_9, reqConcurrentFps, frameDropsPerSec);
729         }
730 
731         /**
732          * [2.2.7.1/5.1/H-1-10] Support 3 instances of non-secure hardware video decoder sessions
733          * together with 1 instance of secure hardware video decoder session (4 instances total)
734          * (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently at 1080p
735          * resolution@30fps.
736          */
createR5_1__H_1_10_1080p()737         public static ConcurrentCodecRequirement createR5_1__H_1_10_1080p() {
738             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
739                     .setId(RequirementConstants.CONCURRENT_FPS)
740                     .setPredicate(RequirementConstants.DOUBLE_GTE)
741                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 4 * FPS_30_TOLERANCE)
742                     .build();
743 
744             return create1080p(RequirementConstants.R5_1__H_1_10, reqConcurrentFps);
745         }
746 
747         /**
748          * [2.2.7.1/5.1/H-1-10] Support 3 instances of non-secure hardware video decoder sessions
749          * together with 1 instance of secure hardware video decoder session (4 instances total)
750          * (AVC, HEVC, VP9, AV1 or later) in any codec combination running concurrently with 3
751          * sessions at 4K resolution@30 fps which includes one secure decoder session and 1
752          * session at 1080p resolution@30fps.
753          */
createR5_1__H_1_10_4k()754         public static ConcurrentCodecRequirement createR5_1__H_1_10_4k() {
755             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
756                     .setId(RequirementConstants.CONCURRENT_FPS)
757                     .setPredicate(RequirementConstants.DOUBLE_GTE)
758                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 4 * FPS_30_TOLERANCE)
759                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 4 * FPS_30_TOLERANCE)
760                     .build();
761             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
762             // 1 frame dropped per second.
763             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
764                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
765                     .setPredicate(RequirementConstants.DOUBLE_LTE)
766                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
767                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
768                     .build();
769 
770             return create4k(RequirementConstants.R5_1__H_1_10, reqConcurrentFps, frameDropsPerSec);
771         }
772 
773         /**
774          * [2.2.7.1/5.1/H-1-19] Support 3 instances of hardware video decoder and hardware video
775          * encoder sessions (AVC, HEVC, VP9 or AV1) in any codec combination running concurrently
776          * at 4k(U) @30fps resolution for 10-bit with at most one encoder session.
777          */
createR5_1__H_1_19()778         public static ConcurrentCodecRequirement createR5_1__H_1_19() {
779             RequiredMeasurement<Double> reqConcurrentFps = RequiredMeasurement.<Double>builder()
780                     .setId(RequirementConstants.CONCURRENT_FPS)
781                     .setPredicate(RequirementConstants.DOUBLE_GTE)
782                     // Test transcoding, fps calculated for encoder and decoder combined so req / 2
783                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE,
784                             3 * FPS_30_TOLERANCE / 2)
785                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM,
786                             3 * FPS_30_TOLERANCE / 2)
787                     .build();
788             // Additionally for Performance Class V: For all sessions, there MUST NOT be more than
789             // 1 frame dropped per second.
790             RequiredMeasurement<Double> frameDropsPerSec = RequiredMeasurement.<Double>builder()
791                     .setId(RequirementConstants.FRAMES_DROPPED_PER_SECOND)
792                     .setPredicate(RequirementConstants.DOUBLE_LTE)
793                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, Double.MAX_VALUE)
794                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1.0)
795                     .build();
796 
797             return create4k(RequirementConstants.R5_1__H_1_19, reqConcurrentFps, frameDropsPerSec);
798         }
799     }
800 
801     // used for requirements [7.1.1.3/H-1-1], [7.1.1.3/H-2-1]
802     public static class DensityRequirement extends Requirement {
803         private static final String TAG = DensityRequirement.class.getSimpleName();
804 
DensityRequirement(String id, RequiredMeasurement<?>... reqs)805         private DensityRequirement(String id, RequiredMeasurement<?>... reqs) {
806             super(id, reqs);
807         }
808 
setDisplayDensity(int displayDensity)809         public void setDisplayDensity(int displayDensity) {
810             this.<Integer>setMeasuredValue(RequirementConstants.DISPLAY_DENSITY, displayDensity);
811         }
812 
813         /**
814          * [7.1.1.3/H-1-1] MUST have screen density of at least 400 dpi.
815          */
createR7_1_1_3__H_1_1()816         public static DensityRequirement createR7_1_1_3__H_1_1() {
817             RequiredMeasurement<Integer> display_density = RequiredMeasurement
818                     .<Integer>builder()
819                     .setId(RequirementConstants.DISPLAY_DENSITY)
820                     .setPredicate(RequirementConstants.INTEGER_GTE)
821                     .addRequiredValue(Build.VERSION_CODES.R, 400)
822                     .build();
823 
824             return new DensityRequirement(RequirementConstants.R7_1_1_3__H_1_1, display_density);
825         }
826 
827         /**
828          * [7.1.1.3/H-2-1] MUST have screen density of at least 400 dpi.
829          */
createR7_1_1_3__H_2_1()830         public static DensityRequirement createR7_1_1_3__H_2_1() {
831             RequiredMeasurement<Integer> display_density = RequiredMeasurement
832                     .<Integer>builder()
833                     .setId(RequirementConstants.DISPLAY_DENSITY)
834                     .setPredicate(RequirementConstants.INTEGER_GTE)
835                     .addRequiredValue(Build.VERSION_CODES.S, 400)
836                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 400)
837                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 400)
838                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 400)
839                     .build();
840 
841             return new DensityRequirement(RequirementConstants.R7_1_1_3__H_2_1, display_density);
842         }
843     }
844 
845     public static class ExtYuvTargetRequirement extends Requirement {
846         private static final String TAG = ExtYuvTargetRequirement.class.getSimpleName();
847 
ExtYuvTargetRequirement(String id, RequiredMeasurement<?>... reqs)848         private ExtYuvTargetRequirement(String id, RequiredMeasurement<?>... reqs) {
849             super(id, reqs);
850         }
851 
setExtYuvTargetSupport(boolean extensionSupported)852         public void setExtYuvTargetSupport(boolean extensionSupported) {
853             this.setMeasuredValue(RequirementConstants.EXT_YUV_EXTENSION, extensionSupported);
854         }
855 
856         /**
857          * [5.12/H-1-3] MUST checks for EXT_YUV_target extension support.
858          */
createExtensionReq()859         public static ExtYuvTargetRequirement createExtensionReq() {
860             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
861                     .<Boolean>builder()
862                     .setId(RequirementConstants.EXT_YUV_EXTENSION)
863                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
864                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
865                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
866                     .build();
867 
868             return new ExtYuvTargetRequirement(RequirementConstants.R5_12__H_1_3, requirement);
869         }
870     }
871 
872     // used for requirements [8.2/H-1-1], [8.2/H-1-2], [8.2/H-1-3], [8.2/H-1-4]
873     public static class FileSystemRequirement extends Requirement {
874 
875         private static final String TAG = FileSystemRequirement.class.getSimpleName();
876 
FileSystemRequirement(String id, RequiredMeasurement<?>... reqs)877         private FileSystemRequirement(String id, RequiredMeasurement<?>... reqs) {
878             super(id, reqs);
879         }
880 
881         /**
882          * Set the Filesystem I/O Rate in MB/s.
883          */
setFilesystemIoRate(double filesystemIoRate)884         public void setFilesystemIoRate(double filesystemIoRate) {
885             this.setMeasuredValue(RequirementConstants.FILESYSTEM_IO_RATE, filesystemIoRate);
886         }
887 
888         /**
889          * [8.2/H-1-1] MUST ensure a sequential write performance of at least 100(R) / 125(S &
890          * above) MB/s.
891          */
createR8_2__H_1_1()892         public static FileSystemRequirement createR8_2__H_1_1() {
893             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
894                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
895                     .setPredicate(RequirementConstants.DOUBLE_GTE)
896                     .addRequiredValue(Build.VERSION_CODES.R, 100.0)
897                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 125.0)
898                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 150.0)
899                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 150.0)
900                     .build();
901 
902             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_1, filesystem_io_rate);
903         }
904 
905         /**
906          * [8.2/H-2-1] MUST ensure a sequential write performance of at least 125 MB/s.
907          */
createR8_2__H_2_1()908         public static FileSystemRequirement createR8_2__H_2_1() {
909             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
910                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
911                     .setPredicate(RequirementConstants.DOUBLE_GTE)
912                     .addRequiredValue(Build.VERSION_CODES.S, 125.0)
913                     .build();
914 
915             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_1, filesystem_io_rate);
916         }
917 
918         /**
919          * [8.2/H-1-2] MUST ensure a random write performance of at least 10 MB/s
920          */
createR8_2__H_1_2()921         public static FileSystemRequirement createR8_2__H_1_2() {
922             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
923                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
924                     .setPredicate(RequirementConstants.DOUBLE_GTE)
925                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 10.0)
926                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 10.0)
927                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 10.0)
928                     .build();
929 
930             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_2, filesystem_io_rate);
931         }
932 
933         /**
934          * [8.2/H-2-2] MUST ensure a random write performance of at least 10 MB/s.
935          */
createR8_2__H_2_2()936         public static FileSystemRequirement createR8_2__H_2_2() {
937             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
938                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
939                     .setPredicate(RequirementConstants.DOUBLE_GTE)
940                     .addRequiredValue(Build.VERSION_CODES.S, 10.0)
941                     .build();
942 
943             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_2, filesystem_io_rate);
944         }
945 
946         /**
947          * [8.2/H-1-3] MUST ensure a sequential read performance of at least 200(R) / 250(S &
948          * above) MB/s.
949          */
createR8_2__H_1_3()950         public static FileSystemRequirement createR8_2__H_1_3() {
951             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
952                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
953                     .setPredicate(RequirementConstants.DOUBLE_GTE)
954                     .addRequiredValue(Build.VERSION_CODES.R, 200.0)
955                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 250.0)
956                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 250.0)
957                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 250.0)
958                     .build();
959 
960             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_3, filesystem_io_rate);
961         }
962 
963         /**
964          * [8.2/H-2-3] MUST ensure a sequential read performance of at least 250 MB/s.
965          */
createR8_2__H_2_3()966         public static FileSystemRequirement createR8_2__H_2_3() {
967             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
968                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
969                     .setPredicate(RequirementConstants.DOUBLE_GTE)
970                     .addRequiredValue(Build.VERSION_CODES.S, 250.0)
971                     .build();
972 
973             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_3, filesystem_io_rate);
974         }
975 
976         /**
977          * [8.2/H-1-4] MUST ensure a random read performance of at least 25(R) / 40(S & above) MB/s.
978          */
createR8_2__H_1_4()979         public static FileSystemRequirement createR8_2__H_1_4() {
980             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
981                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
982                     .setPredicate(RequirementConstants.DOUBLE_GTE)
983                     .addRequiredValue(Build.VERSION_CODES.R, 25.0)
984                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 40.0)
985                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 100.0)
986                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 100.0)
987                     .build();
988 
989             return new FileSystemRequirement(RequirementConstants.R8_2__H_1_4, filesystem_io_rate);
990         }
991 
992         /**
993          * [8.2/H-2-4] MUST ensure a random read performance of at least 40 MB/s.
994          */
createR8_2__H_2_4()995         public static FileSystemRequirement createR8_2__H_2_4() {
996             RequiredMeasurement<Double> filesystem_io_rate = RequiredMeasurement
997                     .<Double>builder().setId(RequirementConstants.FILESYSTEM_IO_RATE)
998                     .setPredicate(RequirementConstants.DOUBLE_GTE)
999                     .addRequiredValue(Build.VERSION_CODES.S, 40.0)
1000                     .build();
1001 
1002             return new FileSystemRequirement(RequirementConstants.R8_2__H_2_4, filesystem_io_rate);
1003         }
1004     }
1005 
1006     // used for requirements [2.2.7.1/5.3/H-1-1], [2.2.7.1/5.3/H-1-2]
1007     public static class FrameDropRequirement extends Requirement {
1008         private static final String TAG = FrameDropRequirement.class.getSimpleName();
1009 
FrameDropRequirement(String id, RequiredMeasurement<?>... reqs)1010         private FrameDropRequirement(String id, RequiredMeasurement<?>... reqs) {
1011             super(id, reqs);
1012         }
1013 
setFramesDropped(int framesDropped)1014         public void setFramesDropped(int framesDropped) {
1015             this.setMeasuredValue(RequirementConstants.FRAMES_DROPPED, framesDropped);
1016         }
1017 
setFrameRate(double frameRate)1018         public void setFrameRate(double frameRate) {
1019             this.setMeasuredValue(RequirementConstants.FRAME_RATE, frameRate);
1020         }
1021 
setTestResolution(int res)1022         public void setTestResolution(int res) {
1023             this.setMeasuredValue(RequirementConstants.TEST_RESOLUTION, res);
1024         }
1025 
1026         /**
1027          * [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
1028          * percent frame drop) for a 1080p 30 fps video session under load. Load is defined as a
1029          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1030          * as well as a 128 kbps AAC audio playback.
1031          */
createR5_3__H_1_1_R()1032         public static FrameDropRequirement createR5_3__H_1_1_R() {
1033             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1034                     .<Integer>builder()
1035                     .setId(RequirementConstants.FRAMES_DROPPED)
1036                     .setPredicate(RequirementConstants.INTEGER_LTE)
1037                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1038                     .addRequiredValue(Build.VERSION_CODES.R, 3)
1039                     .build();
1040 
1041             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1042                     .<Double>builder()
1043                     .setId(RequirementConstants.FRAME_RATE)
1044                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1045                     .addRequiredValue(Build.VERSION_CODES.R, 30.0)
1046                     .build();
1047 
1048             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1049                     .setId(RequirementConstants.TEST_RESOLUTION)
1050                     .setPredicate(RequirementConstants.INTEGER_EQ)
1051                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1052                     .build();
1053 
1054             return new FrameDropRequirement(
1055                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1056         }
1057 
1058         /**
1059          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 1 frame in 10 seconds during a video
1060          * resolution change in a 30 fps video session under load. Load is defined as a
1061          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1062          * as well as a 128Kbps AAC audio playback.
1063          */
createR5_3__H_1_2_R()1064         public static FrameDropRequirement createR5_3__H_1_2_R() {
1065             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1066                     .<Integer>builder()
1067                     .setId(RequirementConstants.FRAMES_DROPPED)
1068                     .setPredicate(RequirementConstants.INTEGER_LTE)
1069                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1070                     .addRequiredValue(Build.VERSION_CODES.R, 3)
1071                     .build();
1072 
1073             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1074                     .<Double>builder()
1075                     .setId(RequirementConstants.FRAME_RATE)
1076                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1077                     .addRequiredValue(Build.VERSION_CODES.R, 30.0)
1078                     .build();
1079 
1080             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1081                     .setId(RequirementConstants.TEST_RESOLUTION)
1082                     .setPredicate(RequirementConstants.INTEGER_EQ)
1083                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1084                     .build();
1085 
1086             return new FrameDropRequirement(
1087                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1088         }
1089 
1090         /**
1091          * [2.2.7.1/5.3/H-1-1] MUST NOT drop more than 2(S) / 1(T) frames in 10 seconds for a
1092          * 1080p 60 fps video session under load. Load is defined as a concurrent 1080p to 720p
1093          * video-only transcoding session using hardware video codecs, as well as a 128 kbps AAC
1094          * audio playback.
1095          */
createR5_3__H_1_1_ST()1096         public static FrameDropRequirement createR5_3__H_1_1_ST() {
1097             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1098                     .<Integer>builder()
1099                     .setId(RequirementConstants.FRAMES_DROPPED)
1100                     .setPredicate(RequirementConstants.INTEGER_LTE)
1101                     // MUST NOT drop more than 2 frame in 10 seconds so 6 frames for 30 seconds
1102                     .addRequiredValue(Build.VERSION_CODES.S, 6)
1103                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1104                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 3)
1105                     .build();
1106 
1107             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1108                     .<Double>builder()
1109                     .setId(RequirementConstants.FRAME_RATE)
1110                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1111                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 60.0)
1112                     .build();
1113 
1114             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1115                     .setId(RequirementConstants.TEST_RESOLUTION)
1116                     .setPredicate(RequirementConstants.INTEGER_EQ)
1117                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1118                     .build();
1119 
1120             return new FrameDropRequirement(
1121                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1122         }
1123 
1124         /**
1125          * [2.2.7.1/5.3/H-1-1] MUST NOT drop more than 1 frame in 10 seconds for a
1126          * 4k 60 fps video session under load. Load is defined as a concurrent 1080p to 720p
1127          * video-only transcoding session using hardware video codecs, as well as a 128 kbps AAC
1128          * audio playback.
1129          */
createR5_3__H_1_1_U()1130         public static FrameDropRequirement createR5_3__H_1_1_U() {
1131             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1132                     .<Integer>builder()
1133                     .setId(RequirementConstants.FRAMES_DROPPED)
1134                     .setPredicate(RequirementConstants.INTEGER_LTE)
1135                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1136                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 3)
1137                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 3)
1138                     .build();
1139 
1140             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1141                     .<Double>builder()
1142                     .setId(RequirementConstants.FRAME_RATE)
1143                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1144                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 60.0)
1145                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 60.0)
1146                     .build();
1147 
1148             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1149                     .setId(RequirementConstants.TEST_RESOLUTION)
1150                     .setPredicate(RequirementConstants.INTEGER_EQ)
1151                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
1152                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 2160)
1153                     .build();
1154 
1155             return new FrameDropRequirement(
1156                     RequirementConstants.R5_3__H_1_1, frameDropped, frameRate, testResolution);
1157         }
1158 
1159         /**
1160          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 2(S) / 1(T) frames in 10 seconds during a
1161          * video resolution change in a 60 fps video session under load. Load is defined as a
1162          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1163          * as well as a 128Kbps AAC audio playback.
1164          */
createR5_3__H_1_2_ST()1165         public static FrameDropRequirement createR5_3__H_1_2_ST() {
1166             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1167                     .<Integer>builder()
1168                     .setId(RequirementConstants.FRAMES_DROPPED)
1169                     .setPredicate(RequirementConstants.INTEGER_LTE)
1170                     // MUST NOT drop more than 2 frame in 10 seconds so 6 frames for 30 seconds
1171                     .addRequiredValue(Build.VERSION_CODES.S, 6)
1172                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1173                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 3)
1174                     .build();
1175 
1176             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1177                     .<Double>builder()
1178                     .setId(RequirementConstants.FRAME_RATE)
1179                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1180                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 60.0)
1181                     .build();
1182 
1183             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1184                     .setId(RequirementConstants.TEST_RESOLUTION)
1185                     .setPredicate(RequirementConstants.INTEGER_EQ)
1186                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1187                     .build();
1188 
1189             return new FrameDropRequirement(
1190                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1191         }
1192 
1193         /**
1194          * [2.2.7.1/5.3/H-1-2] MUST NOT drop more than 1 frames in 10 seconds during a
1195          * video resolution change in a 4k 60 fps video session under load. Load is defined as a
1196          * concurrent 1080p to 720p video-only transcoding session using hardware video codecs,
1197          * as well as a 128Kbps AAC audio playback.
1198          */
createR5_3__H_1_2_U()1199         public static FrameDropRequirement createR5_3__H_1_2_U() {
1200             RequiredMeasurement<Integer> frameDropped = RequiredMeasurement
1201                     .<Integer>builder()
1202                     .setId(RequirementConstants.FRAMES_DROPPED)
1203                     .setPredicate(RequirementConstants.INTEGER_LTE)
1204                     // MUST NOT drop more than 1 frame in 10 seconds so 3 frames for 30 seconds
1205                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 3)
1206                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 3)
1207                     .build();
1208 
1209             RequiredMeasurement<Double> frameRate = RequiredMeasurement
1210                     .<Double>builder()
1211                     .setId(RequirementConstants.FRAME_RATE)
1212                     .setPredicate(RequirementConstants.DOUBLE_EQ)
1213                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 60.0)
1214                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 60.0)
1215                     .build();
1216 
1217             RequiredMeasurement<Integer> testResolution = RequiredMeasurement.<Integer>builder()
1218                     .setId(RequirementConstants.TEST_RESOLUTION)
1219                     .setPredicate(RequirementConstants.INTEGER_EQ)
1220                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 2160)
1221                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 2160)
1222                     .build();
1223 
1224             return new FrameDropRequirement(
1225                     RequirementConstants.R5_3__H_1_2, frameDropped, frameRate, testResolution);
1226         }
1227     }
1228 
1229     // used for requirements [7.1.1.1/H-1-1], [7.1.1.1/H-2-1]
1230     public static class ResolutionRequirement extends Requirement {
1231         private static final String TAG = ResolutionRequirement.class.getSimpleName();
1232 
ResolutionRequirement(String id, RequiredMeasurement<?>... reqs)1233         private ResolutionRequirement(String id, RequiredMeasurement<?>... reqs) {
1234             super(id, reqs);
1235         }
1236 
setLongResolution(int longResolution)1237         public void setLongResolution(int longResolution) {
1238             this.<Integer>setMeasuredValue(RequirementConstants.LONG_RESOLUTION, longResolution);
1239         }
1240 
setShortResolution(int shortResolution)1241         public void setShortResolution(int shortResolution) {
1242             this.<Integer>setMeasuredValue(RequirementConstants.SHORT_RESOLUTION, shortResolution);
1243         }
1244 
1245         /**
1246          * [7.1.1.1/H-1-1] MUST have screen resolution of at least 1080p.
1247          */
createR7_1_1_1__H_1_1()1248         public static ResolutionRequirement createR7_1_1_1__H_1_1() {
1249             RequiredMeasurement<Integer> long_resolution = RequiredMeasurement
1250                     .<Integer>builder()
1251                     .setId(RequirementConstants.LONG_RESOLUTION)
1252                     .setPredicate(RequirementConstants.INTEGER_GTE)
1253                     .addRequiredValue(Build.VERSION_CODES.R, 1920)
1254                     .build();
1255             RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
1256                     .<Integer>builder()
1257                     .setId(RequirementConstants.SHORT_RESOLUTION)
1258                     .setPredicate(RequirementConstants.INTEGER_GTE)
1259                     .addRequiredValue(Build.VERSION_CODES.R, 1080)
1260                     .build();
1261 
1262             return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_1_1, long_resolution,
1263                     short_resolution);
1264         }
1265 
1266         /**
1267          * [7.1.1.1/H-2-1] MUST have screen resolution of at least 1080p.
1268          */
createR7_1_1_1__H_2_1()1269         public static ResolutionRequirement createR7_1_1_1__H_2_1() {
1270             RequiredMeasurement<Integer> long_resolution = RequiredMeasurement
1271                     .<Integer>builder()
1272                     .setId(RequirementConstants.LONG_RESOLUTION)
1273                     .setPredicate(RequirementConstants.INTEGER_GTE)
1274                     .addRequiredValue(Build.VERSION_CODES.S, 1920)
1275                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1920)
1276                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1920)
1277                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1920)
1278                     .build();
1279             RequiredMeasurement<Integer> short_resolution = RequiredMeasurement
1280                     .<Integer>builder()
1281                     .setId(RequirementConstants.SHORT_RESOLUTION)
1282                     .setPredicate(RequirementConstants.INTEGER_GTE)
1283                     .addRequiredValue(Build.VERSION_CODES.S, 1080)
1284                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1080)
1285                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1080)
1286                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1080)
1287                     .build();
1288 
1289             return new ResolutionRequirement(RequirementConstants.R7_1_1_1__H_2_1, long_resolution,
1290                     short_resolution);
1291         }
1292     }
1293 
1294     // used for requirements [2.2.7.1/5.1/H-1-11], [2.2.7.1/5.7/H-1-2]
1295     public static class SecureCodecRequirement extends Requirement {
1296         private static final String TAG = SecureCodecRequirement.class.getSimpleName();
1297 
SecureCodecRequirement(String id, RequiredMeasurement<?>... reqs)1298         private SecureCodecRequirement(String id, RequiredMeasurement<?>... reqs) {
1299             super(id, reqs);
1300         }
1301 
setSecureReqSatisfied(boolean secureReqSatisfied)1302         public void setSecureReqSatisfied(boolean secureReqSatisfied) {
1303             this.setMeasuredValue(RequirementConstants.SECURE_REQ_SATISFIED, secureReqSatisfied);
1304         }
1305 
setNumCryptoHwSecureAllDec(int numCryptoHwSecureAllDec)1306         public void setNumCryptoHwSecureAllDec(int numCryptoHwSecureAllDec) {
1307             this.setMeasuredValue(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT,
1308                     numCryptoHwSecureAllDec);
1309         }
1310 
1311         /**
1312          * [2.2.7.1/5.7/H-1-2] MUST support MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL with the below
1313          * content decryption capabilities.
1314          */
createR5_7__H_1_2()1315         public static SecureCodecRequirement createR5_7__H_1_2() {
1316             RequiredMeasurement<Integer> hw_secure_all = RequiredMeasurement.<Integer>builder()
1317                     .setId(RequirementConstants.NUM_CRYPTO_HW_SECURE_ALL_SUPPORT)
1318                     .setPredicate(RequirementConstants.INTEGER_GTE)
1319                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1320                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1321                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1)
1322                     .build();
1323 
1324             return new SecureCodecRequirement(RequirementConstants.R5_7__H_1_2, hw_secure_all);
1325         }
1326 
1327         /**
1328          * [2.2.7.1/5.1/H-1-11] Must support secure decoder when a corresponding AVC/VP9/HEVC or AV1
1329          * hardware decoder is available
1330          */
createR5_1__H_1_11()1331         public static SecureCodecRequirement createR5_1__H_1_11() {
1332             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1333                     .<Boolean>builder()
1334                     .setId(RequirementConstants.SECURE_REQ_SATISFIED)
1335                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1336                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1337                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1338                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1339                     .build();
1340 
1341             return new SecureCodecRequirement(RequirementConstants.R5_1__H_1_11, requirement);
1342         }
1343     }
1344 
1345     public static class VideoCodecRequirement extends Requirement {
1346         private static final String TAG = VideoCodecRequirement.class.getSimpleName();
1347 
VideoCodecRequirement(String id, RequiredMeasurement<?>... reqs)1348         private VideoCodecRequirement(String id, RequiredMeasurement<?>... reqs) {
1349             super(id, reqs);
1350         }
1351 
setAv1DecoderReq(boolean av1DecoderReqSatisfied)1352         public void setAv1DecoderReq(boolean av1DecoderReqSatisfied) {
1353             this.setMeasuredValue(RequirementConstants.AV1_DEC_REQ, av1DecoderReqSatisfied);
1354         }
1355 
set4kHwDecoders(int num4kHwDecoders)1356         public void set4kHwDecoders(int num4kHwDecoders) {
1357             this.setMeasuredValue(RequirementConstants.NUM_4k_HW_DEC, num4kHwDecoders);
1358         }
1359 
set4kHwEncoders(int num4kHwEncoders)1360         public void set4kHwEncoders(int num4kHwEncoders) {
1361             this.setMeasuredValue(RequirementConstants.NUM_4k_HW_ENC, num4kHwEncoders);
1362         }
1363 
setAVIFDecoderReq(boolean avifDecoderReqSatisfied)1364         public void setAVIFDecoderReq(boolean avifDecoderReqSatisfied) {
1365             this.setMeasuredValue(RequirementConstants.AVIF_DEC_REQ, avifDecoderReqSatisfied);
1366         }
1367 
setAv1EncResolution(int resolution)1368         public void setAv1EncResolution(int resolution) {
1369             this.setMeasuredValue(RequirementConstants.AV1_ENC_RESOLUTION, resolution);
1370         }
1371 
setAv1EncFps(double fps)1372         public void setAv1EncFps(double fps) {
1373             this.setMeasuredValue(RequirementConstants.AV1_ENC_FPS, fps);
1374         }
1375 
setAv1EncBitrate(int bitrate)1376         public void setAv1EncBitrate(int bitrate) {
1377             this.setMeasuredValue(RequirementConstants.AV1_ENC_BITRATE, bitrate);
1378         }
1379 
setHlgEditingSupportedReq(boolean HlgEditingSupported)1380         public void setHlgEditingSupportedReq(boolean HlgEditingSupported) {
1381             this.setMeasuredValue(RequirementConstants.HLG_EDITING, HlgEditingSupported);
1382         }
1383 
setPortraitResolutionSupportreq(boolean isPortraitSupported)1384         public void setPortraitResolutionSupportreq(boolean isPortraitSupported) {
1385             this.setMeasuredValue(RequirementConstants.PORTRAIT_RESOLUTION, isPortraitSupported);
1386         }
1387 
setColorFormatSupportReq(boolean colorFormatSupported)1388         public void setColorFormatSupportReq(boolean colorFormatSupported) {
1389             this.setMeasuredValue(RequirementConstants.RGBA_1010102_COLOR_FORMAT_REQ,
1390                     colorFormatSupported);
1391         }
1392 
setDynamicColorAspectsSupportReq(boolean dynamicColorAspectsSupported)1393         public void setDynamicColorAspectsSupportReq(boolean dynamicColorAspectsSupported) {
1394             this.setMeasuredValue(RequirementConstants.DYNAMIC_COLOR_ASPECTS,
1395                     dynamicColorAspectsSupported);
1396         }
1397 
1398         /**
1399          * [2.2.7.1/5.1/H-1-15] Must have at least 1 HW video decoder supporting 4K60
1400          */
createR4k60HwDecoder()1401         public static VideoCodecRequirement createR4k60HwDecoder() {
1402             RequiredMeasurement<Integer> requirement = RequiredMeasurement
1403                     .<Integer>builder()
1404                     .setId(RequirementConstants.NUM_4k_HW_DEC)
1405                     .setPredicate(RequirementConstants.INTEGER_GTE)
1406                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1407                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1408                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1)
1409                     .build();
1410 
1411             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_15, requirement);
1412         }
1413 
1414         /**
1415          * [2.2.7.1/5.1/H-1-16] Must have at least 1 HW video encoder supporting 4K60
1416          */
createR4k60HwEncoder()1417         public static VideoCodecRequirement createR4k60HwEncoder() {
1418             RequiredMeasurement<Integer> requirement = RequiredMeasurement
1419                     .<Integer>builder()
1420                     .setId(RequirementConstants.NUM_4k_HW_ENC)
1421                     .setPredicate(RequirementConstants.INTEGER_GTE)
1422                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, 1)
1423                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1424                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1)
1425                     .build();
1426 
1427             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_16, requirement);
1428         }
1429 
1430         /**
1431          * [2.2.7.1/5.1/H-1-14] AV1 Hardware decoder: Main 10, Level 4.1, Film Grain
1432          */
createRAV1DecoderReq()1433         public static VideoCodecRequirement createRAV1DecoderReq() {
1434             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1435                     .<Boolean>builder()
1436                     .setId(RequirementConstants.AV1_DEC_REQ)
1437                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1438                     .addRequiredValue(Build.VERSION_CODES.TIRAMISU, true)
1439                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1440                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1441                     .build();
1442 
1443             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_14, requirement);
1444         }
1445 
1446         /**
1447          * [5.1/H-1-17] MUST have at least 1 Hw image decoder supporting AVIF Baseline profile.
1448          */
createRAVIFDecoderReq()1449         public static VideoCodecRequirement createRAVIFDecoderReq() {
1450             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1451                     .<Boolean>builder()
1452                     .setId(RequirementConstants.AVIF_DEC_REQ)
1453                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1454                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, true)
1455                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1456                     .build();
1457 
1458             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_17, requirement);
1459         }
1460 
1461         /**
1462          * [2.2.7.1/5.1/H-1-18] MUST support AV1 encoder which can encode up to 480p resolution
1463          * at 30fps and 1Mbps.
1464          */
createRAV1EncoderReq()1465         public static VideoCodecRequirement createRAV1EncoderReq() {
1466             RequiredMeasurement<Integer> resolution = RequiredMeasurement
1467                     .<Integer>builder()
1468                     .setId(RequirementConstants.AV1_ENC_RESOLUTION)
1469                     .setPredicate(RequirementConstants.INTEGER_GTE)
1470                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 480)
1471                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 480)
1472                     .build();
1473 
1474             RequiredMeasurement<Double> fps = RequiredMeasurement
1475                     .<Double>builder()
1476                     .setId(RequirementConstants.AV1_ENC_FPS)
1477                     .setPredicate(RequirementConstants.DOUBLE_GTE)
1478                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 30.0)
1479                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 30.0)
1480                     .build();
1481 
1482             RequiredMeasurement<Integer> bitrate = RequiredMeasurement
1483                     .<Integer>builder()
1484                     .setId(RequirementConstants.AV1_ENC_BITRATE)
1485                     .setPredicate(RequirementConstants.INTEGER_GTE)
1486                     .addRequiredValue(Build.VERSION_CODES.UPSIDE_DOWN_CAKE, 1)
1487                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, 1)
1488                     .build();
1489 
1490             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_18, resolution, fps,
1491                     bitrate);
1492         }
1493 
1494         /**
1495          * [5.1/H-1-20] MUST support the Feature_HlgEditing feature for all hardware AV1 and HEVC
1496          * encoders present on the device at 4K resolution or the largest Camera-supported
1497          * resolution, whichever is less.
1498          */
createR5_1__H_1_20()1499         public static VideoCodecRequirement createR5_1__H_1_20() {
1500             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1501                     .<Boolean>builder()
1502                     .setId(RequirementConstants.HLG_EDITING)
1503                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1504                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1505                     .build();
1506 
1507             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_20, requirement);
1508         }
1509 
1510         /**
1511          * [5.1/H-1-21] MUST support FEATURE_DynamicColorAspects for all hardware video decoders
1512          *  (AVC, HEVC, VP9, AV1 or later).
1513          */
createR5_1__H_1_21()1514         public static VideoCodecRequirement createR5_1__H_1_21() {
1515             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1516                     .<Boolean>builder()
1517                     .setId(RequirementConstants.DYNAMIC_COLOR_ASPECTS)
1518                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1519                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1520                     .build();
1521 
1522             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_21, requirement);
1523         }
1524 
1525         /**
1526          * [5.12/H-1-22] MUST support both landscape and portrait resolution for all hardware
1527          * codecs. AV1 codecs are limited to only 1080p resolution while others should support
1528          * 4k or camera preferred resolution (whichever is less)
1529          */
createR5_1__H_1_22()1530         public static VideoCodecRequirement createR5_1__H_1_22() {
1531             RequiredMeasurement<Boolean> requirement = RequiredMeasurement
1532                     .<Boolean>builder()
1533                     .setId(RequirementConstants.PORTRAIT_RESOLUTION)
1534                     .setPredicate(RequirementConstants.BOOLEAN_EQ)
1535                     .addRequiredValue(Build.VERSION_CODES.VANILLA_ICE_CREAM, true)
1536                     .build();
1537 
1538             return new VideoCodecRequirement(RequirementConstants.R5_1__H_1_22, requirement);
1539         }
1540     }
1541 
addRequirement(R req)1542     public <R extends Requirement> R addRequirement(R req) {
1543         if (!this.mRequirements.add(req)) {
1544             throw new IllegalStateException("Requirement " + req.id() + " already added");
1545         }
1546         return req;
1547     }
1548 
addR5_1__H_1_1_720p(String mimeType1, String mimeType2, int resolution)1549     public ConcurrentCodecRequirement addR5_1__H_1_1_720p(String mimeType1, String mimeType2,
1550             int resolution) {
1551         return this.addRequirement(
1552                 ConcurrentCodecRequirement.createR5_1__H_1_1_720p(mimeType1, mimeType2,
1553                         resolution));
1554     }
1555 
addR5_1__H_1_1_1080p()1556     public ConcurrentCodecRequirement addR5_1__H_1_1_1080p() {
1557         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_1_1080p());
1558     }
1559 
addR5_1__H_1_1_4k()1560     public ConcurrentCodecRequirement addR5_1__H_1_1_4k() {
1561         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_1_4k());
1562     }
1563 
addR5_1__H_1_2_720p(String mimeType1, String mimeType2, int resolution)1564     public ConcurrentCodecRequirement addR5_1__H_1_2_720p(String mimeType1, String mimeType2,
1565             int resolution) {
1566         return this.addRequirement(
1567                 ConcurrentCodecRequirement.createR5_1__H_1_2_720p(mimeType1, mimeType2,
1568                         resolution));
1569     }
1570 
addR5_1__H_1_2_1080p()1571     public ConcurrentCodecRequirement addR5_1__H_1_2_1080p() {
1572         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_2_1080p());
1573     }
1574 
addR5_1__H_1_2_4k()1575     public ConcurrentCodecRequirement addR5_1__H_1_2_4k() {
1576         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_2_4k());
1577     }
1578 
addR5_1__H_1_3_720p(String mimeType1, String mimeType2, int resolution)1579     public ConcurrentCodecRequirement addR5_1__H_1_3_720p(String mimeType1, String mimeType2,
1580             int resolution) {
1581         return this.addRequirement(
1582                 ConcurrentCodecRequirement.createR5_1__H_1_3_720p(mimeType1, mimeType2,
1583                         resolution));
1584     }
1585 
addR5_1__H_1_3_1080p()1586     public ConcurrentCodecRequirement addR5_1__H_1_3_1080p() {
1587         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_3_1080p());
1588     }
1589 
addR5_1__H_1_3_4k()1590     public ConcurrentCodecRequirement addR5_1__H_1_3_4k() {
1591         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_3_4K());
1592     }
1593 
addR5_1__H_1_4_720p()1594     public ConcurrentCodecRequirement addR5_1__H_1_4_720p() {
1595         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_720p());
1596     }
1597 
addR5_1__H_1_4_1080p()1598     public ConcurrentCodecRequirement addR5_1__H_1_4_1080p() {
1599         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_1080p());
1600     }
1601 
addR5_1__H_1_4_4k()1602     public ConcurrentCodecRequirement addR5_1__H_1_4_4k() {
1603         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_4_4k());
1604     }
1605 
addR5_1__H_1_5_720p(String mimeType1, String mimeType2, int resolution)1606     public ConcurrentCodecRequirement addR5_1__H_1_5_720p(String mimeType1, String mimeType2,
1607             int resolution) {
1608         return this.addRequirement(
1609                 ConcurrentCodecRequirement.createR5_1__H_1_5_720p(mimeType1, mimeType2,
1610                         resolution));
1611     }
1612 
addR5_1__H_1_5_1080p()1613     public ConcurrentCodecRequirement addR5_1__H_1_5_1080p() {
1614         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_5_1080p());
1615     }
1616 
addR5_1__H_1_5_4k()1617     public ConcurrentCodecRequirement addR5_1__H_1_5_4k() {
1618         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_5_4k());
1619     }
1620 
addR5_1__H_1_6_720p(String mimeType1, String mimeType2, int resolution)1621     public ConcurrentCodecRequirement addR5_1__H_1_6_720p(String mimeType1, String mimeType2,
1622             int resolution) {
1623         return this.addRequirement(
1624                 ConcurrentCodecRequirement.createR5_1__H_1_6_720p(mimeType1, mimeType2,
1625                         resolution));
1626     }
1627 
addR5_1__H_1_6_1080p()1628     public ConcurrentCodecRequirement addR5_1__H_1_6_1080p() {
1629         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_6_1080p());
1630     }
1631 
addR5_1__H_1_6_4k()1632     public ConcurrentCodecRequirement addR5_1__H_1_6_4k() {
1633         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_6_4k());
1634     }
1635 
addR5_1__H_1_9_1080p()1636     public ConcurrentCodecRequirement addR5_1__H_1_9_1080p() {
1637         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_9_1080p());
1638     }
1639 
addR5_1__H_1_9_4k()1640     public ConcurrentCodecRequirement addR5_1__H_1_9_4k() {
1641         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_9_4k());
1642     }
1643 
addR5_1__H_1_10_1080p()1644     public ConcurrentCodecRequirement addR5_1__H_1_10_1080p() {
1645         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10_1080p());
1646     }
1647 
addR5_1__H_1_10_4k()1648     public ConcurrentCodecRequirement addR5_1__H_1_10_4k() {
1649         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_10_4k());
1650     }
1651 
addR5_1__H_1_11()1652     public SecureCodecRequirement addR5_1__H_1_11() {
1653         return this.addRequirement(SecureCodecRequirement.createR5_1__H_1_11());
1654     }
1655 
addR5_1__H_1_12()1656     public CodecInitLatencyRequirement addR5_1__H_1_12() {
1657         return this.addRequirement(CodecInitLatencyRequirement.createR5_1__H_1_12());
1658     }
1659 
1660     /* Adds requirement 5.1/H-1-14 */
addRAV1DecoderReq()1661     public VideoCodecRequirement addRAV1DecoderReq() {
1662         return this.addRequirement(VideoCodecRequirement.createRAV1DecoderReq());
1663     }
1664 
1665     /* Adds requirement 5.1/H-1-15 */
addR4k60HwDecoder()1666     public VideoCodecRequirement addR4k60HwDecoder() {
1667         return this.addRequirement(VideoCodecRequirement.createR4k60HwDecoder());
1668     }
1669 
1670     /* Adds requirement 5.1/H-1-16 */
addR4k60HwEncoder()1671     public VideoCodecRequirement addR4k60HwEncoder() {
1672         return this.addRequirement(VideoCodecRequirement.createR4k60HwEncoder());
1673     }
1674 
1675     /* Adds requirement 5.1/H-1-17 */
addRAVIFDecoderReq()1676     public VideoCodecRequirement addRAVIFDecoderReq() {
1677         return this.addRequirement(VideoCodecRequirement.createRAVIFDecoderReq());
1678     }
1679 
1680     /* Adds requirement 5.1/H-1-18 */
addRAV1EncoderReq()1681     public VideoCodecRequirement addRAV1EncoderReq() {
1682         return this.addRequirement(VideoCodecRequirement.createRAV1EncoderReq());
1683     }
1684 
addR5_1__H_1_19()1685     public ConcurrentCodecRequirement addR5_1__H_1_19() {
1686         return this.addRequirement(ConcurrentCodecRequirement.createR5_1__H_1_19());
1687     }
1688 
1689     /* Adds requirement 5.1/H-1-20 */
addR5_1__H_1_20()1690     public VideoCodecRequirement addR5_1__H_1_20() {
1691         return this.addRequirement(VideoCodecRequirement.createR5_1__H_1_20());
1692     }
1693 
1694     /* Adds requirement 5.1/H-1-21 */
addR5_1__H_1_21()1695     public VideoCodecRequirement addR5_1__H_1_21() {
1696         return this.addRequirement(VideoCodecRequirement.createR5_1__H_1_21());
1697     }
1698 
1699     /* Adds requirement 5.1/H-1-22 */
addR5_1__H_1_22()1700     public VideoCodecRequirement addR5_1__H_1_22() {
1701         return this.addRequirement(VideoCodecRequirement.createR5_1__H_1_22());
1702     }
1703 
addR5_3__H_1_1_R()1704     public FrameDropRequirement addR5_3__H_1_1_R() {
1705         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_R());
1706     }
1707 
addR5_3__H_1_1_ST()1708     public FrameDropRequirement addR5_3__H_1_1_ST() {
1709         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_ST());
1710     }
1711 
addR5_3__H_1_1_U()1712     public FrameDropRequirement addR5_3__H_1_1_U() {
1713         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_1_U());
1714     }
1715 
addR5_3__H_1_2_R()1716     public FrameDropRequirement addR5_3__H_1_2_R() {
1717         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_R());
1718     }
1719 
addR5_3__H_1_2_ST()1720     public FrameDropRequirement addR5_3__H_1_2_ST() {
1721         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_ST());
1722     }
1723 
addR5_3__H_1_2_U()1724     public FrameDropRequirement addR5_3__H_1_2_U() {
1725         return this.addRequirement(FrameDropRequirement.createR5_3__H_1_2_U());
1726     }
1727 
1728 
addR5_6__H_1_1()1729     public AudioTap2ToneLatencyRequirement addR5_6__H_1_1() {
1730         return this.addRequirement(AudioTap2ToneLatencyRequirement.createR5_6__H_1_1());
1731     }
1732 
1733 
addR5_7__H_1_2()1734     public SecureCodecRequirement addR5_7__H_1_2() {
1735         return this.addRequirement(SecureCodecRequirement.createR5_7__H_1_2());
1736     }
1737 
1738     /* Adds requirement 5.12/H-1-3 */
addExtYUVSupportReq()1739     public ExtYuvTargetRequirement addExtYUVSupportReq() {
1740         return this.addRequirement(ExtYuvTargetRequirement.createExtensionReq());
1741     }
1742 
1743     /** Add requirement <b>7.1.4.1/H-1-2</b> */
addR7_1_4_1__H_1_2()1744     public EglRequirement addR7_1_4_1__H_1_2() {
1745         return this.addRequirement(EglRequirement.createR7_1_4_1__H_1_2());
1746     }
1747 
1748     /* Adds requirement 7.5/H-1-1 */
addPrimaryRearCameraReq()1749     public PrimaryCameraRequirement addPrimaryRearCameraReq() {
1750         return this.addRequirement(PrimaryCameraRequirement.createRearPrimaryCamera());
1751     }
1752 
1753     /* Adds requirement 7.5/H-1-2 */
addPrimaryFrontCameraReq()1754     public PrimaryCameraRequirement addPrimaryFrontCameraReq() {
1755         return this.addRequirement(PrimaryCameraRequirement.createFrontPrimaryCamera());
1756     }
1757 
addR7_5__H_1_4()1758     public CameraTimestampSourceRequirement addR7_5__H_1_4() {
1759         return this.addRequirement(CameraTimestampSourceRequirement.createTimestampSourceReq());
1760     }
1761 
addR7_5__H_1_5()1762     public CameraLatencyRequirement addR7_5__H_1_5() {
1763         return this.addRequirement(CameraLatencyRequirement.createJpegLatencyReq());
1764     }
1765 
addR7_5__H_1_6()1766     public CameraLatencyRequirement addR7_5__H_1_6() {
1767         return this.addRequirement(CameraLatencyRequirement.createLaunchLatencyReq());
1768     }
1769 
addR7_5__H_1_8()1770     public CameraRawRequirement addR7_5__H_1_8() {
1771         return this.addRequirement(CameraRawRequirement.createRawReq());
1772     }
1773 
addR7_5__H_1_9()1774     public Camera240FpsRequirement addR7_5__H_1_9() {
1775         return this.addRequirement(Camera240FpsRequirement.create240FpsReq());
1776     }
1777 
addR7_5__H_1_10()1778     public UltraWideZoomRatioRequirement addR7_5__H_1_10() {
1779         return this.addRequirement(UltraWideZoomRatioRequirement.createUltrawideZoomRatioReq());
1780     }
1781 
addR7_5__H_1_11()1782     public ConcurrentRearFrontRequirement addR7_5__H_1_11() {
1783         return this.addRequirement(ConcurrentRearFrontRequirement.createConcurrentRearFrontReq());
1784     }
1785 
addR7_5__H_1_12()1786     public PreviewStabilizationRequirement addR7_5__H_1_12() {
1787         return this.addRequirement(PreviewStabilizationRequirement.createPreviewStabilizationReq());
1788     }
1789 
addR7_5__H_1_13()1790     public LogicalMultiCameraRequirement addR7_5__H_1_13() {
1791         return this.addRequirement(LogicalMultiCameraRequirement.createLogicalMultiCameraReq());
1792     }
1793 
addR7_5__H_1_14()1794     public StreamUseCaseRequirement addR7_5__H_1_14() {
1795         return this.addRequirement(StreamUseCaseRequirement.createStreamUseCaseReq());
1796     }
1797 
addR7_5__H_1_15()1798     public CameraExtensionRequirement addR7_5__H_1_15() {
1799         return this.addRequirement(CameraExtensionRequirement.createCameraExtensionReq());
1800     }
1801 
addR7_5__H_1_16()1802     public DynamicRangeTenBitsRequirement addR7_5__H_1_16() {
1803         return this.addRequirement(DynamicRangeTenBitsRequirement.createDynamicRangeTenBitsReq());
1804     }
1805 
addR7_5__H_1_17()1806     public FaceDetectionRequirement addR7_5__H_1_17() {
1807         return this.addRequirement(FaceDetectionRequirement.createFaceDetectionReq());
1808     }
addR7_5__H_1_18()1809     public JpegRRequirement addR7_5__H_1_18() {
1810         return this.addRequirement(JpegRRequirement.createJpegRReq());
1811     }
1812 
1813     /* Adds requirement 7.5/H-1-20 */
addR7_5__H_1_20()1814     public CameraUltraHdrRequirement addR7_5__H_1_20() {
1815         return this.addRequirement(CameraUltraHdrRequirement.createUltraHdrReq());
1816     }
1817 
1818     // TODO: b/329526179 Move all camera requirements to separate file
addR7_5__H_1_19()1819     public HLGCombinationRequirement addR7_5__H_1_19() {
1820         return this.addRequirement(HLGCombinationRequirement.createRearHLGCombinationReq());
1821     }
1822 
addR7_1_1_1__H_1_1()1823     public ResolutionRequirement addR7_1_1_1__H_1_1() {
1824         return this.<ResolutionRequirement>addRequirement(
1825                 ResolutionRequirement.createR7_1_1_1__H_1_1());
1826     }
1827 
addR7_1_1_3__H_1_1()1828     public DensityRequirement addR7_1_1_3__H_1_1() {
1829         return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__H_1_1());
1830     }
1831 
addR7_1_1_1__H_2_1()1832     public ResolutionRequirement addR7_1_1_1__H_2_1() {
1833         return this.<ResolutionRequirement>addRequirement(
1834                 ResolutionRequirement.createR7_1_1_1__H_2_1());
1835     }
1836 
addR7_1_1_3__H_2_1()1837     public DensityRequirement addR7_1_1_3__H_2_1() {
1838         return this.<DensityRequirement>addRequirement(DensityRequirement.createR7_1_1_3__H_2_1());
1839     }
1840 
addR8_2__H_1_1()1841     public FileSystemRequirement addR8_2__H_1_1() {
1842         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_1());
1843     }
1844 
addR8_2__H_2_1()1845     public FileSystemRequirement addR8_2__H_2_1() {
1846         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_1());
1847     }
1848 
addR8_2__H_1_2()1849     public FileSystemRequirement addR8_2__H_1_2() {
1850         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_2());
1851     }
1852 
addR8_2__H_2_2()1853     public FileSystemRequirement addR8_2__H_2_2() {
1854         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_2());
1855     }
1856 
addR8_2__H_1_3()1857     public FileSystemRequirement addR8_2__H_1_3() {
1858         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_3());
1859     }
1860 
addR8_2__H_2_3()1861     public FileSystemRequirement addR8_2__H_2_3() {
1862         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_3());
1863     }
1864 
addR8_2__H_1_4()1865     public FileSystemRequirement addR8_2__H_1_4() {
1866         return this.addRequirement(FileSystemRequirement.createR8_2__H_1_4());
1867     }
1868 
addR8_2__H_2_4()1869     public FileSystemRequirement addR8_2__H_2_4() {
1870         return this.addRequirement(FileSystemRequirement.createR8_2__H_2_4());
1871     }
1872 
1873 
1874     private enum SubmitType {
1875         TRADEFED, VERIFIER
1876     }
1877 
submitAndCheck()1878     public void submitAndCheck() {
1879         boolean perfClassMet = submit(SubmitType.TRADEFED);
1880 
1881         // check performance class
1882         assumeTrue("Build.VERSION.MEDIA_PERFORMANCE_CLASS is not declared", Utils.isPerfClass());
1883         assertThat(perfClassMet).isTrue();
1884     }
1885 
submitAndVerify()1886     public void submitAndVerify() {
1887         boolean perfClassMet = submit(SubmitType.VERIFIER);
1888 
1889         if (!perfClassMet && Utils.isPerfClass()) {
1890             Log.w(TAG, "Device did not meet specified performance class: " + Utils.getPerfClass());
1891         }
1892     }
1893 
submit(SubmitType type)1894     private boolean submit(SubmitType type) {
1895         boolean perfClassMet = true;
1896         for (Requirement req : this.mRequirements) {
1897             switch (type) {
1898                 case VERIFIER:
1899                     CtsVerifierReportLog verifierLog = new CtsVerifierReportLog(
1900                             RequirementConstants.REPORT_LOG_NAME, req.id());
1901                     perfClassMet &= req.writeLogAndCheck(verifierLog, this.mTestName);
1902                     verifierLog.submit();
1903                     break;
1904 
1905                 case TRADEFED:
1906                 default:
1907                     DeviceReportLog tradefedLog = new DeviceReportLog(
1908                             RequirementConstants.REPORT_LOG_NAME, req.id());
1909                     perfClassMet &= req.writeLogAndCheck(tradefedLog, this.mTestName);
1910                     tradefedLog.submit(InstrumentationRegistry.getInstrumentation());
1911                     break;
1912             }
1913         }
1914         this.mRequirements.clear(); // makes sure report isn't submitted twice
1915         return perfClassMet;
1916     }
1917 }
1918