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"""Verifies AE state machine when using precapture trigger.""" 15 16 17import logging 18import os 19from mobly import test_runner 20 21import its_base_test 22import camera_properties_utils 23import capture_request_utils 24import its_session_utils 25import target_exposure_utils 26 27_AE_INACTIVE = 0 28_AE_SEARCHING = 1 29_AE_CONVERGED = 2 30_AE_LOCKED = 3 # not used in this test 31_AE_FLASHREQUIRED = 4 # not used in this test 32_AE_PRECAPTURE = 5 33_FRAMES_AE_DISABLED = 5 34_FRAMES_PER_ITERATION = 8 35_ITERATIONS_TO_CONVERGE = 5 36_NAME = os.path.splitext(os.path.basename(__file__))[0] 37_START_AE_PRECAP_TRIG = 1 38_STOP_AE_PRECAP_TRIG = 0 39 40 41class AePrecaptureTest(its_base_test.ItsBaseTest): 42 """Test the AE state machine when using the precapture trigger. 43 """ 44 45 def test_ae_precapture(self): 46 logging.debug('Starting %s', _NAME) 47 logging.debug('AE_INACTIVE: %d', _AE_INACTIVE) 48 logging.debug('AE_SEARCHING: %d', _AE_SEARCHING) 49 logging.debug('AE_CONVERGED: %d', _AE_CONVERGED) 50 logging.debug('AE_PRECAPTURE: %d', _AE_PRECAPTURE) 51 52 with its_session_utils.ItsSession( 53 device_id=self.dut.serial, 54 camera_id=self.camera_id, 55 hidden_physical_id=self.hidden_physical_id) as cam: 56 props = cam.get_camera_properties() 57 props = cam.override_with_hidden_physical_camera_props(props) 58 59 # Check SKIP conditions 60 camera_properties_utils.skip_unless( 61 camera_properties_utils.compute_target_exposure(props) and 62 camera_properties_utils.per_frame_control(props)) 63 64 # Load chart for scene 65 its_session_utils.load_scene( 66 cam, props, self.scene, self.tablet, self.chart_distance) 67 68 _, fmt = capture_request_utils.get_fastest_manual_capture_settings(props) 69 70 # Capture 5 manual requests with AE disabled and the last request 71 # has an AE precapture trigger (which should be ignored since AE is 72 # disabled). 73 logging.debug('Manual captures') 74 manual_reqs = [] 75 e, s = target_exposure_utils.get_target_exposure_combos( 76 self.log_path, cam)['midExposureTime'] 77 manual_req = capture_request_utils.manual_capture_request(s, e) 78 manual_req['android.control.aeMode'] = _AE_INACTIVE 79 manual_reqs += [manual_req] * (_FRAMES_AE_DISABLED-1) 80 precap_req = capture_request_utils.manual_capture_request(s, e) 81 precap_req['android.control.aeMode'] = _AE_INACTIVE 82 precap_req['android.control.aePrecaptureTrigger'] = _START_AE_PRECAP_TRIG 83 manual_reqs.append(precap_req) 84 caps = cam.do_capture(manual_reqs, fmt) 85 for i, cap in enumerate(caps): 86 state = cap['metadata']['android.control.aeState'] 87 msg = f'AE state after manual request {i}: {state}' 88 logging.debug('%s', msg) 89 if state != _AE_INACTIVE: 90 raise AssertionError(f'{msg} AE_INACTIVE: {_AE_INACTIVE}') 91 92 # Capture auto request and verify the AE state: no trigger. 93 logging.debug('Auto capture') 94 auto_req = capture_request_utils.auto_capture_request() 95 auto_req['android.control.aeMode'] = _AE_SEARCHING 96 cap = cam.do_capture(auto_req, fmt) 97 state = cap['metadata']['android.control.aeState'] 98 msg = f'AE state after auto request: {state}' 99 logging.debug('%s', msg) 100 if state not in [_AE_SEARCHING, _AE_CONVERGED]: 101 raise AssertionError(f'{msg} AE_SEARCHING: {_AE_SEARCHING}, ' 102 f'AE_CONVERGED: {_AE_CONVERGED}') 103 104 # Capture auto request with a precapture trigger. 105 logging.debug('Auto capture with precapture trigger') 106 auto_req['android.control.aePrecaptureTrigger'] = _START_AE_PRECAP_TRIG 107 cap = cam.do_capture(auto_req, fmt) 108 state = cap['metadata']['android.control.aeState'] 109 msg = f'AE state after auto request with precapture trigger: {state}' 110 logging.debug('%s', msg) 111 if state not in [_AE_SEARCHING, _AE_CONVERGED, _AE_PRECAPTURE]: 112 raise AssertionError(f'{msg} AE_SEARCHING: {_AE_SEARCHING}, ' 113 f'AE_CONVERGED: {_AE_CONVERGED}, ' 114 f'AE_PRECAPTURE: {_AE_PRECAPTURE}') 115 116 # Capture some more auto requests, and AE should converge. 117 logging.debug('Additional auto captures') 118 auto_req['android.control.aePrecaptureTrigger'] = _STOP_AE_PRECAP_TRIG 119 for _ in range(_ITERATIONS_TO_CONVERGE): 120 caps = cam.do_capture([auto_req] * _FRAMES_PER_ITERATION, fmt) 121 state = caps[-1]['metadata']['android.control.aeState'] 122 msg = f'AE state after auto request: {state}' 123 logging.debug('%s', msg) 124 if state == _AE_CONVERGED: 125 return 126 if state != _AE_CONVERGED: 127 raise AssertionError(f'{msg} AE_CONVERGED: {_AE_CONVERGED}') 128 129if __name__ == '__main__': 130 test_runner.main() 131