1# Copyright 2014 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import sys 16import unittest 17 18import its.objects 19 20# lens facing 21FACING_FRONT = 0 22FACING_BACK = 1 23FACING_EXTERNAL = 2 24 25SKIP_RET_CODE = 101 26 27def skip_unless(cond): 28 """Skips the test if the condition is false. 29 30 If a test is skipped, then it is exited and returns the special code 31 of 101 to the calling shell, which can be used by an external test 32 harness to differentiate a skip from a pass or fail. 33 34 Args: 35 cond: Boolean, which must be true for the test to not skip. 36 37 Returns: 38 Nothing. 39 """ 40 if not cond: 41 print "Test skipped" 42 sys.exit(SKIP_RET_CODE) 43 44def full_or_better(props): 45 """Returns whether a device is a FULL or better camera2 device. 46 47 Args: 48 props: Camera properties object. 49 50 Returns: 51 Boolean. 52 """ 53 return props.has_key("android.info.supportedHardwareLevel") and \ 54 props["android.info.supportedHardwareLevel"] != 2 and \ 55 props["android.info.supportedHardwareLevel"] >= 1 56 57def level3(props): 58 """Returns whether a device is a LEVEL3 capability camera2 device. 59 60 Args: 61 props: Camera properties object. 62 63 Returns: 64 Boolean. 65 """ 66 return props.has_key("android.info.supportedHardwareLevel") and \ 67 props["android.info.supportedHardwareLevel"] == 3 68 69def full(props): 70 """Returns whether a device is a FULL capability camera2 device. 71 72 Args: 73 props: Camera properties object. 74 75 Returns: 76 Boolean. 77 """ 78 return props.has_key("android.info.supportedHardwareLevel") and \ 79 props["android.info.supportedHardwareLevel"] == 1 80 81def limited(props): 82 """Returns whether a device is a LIMITED capability camera2 device. 83 84 Args: 85 props: Camera properties object. 86 87 Returns: 88 Boolean. 89 """ 90 return props.has_key("android.info.supportedHardwareLevel") and \ 91 props["android.info.supportedHardwareLevel"] == 0 92 93def legacy(props): 94 """Returns whether a device is a LEGACY capability camera2 device. 95 96 Args: 97 props: Camera properties object. 98 99 Returns: 100 Boolean. 101 """ 102 return props.has_key("android.info.supportedHardwareLevel") and \ 103 props["android.info.supportedHardwareLevel"] == 2 104 105def distortion_correction(props): 106 """Returns whether a device supports DISTORTION_CORRECTION 107 capabilities. 108 109 Args: 110 props: Camera properties object. 111 112 Returns: 113 Boolean. 114 """ 115 return props.has_key("android.lens.distortion") and \ 116 props["android.lens.distortion"] is not None 117 118def manual_sensor(props): 119 """Returns whether a device supports MANUAL_SENSOR capabilities. 120 121 Args: 122 props: Camera properties object. 123 124 Returns: 125 Boolean. 126 """ 127 return props.has_key("android.request.availableCapabilities") and \ 128 1 in props["android.request.availableCapabilities"] 129 130def manual_post_proc(props): 131 """Returns whether a device supports MANUAL_POST_PROCESSING capabilities. 132 133 Args: 134 props: Camera properties object. 135 136 Returns: 137 Boolean. 138 """ 139 return props.has_key("android.request.availableCapabilities") and \ 140 2 in props["android.request.availableCapabilities"] 141 142def raw(props): 143 """Returns whether a device supports RAW capabilities. 144 145 Args: 146 props: Camera properties object. 147 148 Returns: 149 Boolean. 150 """ 151 return props.has_key("android.request.availableCapabilities") and \ 152 3 in props["android.request.availableCapabilities"] 153 154def raw16(props): 155 """Returns whether a device supports RAW16 output. 156 157 Args: 158 props: Camera properties object. 159 160 Returns: 161 Boolean. 162 """ 163 return len(its.objects.get_available_output_sizes("raw", props)) > 0 164 165def raw10(props): 166 """Returns whether a device supports RAW10 output. 167 168 Args: 169 props: Camera properties object. 170 171 Returns: 172 Boolean. 173 """ 174 return len(its.objects.get_available_output_sizes("raw10", props)) > 0 175 176def raw12(props): 177 """Returns whether a device supports RAW12 output. 178 179 Args: 180 props: Camera properties object. 181 182 Returns: 183 Boolean. 184 """ 185 return len(its.objects.get_available_output_sizes("raw12", props)) > 0 186 187def raw_output(props): 188 """Returns whether a device supports any of RAW output format. 189 190 Args: 191 props: Camera properties object. 192 193 Returns: 194 Boolean. 195 """ 196 return raw16(props) or raw10(props) or raw12(props) 197 198def y8(props): 199 """Returns whether a device supports Y8 output. 200 201 Args: 202 props: Camera properties object. 203 204 Returns: 205 Boolean. 206 """ 207 return len(its.objects.get_available_output_sizes("y8", props)) > 0 208 209def post_raw_sensitivity_boost(props): 210 """Returns whether a device supports post RAW sensitivity boost.. 211 212 Args: 213 props: Camera properties object. 214 215 Returns: 216 Boolean. 217 """ 218 return props.has_key("android.control.postRawSensitivityBoostRange") and \ 219 props["android.control.postRawSensitivityBoostRange"] != [100, 100] 220 221def sensor_fusion(props): 222 """Returns whether the camera and motion sensor timestamps for the device 223 are in the same time domain and can be compared directly. 224 225 Args: 226 props: Camera properties object. 227 228 Returns: 229 Boolean. 230 """ 231 return props.has_key("android.sensor.info.timestampSource") and \ 232 props["android.sensor.info.timestampSource"] == 1 233 234def read_3a(props): 235 """Return whether a device supports reading out the following 3A settings: 236 sensitivity 237 exposure time 238 awb gain 239 awb cct 240 focus distance 241 242 Args: 243 props: Camera properties object. 244 245 Returns: 246 Boolean. 247 """ 248 # TODO: check available result keys explicitly 249 return manual_sensor(props) and manual_post_proc(props) 250 251def compute_target_exposure(props): 252 """Return whether a device supports target exposure computation in its.target module. 253 254 Args: 255 props: Camera properties object. 256 257 Returns: 258 Boolean. 259 """ 260 return manual_sensor(props) and manual_post_proc(props) 261 262def freeform_crop(props): 263 """Returns whether a device supports freefrom cropping. 264 265 Args: 266 props: Camera properties object. 267 268 Return: 269 Boolean. 270 """ 271 return props.has_key("android.scaler.croppingType") and \ 272 props["android.scaler.croppingType"] == 1 273 274def flash(props): 275 """Returns whether a device supports flash control. 276 277 Args: 278 props: Camera properties object. 279 280 Return: 281 Boolean. 282 """ 283 return props.has_key("android.flash.info.available") and \ 284 props["android.flash.info.available"] == 1 285 286def per_frame_control(props): 287 """Returns whether a device supports per frame control 288 289 Args: 290 props: Camera properties object. 291 292 Return: 293 Boolean. 294 """ 295 return props.has_key("android.sync.maxLatency") and \ 296 props["android.sync.maxLatency"] == 0 297 298def ev_compensation(props): 299 """Returns whether a device supports ev compensation 300 301 Args: 302 props: Camera properties object. 303 304 Return: 305 Boolean. 306 """ 307 return props.has_key("android.control.aeCompensationRange") and \ 308 props["android.control.aeCompensationRange"] != [0, 0] 309 310def ae_lock(props): 311 """Returns whether a device supports AE lock 312 313 Args: 314 props: Camera properties object. 315 316 Return: 317 Boolean. 318 """ 319 return props.has_key("android.control.aeLockAvailable") and \ 320 props["android.control.aeLockAvailable"] == 1 321 322def awb_lock(props): 323 """Returns whether a device supports AWB lock 324 325 Args: 326 props: Camera properties object. 327 328 Return: 329 Boolean. 330 """ 331 return props.has_key("android.control.awbLockAvailable") and \ 332 props["android.control.awbLockAvailable"] == 1 333 334def lsc_map(props): 335 """Returns whether a device supports lens shading map output 336 337 Args: 338 props: Camera properties object. 339 340 Return: 341 Boolean. 342 """ 343 return props.has_key( 344 "android.statistics.info.availableLensShadingMapModes") and \ 345 1 in props["android.statistics.info.availableLensShadingMapModes"] 346 347def lsc_off(props): 348 """Returns whether a device supports disabling lens shading correction 349 350 Args: 351 props: Camera properties object. 352 353 Return: 354 Boolean. 355 """ 356 return props.has_key( 357 "android.shading.availableModes") and \ 358 0 in props["android.shading.availableModes"] 359 360def yuv_reprocess(props): 361 """Returns whether a device supports YUV reprocessing. 362 363 Args: 364 props: Camera properties object. 365 366 Returns: 367 Boolean. 368 """ 369 return props.has_key("android.request.availableCapabilities") and \ 370 7 in props["android.request.availableCapabilities"] 371 372def private_reprocess(props): 373 """Returns whether a device supports PRIVATE reprocessing. 374 375 Args: 376 props: Camera properties object. 377 378 Returns: 379 Boolean. 380 """ 381 return props.has_key("android.request.availableCapabilities") and \ 382 4 in props["android.request.availableCapabilities"] 383 384def noise_reduction_mode(props, mode): 385 """Returns whether a device supports the noise reduction mode. 386 387 Args: 388 props: Camera properties objects. 389 mode: Integer, indicating the noise reduction mode to check for 390 availability. 391 392 Returns: 393 Boolean. 394 """ 395 return props.has_key( 396 "android.noiseReduction.availableNoiseReductionModes") and mode \ 397 in props["android.noiseReduction.availableNoiseReductionModes"]; 398 399def edge_mode(props, mode): 400 """Returns whether a device supports the edge mode. 401 402 Args: 403 props: Camera properties objects. 404 mode: Integer, indicating the edge mode to check for availability. 405 406 Returns: 407 Boolean. 408 """ 409 return props.has_key( 410 "android.edge.availableEdgeModes") and mode \ 411 in props["android.edge.availableEdgeModes"]; 412 413 414def lens_calibrated(props): 415 """Returns whether lens position is calibrated or not. 416 417 android.lens.info.focusDistanceCalibration has 3 modes. 418 0: Uncalibrated 419 1: Approximate 420 2: Calibrated 421 422 Args: 423 props: Camera properties objects. 424 425 Returns: 426 Boolean. 427 """ 428 return props.has_key("android.lens.info.focusDistanceCalibration") and \ 429 props["android.lens.info.focusDistanceCalibration"] == 2 430 431 432def lens_approx_calibrated(props): 433 """Returns whether lens position is calibrated or not. 434 435 android.lens.info.focusDistanceCalibration has 3 modes. 436 0: Uncalibrated 437 1: Approximate 438 2: Calibrated 439 440 Args: 441 props: Camera properties objects. 442 443 Returns: 444 Boolean. 445 """ 446 return props.has_key("android.lens.info.focusDistanceCalibration") and \ 447 (props["android.lens.info.focusDistanceCalibration"] == 1 or 448 props["android.lens.info.focusDistanceCalibration"] == 2) 449 450 451def fixed_focus(props): 452 """Returns whether a device is fixed focus. 453 454 props[android.lens.info.minimumFocusDistance] == 0 is fixed focus 455 456 Args: 457 props: Camera properties objects. 458 459 Returns: 460 Boolean. 461 """ 462 return props.has_key("android.lens.info.minimumFocusDistance") and \ 463 props["android.lens.info.minimumFocusDistance"] == 0 464 465def logical_multi_camera(props): 466 """Returns whether a device is a logical multi-camera. 467 468 Args: 469 props: Camera properties object. 470 471 Return: 472 Boolean. 473 """ 474 return props.has_key("android.request.availableCapabilities") and \ 475 11 in props["android.request.availableCapabilities"] 476 477def logical_multi_camera_physical_ids(props): 478 """Returns a logical multi-camera's underlying physical cameras. 479 480 Args: 481 props: Camera properties object. 482 483 Return: 484 list of physical cameras backing the logical multi-camera. 485 """ 486 physicalIdsList = [] 487 if logical_multi_camera(props): 488 physicalIdsList = props['camera.characteristics.physicalCamIds']; 489 return physicalIdsList 490 491def mono_camera(props): 492 """Returns whether a device is monochromatic. 493 494 Args: 495 props: Camera properties object. 496 497 Return: 498 Boolean. 499 """ 500 return props.has_key("android.request.availableCapabilities") and \ 501 12 in props["android.request.availableCapabilities"] 502 503 504def face_detect(props): 505 """Returns whether a device has face detection mode. 506 507 props['android.statistics.info.availableFaceDetectModes'] != 0 is face det 508 509 Args: 510 props: Camera properties objects. 511 512 Returns: 513 Boolean. 514 """ 515 return props.has_key("android.statistics.info.availableFaceDetectModes") and \ 516 props["android.statistics.info.availableFaceDetectModes"] != [0] 517 518 519def debug_mode(): 520 """Returns True/False for whether test is run in debug mode. 521 522 Returns: 523 Boolean. 524 """ 525 for s in sys.argv[1:]: 526 if s[:6] == "debug=" and s[6:] == "True": 527 return True 528 return False 529 530 531def sync_latency(props): 532 """Returns sync latency in number of frames. 533 534 If undefined, 8 frames. 535 536 Returns: 537 integer number of frames 538 """ 539 sync_latency = props['android.sync.maxLatency'] 540 if sync_latency < 0: 541 sync_latency = 8 542 return sync_latency 543 544 545def backward_compatible(props): 546 """Returns whether a device supports BACKWARD_COMPATIBLE. 547 548 Args: 549 props: Camera properties object. 550 551 Returns: 552 Boolean. 553 """ 554 return props.has_key("android.request.availableCapabilities") and \ 555 0 in props["android.request.availableCapabilities"] 556 557 558def sensor_fusion_test_capable(props, cam): 559 """Determine if test_sensor_fusion is run.""" 560 return all([ 561 its.caps.sensor_fusion(props), 562 its.caps.manual_sensor(props), 563 props["android.lens.facing"] != FACING_EXTERNAL, 564 cam.get_sensors().get("gyro")]) 565 566 567def multi_camera_frame_sync_capable(props): 568 """Determine if test_multi_camera_frame_sync is run.""" 569 return all([ 570 read_3a(props), 571 per_frame_control(props), 572 logical_multi_camera(props), 573 sensor_fusion(props)]) 574 575 576def continuous_picture(props): 577 """Returns whether a device supports CONTINUOUS_PICTURE.""" 578 return props.has_key('android.control.afAvailableModes') and \ 579 4 in props['android.control.afAvailableModes'] 580 581 582def af_scene_change(props): 583 """Returns whether a device supports afSceneChange.""" 584 return props.has_key('camera.characteristics.resultKeys') and \ 585 'android.control.afSceneChange' in props['camera.characteristics.resultKeys'] 586 587 588def zoom_ratio_range(props): 589 """Returns whether a device supports zoom capabilities. 590 591 Args: 592 props: Camera properties object. 593 594 Returns: 595 Boolean. 596 """ 597 return props.has_key('android.control.zoomRatioRange') and \ 598 props['android.control.zoomRatioRange'] is not None 599 600 601def jpeg_quality(props): 602 """Returns whether a device supports JPEG quality.""" 603 return props.has_key('camera.characteristics.requestKeys') and \ 604 'android.jpeg.quality' in props['camera.characteristics.requestKeys'] 605 606 607class __UnitTest(unittest.TestCase): 608 """Run a suite of unit tests on this module. 609 """ 610 # TODO: Add more unit tests. 611 612if __name__ == '__main__': 613 unittest.main() 614