| # Copyright 2014 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import sys |
| import unittest |
| |
| import its.objects |
| |
| |
| def skip_unless(cond): |
| """Skips the test if the condition is false. |
| |
| If a test is skipped, then it is exited and returns the special code |
| of 101 to the calling shell, which can be used by an external test |
| harness to differentiate a skip from a pass or fail. |
| |
| Args: |
| cond: Boolean, which must be true for the test to not skip. |
| |
| Returns: |
| Nothing. |
| """ |
| SKIP_RET_CODE = 101 |
| |
| if not cond: |
| print "Test skipped" |
| sys.exit(SKIP_RET_CODE) |
| |
| def full_or_better(props): |
| """Returns whether a device is a FULL or better camera2 device. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.info.supportedHardwareLevel") and \ |
| props["android.info.supportedHardwareLevel"] != 2 and \ |
| props["android.info.supportedHardwareLevel"] >= 1 |
| |
| def level3(props): |
| """Returns whether a device is a LEVEL3 capability camera2 device. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.info.supportedHardwareLevel") and \ |
| props["android.info.supportedHardwareLevel"] == 3 |
| |
| def full(props): |
| """Returns whether a device is a FULL capability camera2 device. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.info.supportedHardwareLevel") and \ |
| props["android.info.supportedHardwareLevel"] == 1 |
| |
| def limited(props): |
| """Returns whether a device is a LIMITED capability camera2 device. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.info.supportedHardwareLevel") and \ |
| props["android.info.supportedHardwareLevel"] == 0 |
| |
| def legacy(props): |
| """Returns whether a device is a LEGACY capability camera2 device. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.info.supportedHardwareLevel") and \ |
| props["android.info.supportedHardwareLevel"] == 2 |
| |
| def distortion_correction(props): |
| """Returns whether a device supports DISTORTION_CORRECTION |
| capabilities. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.lens.distortion") and \ |
| props["android.lens.distortion"] is not None |
| |
| def manual_sensor(props): |
| """Returns whether a device supports MANUAL_SENSOR capabilities. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 1 in props["android.request.availableCapabilities"] |
| |
| def manual_post_proc(props): |
| """Returns whether a device supports MANUAL_POST_PROCESSING capabilities. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 2 in props["android.request.availableCapabilities"] |
| |
| def raw(props): |
| """Returns whether a device supports RAW capabilities. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 3 in props["android.request.availableCapabilities"] |
| |
| def raw16(props): |
| """Returns whether a device supports RAW16 output. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return len(its.objects.get_available_output_sizes("raw", props)) > 0 |
| |
| def raw10(props): |
| """Returns whether a device supports RAW10 output. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return len(its.objects.get_available_output_sizes("raw10", props)) > 0 |
| |
| def raw12(props): |
| """Returns whether a device supports RAW12 output. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return len(its.objects.get_available_output_sizes("raw12", props)) > 0 |
| |
| def raw_output(props): |
| """Returns whether a device supports any of RAW output format. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return raw16(props) or raw10(props) or raw12(props) |
| |
| def post_raw_sensitivity_boost(props): |
| """Returns whether a device supports post RAW sensitivity boost.. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.control.postRawSensitivityBoostRange") and \ |
| props["android.control.postRawSensitivityBoostRange"] != [100, 100] |
| |
| def sensor_fusion(props): |
| """Returns whether the camera and motion sensor timestamps for the device |
| are in the same time domain and can be compared directly. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.sensor.info.timestampSource") and \ |
| props["android.sensor.info.timestampSource"] == 1 |
| |
| def read_3a(props): |
| """Return whether a device supports reading out the following 3A settings: |
| sensitivity |
| exposure time |
| awb gain |
| awb cct |
| focus distance |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| # TODO: check available result keys explicitly |
| return manual_sensor(props) and manual_post_proc(props) |
| |
| def compute_target_exposure(props): |
| """Return whether a device supports target exposure computation in its.target module. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return manual_sensor(props) and manual_post_proc(props) |
| |
| def freeform_crop(props): |
| """Returns whether a device supports freefrom cropping. |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.scaler.croppingType") and \ |
| props["android.scaler.croppingType"] == 1 |
| |
| def flash(props): |
| """Returns whether a device supports flash control. |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.flash.info.available") and \ |
| props["android.flash.info.available"] == 1 |
| |
| def per_frame_control(props): |
| """Returns whether a device supports per frame control |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.sync.maxLatency") and \ |
| props["android.sync.maxLatency"] == 0 |
| |
| def ev_compensation(props): |
| """Returns whether a device supports ev compensation |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.control.aeCompensationRange") and \ |
| props["android.control.aeCompensationRange"] != [0, 0] |
| |
| def ae_lock(props): |
| """Returns whether a device supports AE lock |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.control.aeLockAvailable") and \ |
| props["android.control.aeLockAvailable"] == 1 |
| |
| def awb_lock(props): |
| """Returns whether a device supports AWB lock |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.control.awbLockAvailable") and \ |
| props["android.control.awbLockAvailable"] == 1 |
| |
| def lsc_map(props): |
| """Returns whether a device supports lens shading map output |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key( |
| "android.statistics.info.availableLensShadingMapModes") and \ |
| 1 in props["android.statistics.info.availableLensShadingMapModes"] |
| |
| def lsc_off(props): |
| """Returns whether a device supports disabling lens shading correction |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key( |
| "android.shading.availableModes") and \ |
| 0 in props["android.shading.availableModes"] |
| |
| def yuv_reprocess(props): |
| """Returns whether a device supports YUV reprocessing. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 7 in props["android.request.availableCapabilities"] |
| |
| def private_reprocess(props): |
| """Returns whether a device supports PRIVATE reprocessing. |
| |
| Args: |
| props: Camera properties object. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 4 in props["android.request.availableCapabilities"] |
| |
| def noise_reduction_mode(props, mode): |
| """Returns whether a device supports the noise reduction mode. |
| |
| Args: |
| props: Camera properties objects. |
| mode: Integer, indicating the noise reduction mode to check for |
| availability. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key( |
| "android.noiseReduction.availableNoiseReductionModes") and mode \ |
| in props["android.noiseReduction.availableNoiseReductionModes"]; |
| |
| def edge_mode(props, mode): |
| """Returns whether a device supports the edge mode. |
| |
| Args: |
| props: Camera properties objects. |
| mode: Integer, indicating the edge mode to check for availability. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key( |
| "android.edge.availableEdgeModes") and mode \ |
| in props["android.edge.availableEdgeModes"]; |
| |
| |
| def lens_calibrated(props): |
| """Returns whether lens position is calibrated or not. |
| |
| android.lens.info.focusDistanceCalibration has 3 modes. |
| 0: Uncalibrated |
| 1: Approximate |
| 2: Calibrated |
| |
| Args: |
| props: Camera properties objects. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.lens.info.focusDistanceCalibration") and \ |
| props["android.lens.info.focusDistanceCalibration"] == 2 |
| |
| |
| def lens_approx_calibrated(props): |
| """Returns whether lens position is calibrated or not. |
| |
| android.lens.info.focusDistanceCalibration has 3 modes. |
| 0: Uncalibrated |
| 1: Approximate |
| 2: Calibrated |
| |
| Args: |
| props: Camera properties objects. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.lens.info.focusDistanceCalibration") and \ |
| (props["android.lens.info.focusDistanceCalibration"] == 1 or |
| props["android.lens.info.focusDistanceCalibration"] == 2) |
| |
| |
| def fixed_focus(props): |
| """Returns whether a device is fixed focus. |
| |
| props[android.lens.info.minimumFocusDistance] == 0 is fixed focus |
| |
| Args: |
| props: Camera properties objects. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.lens.info.minimumFocusDistance") and \ |
| props["android.lens.info.minimumFocusDistance"] == 0 |
| |
| def logical_multi_camera(props): |
| """Returns whether a device is a logical multi-camera. |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 11 in props["android.request.availableCapabilities"] |
| |
| def logical_multi_camera_physical_ids(props): |
| """Returns a logical multi-camera's underlying physical cameras. |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| list of physical cameras backing the logical multi-camera. |
| """ |
| physicalIdsList = [] |
| if logical_multi_camera(props): |
| physicalIds = props['android.logicalMultiCamera.physicalIds']; |
| physicalIdsString = ''.join(chr(e) for e in physicalIds); |
| physicalIdsList = filter(None, physicalIdsString.split('\x00')); |
| return physicalIdsList |
| |
| def mono_camera(props): |
| """Returns whether a device is monochromatic. |
| |
| Args: |
| props: Camera properties object. |
| |
| Return: |
| Boolean. |
| """ |
| return props.has_key("android.request.availableCapabilities") and \ |
| 12 in props["android.request.availableCapabilities"] |
| |
| |
| def face_detect(props): |
| """Returns whether a device has face detection mode. |
| |
| props['android.statistics.info.availableFaceDetectModes'] != 0 is face det |
| |
| Args: |
| props: Camera properties objects. |
| |
| Returns: |
| Boolean. |
| """ |
| return props.has_key("android.statistics.info.availableFaceDetectModes") and \ |
| props["android.statistics.info.availableFaceDetectModes"] != [0] |
| |
| |
| def debug_mode(): |
| """Returns True/False for whether test is run in debug mode. |
| |
| Returns: |
| Boolean. |
| """ |
| for s in sys.argv[1:]: |
| if s[:6] == "debug=" and s[6:] == "True": |
| return True |
| return False |
| |
| |
| class __UnitTest(unittest.TestCase): |
| """Run a suite of unit tests on this module. |
| """ |
| # TODO: Add more unit tests. |
| |
| if __name__ == '__main__': |
| unittest.main() |