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