| # Copyright 2023 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. |
| """Verifies landscape to portrait override works as intended.""" |
| |
| |
| import logging |
| import os |
| |
| from mobly import test_runner |
| |
| import its_base_test |
| import camera_properties_utils |
| import its_session_utils |
| import opencv_processing_utils |
| |
| |
| _NAME = os.path.splitext(os.path.basename(__file__))[0] |
| _OPT_VAL_THRESHOLD = 0.5 |
| _ENABLED = 'enabled' |
| _DISABLED = 'disabled' |
| |
| |
| def _get_true_sensor_orientation(cam, camera_id): |
| """Returns a camera's properties and its true sensor orientation. |
| |
| Args: |
| cam: The camera object |
| camera_id: The id of the camera |
| |
| Returns: |
| Pair of camera properties and sensor orientation. |
| """ |
| props = cam.get_camera_properties_by_id(camera_id, |
| override_to_portrait=False) |
| props = cam.override_with_hidden_physical_camera_props(props) |
| sensor_orientation = camera_properties_utils.sensor_orientation(props) |
| return (props, sensor_orientation) |
| |
| |
| def _create_image_folder(log_path, suffix): |
| """Creates a new folder for storing debugging images and returns its path. |
| |
| Args: |
| log_path: The root log path for LandscapeToPortraitTest |
| suffix: The suffix string for the image folder ("enabled" or "disabled") |
| |
| Returns: |
| The newly created log path string, a subfolder of LandscapeToPortraitTest |
| """ |
| image_path = os.path.join(log_path, f'test_landscape_to_portrait_{suffix}') |
| os.mkdir(image_path) |
| return image_path |
| |
| |
| def _verify_opt_val(chart): |
| """Checks that the opt_val for template matching is sufficient to pass. |
| |
| Args: |
| chart: The chart for the test |
| """ |
| if chart.opt_val is None: |
| raise AssertionError('Unable to find a template match!') |
| elif chart.opt_val < _OPT_VAL_THRESHOLD: |
| raise AssertionError('Poor template match (opt val: ' |
| f'{chart.opt_val:.3f} thresh: {_OPT_VAL_THRESHOLD}' |
| '). Check jpeg output.') |
| |
| |
| class LandscapeToPortraitTest(its_base_test.ItsBaseTest): |
| """Test the landscape to portrait override. |
| |
| Note the test does not require a specific target but does perform |
| both automatic and manual captures so it requires a fixed scene |
| where 3A can converge. |
| """ |
| |
| def test_landscape_to_portrait_enabled(self): |
| logging.debug('Starting %s: %s', _NAME, _ENABLED) |
| with its_session_utils.ItsSession( |
| device_id=self.dut.serial, |
| camera_id=self.camera_id, |
| hidden_physical_id=self.hidden_physical_id, |
| override_to_portrait=True) as cam: |
| |
| # Read the properties with overrideToPortrait off to find the real sensor |
| # orientation |
| props, sensor_orientation = _get_true_sensor_orientation( |
| cam, self.camera_id) |
| |
| # check SKIP conditions |
| camera_properties_utils.skip_unless( |
| cam.is_landscape_to_portrait_enabled() and |
| (sensor_orientation == 0 or sensor_orientation == 180)) |
| |
| # Load chart for scene |
| its_session_utils.load_scene( |
| cam, props, self.scene, self.tablet, self.chart_distance) |
| |
| # Initialize chart class and locate chart in scene |
| # Make a separate log dir for the chart images, otherwise they'll get |
| # overwritten |
| image_path = _create_image_folder(self.log_path, _ENABLED) |
| chart = opencv_processing_utils.Chart( |
| cam, props, image_path, distance=self.chart_distance, rotation=90) |
| |
| _verify_opt_val(chart) |
| |
| def test_landscape_to_portrait_disabled(self): |
| logging.debug('Starting %s: %s', _NAME, _DISABLED) |
| with its_session_utils.ItsSession( |
| device_id=self.dut.serial, |
| camera_id=self.camera_id, |
| hidden_physical_id=self.hidden_physical_id) as cam: |
| |
| # Read the properties with overrideToPortrait off to find the real sensor |
| # orientation |
| props, sensor_orientation = _get_true_sensor_orientation( |
| cam, self.camera_id) |
| |
| # check SKIP conditions. |
| camera_properties_utils.skip_unless( |
| sensor_orientation == 0 or sensor_orientation == 180) |
| |
| # Load chart for scene |
| its_session_utils.load_scene( |
| cam, props, self.scene, self.tablet, self.chart_distance) |
| |
| # Initialize chart class and locate chart in scene |
| # Make a separate log dir for the chart images, otherwise they'll get |
| # overwritten |
| image_path = _create_image_folder(self.log_path, _DISABLED) |
| chart = opencv_processing_utils.Chart( |
| cam, props, image_path, distance=self.chart_distance) |
| |
| _verify_opt_val(chart) |
| |
| if __name__ == '__main__': |
| test_runner.main() |