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