Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 1 | # Copyright 2020 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 | |
| 15 | |
| 16 | import logging |
| 17 | import time |
| 18 | |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 19 | from mobly import asserts |
| 20 | from mobly import base_test |
| 21 | from mobly import utils |
| 22 | from mobly.controllers import android_device |
| 23 | |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 24 | import its_session_utils |
| 25 | |
Clemenz Portmann | 1b6a167 | 2021-02-12 08:10:16 -0800 | [diff] [blame] | 26 | ADAPTIVE_BRIGHTNESS_OFF = '0' |
Clemenz Portmann | 89041658 | 2021-02-23 13:57:19 -0800 | [diff] [blame] | 27 | TABLET_CMD_DELAY_SEC = 0.5 # found empirically |
| 28 | TABLET_DIMMER_TIMEOUT_MS = 1800000 # this is max setting possible |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 29 | CTS_VERIFIER_PKG = 'com.android.cts.verifier' |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 30 | WAIT_TIME_SEC = 5 |
| 31 | SCROLLER_TIMEOUT_MS = 3000 |
| 32 | VALID_NUM_DEVICES = (1, 2) |
| 33 | NOT_YET_MANDATED_ALL = 100 |
| 34 | |
| 35 | # Not yet mandated tests ['test', first_api_level mandatory] |
| 36 | # ie. ['test_test_patterns', 30] is MANDATED for first_api_level >= 30 |
| 37 | NOT_YET_MANDATED = { |
Clemenz Portmann | 249916a | 2021-03-16 14:48:23 -0700 | [diff] [blame] | 38 | 'scene0': [['test_test_patterns', 30], |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 39 | ['test_tonemap_curve', 30]], |
| 40 | 'scene1_1': [['test_ae_precapture_trigger', 28], |
| 41 | ['test_channel_saturation', 29]], |
| 42 | 'scene1_2': [], |
| 43 | 'scene2_a': [['test_jpeg_quality', 30]], |
| 44 | 'scene2_b': [['test_auto_per_frame_control', NOT_YET_MANDATED_ALL]], |
| 45 | 'scene2_c': [], |
| 46 | 'scene2_d': [['test_num_faces', 30]], |
| 47 | 'scene2_e': [['test_num_faces', 30], ['test_continuous_picture', 30]], |
| 48 | 'scene3': [], |
| 49 | 'scene4': [], |
| 50 | 'scene5': [], |
| 51 | 'scene6': [['test_zoom', 30]], |
| 52 | 'sensor_fusion': [], |
| 53 | 'scene_change': [['test_scene_change', 31]] |
| 54 | } |
| 55 | |
| 56 | |
| 57 | class ItsBaseTest(base_test.BaseTestClass): |
| 58 | """Base test for CameraITS tests. |
| 59 | |
| 60 | Tests inherit from this class execute in the Camera ITS automation systems. |
| 61 | These systems consist of either: |
| 62 | 1. a device under test (dut) and an external rotation controller |
| 63 | 2. a device under test (dut) and one screen device(tablet) |
Clemenz Portmann | fb9c281 | 2021-02-19 15:57:28 -0800 | [diff] [blame] | 64 | 3. a device under test (dut) and manual charts |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 65 | |
| 66 | Attributes: |
| 67 | dut: android_device.AndroidDevice, the device under test. |
| 68 | tablet: android_device.AndroidDevice, the tablet device used to display |
| 69 | scenes. |
| 70 | """ |
| 71 | |
| 72 | def setup_class(self): |
| 73 | devices = self.register_controller(android_device, min_number=1) |
| 74 | self.dut = devices[0] |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 75 | self.camera = self.user_params['camera'] |
| 76 | if self.user_params.get('chart_distance'): |
| 77 | self.chart_distance = float(self.user_params['chart_distance']) |
| 78 | logging.debug('Chart distance: %s cm', self.chart_distance) |
Clemenz Portmann | fb9c281 | 2021-02-19 15:57:28 -0800 | [diff] [blame] | 79 | if self.user_params.get('chart_loc_arg'): |
| 80 | self.chart_loc_arg = self.user_params['chart_loc_arg'] |
| 81 | else: |
Clemenz Portmann | dc7ba2f | 2021-03-09 15:38:15 -0800 | [diff] [blame] | 82 | self.chart_loc_arg = '' |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 83 | if self.user_params.get('debug_mode'): |
| 84 | self.debug_mode = True if self.user_params[ |
| 85 | 'debug_mode'] == 'True' else False |
| 86 | if self.user_params.get('scene'): |
| 87 | self.scene = self.user_params['scene'] |
| 88 | camera_id_combo = self.parse_hidden_camera_id() |
| 89 | self.camera_id = camera_id_combo[0] |
| 90 | if len(camera_id_combo) == 2: |
| 91 | self.hidden_physical_id = camera_id_combo[1] |
| 92 | else: |
| 93 | self.hidden_physical_id = None |
| 94 | logging.debug('Camera_id:%s', self.camera_id) |
| 95 | logging.debug('Hidden Physical Camera_id: %s', self.hidden_physical_id) |
| 96 | |
| 97 | num_devices = len(devices) |
| 98 | if num_devices == 2: # scenes [0,1,2,3,4,5,6] |
| 99 | try: |
| 100 | self.tablet = devices[1] |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 101 | self.tablet_screen_brightness = self.user_params['brightness'] |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 102 | except KeyError: |
| 103 | logging.debug('Not all tablet arguments set.') |
| 104 | else: # sensor_fusion or manual run |
| 105 | try: |
| 106 | self.fps = int(self.user_params['fps']) |
| 107 | img_size = self.user_params['img_size'].split(',') |
| 108 | self.img_w = int(img_size[0]) |
| 109 | self.img_h = int(img_size[1]) |
| 110 | self.test_length = float(self.user_params['test_length']) |
| 111 | self.rotator_cntl = self.user_params['rotator_cntl'] |
| 112 | self.rotator_ch = self.user_params['rotator_ch'] |
| 113 | except KeyError: |
Clemenz Portmann | fb9c281 | 2021-02-19 15:57:28 -0800 | [diff] [blame] | 114 | self.tablet = None |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 115 | logging.debug('Not all arguments set. Manual run.') |
| 116 | |
| 117 | self._setup_devices(num_devices) |
| 118 | |
| 119 | def _setup_devices(self, num): |
| 120 | """Sets up each device in parallel if more than one device.""" |
| 121 | if num not in VALID_NUM_DEVICES: |
| 122 | raise AssertionError( |
| 123 | f'Incorrect number of devices! Must be in {str(VALID_NUM_DEVICES)}') |
| 124 | if num == 1: |
| 125 | self.setup_dut(self.dut) |
| 126 | else: |
| 127 | logic = lambda d: self.setup_dut(d) if d else self.setup_tablet() |
| 128 | utils.concurrent_exec( |
| 129 | logic, [(self.dut,), (None,)], |
| 130 | max_workers=2, |
| 131 | raise_on_exception=True) |
| 132 | |
| 133 | def setup_dut(self, device): |
| 134 | self.dut.adb.shell( |
| 135 | 'am start -n com.android.cts.verifier/.CtsVerifierActivity') |
| 136 | # Wait for the app screen to appear. |
| 137 | time.sleep(WAIT_TIME_SEC) |
| 138 | |
| 139 | def setup_tablet(self): |
Clemenz Portmann | 89041658 | 2021-02-23 13:57:19 -0800 | [diff] [blame] | 140 | # KEYCODE_POWER to reset dimmer timer. KEYCODE_WAKEUP no effect if ON. |
| 141 | self.tablet.adb.shell(['input', 'keyevent', 'KEYCODE_POWER']) |
| 142 | time.sleep(TABLET_CMD_DELAY_SEC) |
Clemenz Portmann | 21de9b4 | 2021-02-23 09:45:49 -0800 | [diff] [blame] | 143 | self.tablet.adb.shell(['input', 'keyevent', 'KEYCODE_WAKEUP']) |
Clemenz Portmann | 89041658 | 2021-02-23 13:57:19 -0800 | [diff] [blame] | 144 | time.sleep(TABLET_CMD_DELAY_SEC) |
Clemenz Portmann | f636d95 | 2021-03-04 08:05:33 -0800 | [diff] [blame] | 145 | # Dismiss keyguard |
| 146 | self.tablet.adb.shell(['wm', 'dismiss-keyguard']) |
| 147 | time.sleep(TABLET_CMD_DELAY_SEC) |
Clemenz Portmann | 1b6a167 | 2021-02-12 08:10:16 -0800 | [diff] [blame] | 148 | # Turn off the adaptive brightness on tablet. |
| 149 | self.tablet.adb.shell( |
| 150 | ['settings', 'put', 'system', 'screen_brightness_mode', |
| 151 | ADAPTIVE_BRIGHTNESS_OFF]) |
| 152 | # Set the screen brightness |
| 153 | self.tablet.adb.shell( |
| 154 | ['settings', 'put', 'system', 'screen_brightness', |
| 155 | str(self.tablet_screen_brightness)]) |
Clemenz Portmann | 46968a9 | 2021-02-05 15:00:16 -0800 | [diff] [blame] | 156 | logging.debug('Tablet brightness set to: %s', |
| 157 | format(self.tablet_screen_brightness)) |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 158 | self.tablet.adb.shell('settings put system screen_off_timeout {}'.format( |
Clemenz Portmann | 89041658 | 2021-02-23 13:57:19 -0800 | [diff] [blame] | 159 | TABLET_DIMMER_TIMEOUT_MS)) |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 160 | self.tablet.adb.shell('am force-stop com.google.android.apps.docs') |
| 161 | |
| 162 | def parse_hidden_camera_id(self): |
| 163 | """Parse the string of camera ID into an array. |
| 164 | |
| 165 | Returns: |
| 166 | Array with camera id and hidden_physical camera id. |
| 167 | """ |
Clemenz Portmann | dfbadd7 | 2021-03-12 15:02:39 -0800 | [diff] [blame] | 168 | camera_id_combo = self.camera.split(its_session_utils.SUB_CAMERA_SEPARATOR) |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 169 | return camera_id_combo |
| 170 | |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 171 | def determine_not_yet_mandated_tests(self, device_id, scene): |
| 172 | """Determine not_yet_mandated tests from NOT_YET_MANDATED list & phone info. |
| 173 | |
| 174 | Args: |
| 175 | device_id: string of device id number. |
| 176 | scene: scene to which tests belong to. |
| 177 | |
| 178 | Returns: |
| 179 | dict of not yet mandated tests |
| 180 | """ |
| 181 | # Initialize not_yet_mandated. |
| 182 | not_yet_mandated = {} |
| 183 | not_yet_mandated[scene] = [] |
| 184 | |
| 185 | # Determine first API level for device. |
| 186 | first_api_level = its_session_utils.get_first_api_level(device_id) |
| 187 | |
| 188 | # Determine which test are not yet mandated for first api level. |
| 189 | tests = NOT_YET_MANDATED[scene] |
Clemenz Portmann | dc7ba2f | 2021-03-09 15:38:15 -0800 | [diff] [blame] | 190 | for [test, first_api_level_mandated] in tests: |
Clemenz Portmann | 249916a | 2021-03-16 14:48:23 -0700 | [diff] [blame] | 191 | logging.debug('First API level %s MANDATED: %d', |
| 192 | test, first_api_level_mandated) |
Clemenz Portmann | dc7ba2f | 2021-03-09 15:38:15 -0800 | [diff] [blame] | 193 | if first_api_level < first_api_level_mandated: |
| 194 | not_yet_mandated[scene].append(test) |
Rucha Katakwar | b83e59a | 2021-02-02 17:16:54 -0800 | [diff] [blame] | 195 | return not_yet_mandated |
| 196 | |
| 197 | def on_pass(self, record): |
| 198 | logging.debug('%s on PASS.', record.test_name) |
| 199 | |
| 200 | def on_fail(self, record): |
| 201 | logging.debug('%s on FAIL.', record.test_name) |
| 202 | if self.user_params.get('scene'): |
| 203 | not_yet_mandated_tests = self.determine_not_yet_mandated_tests( |
| 204 | self.dut.serial, self.scene) |
| 205 | if self.current_test_info.name in not_yet_mandated_tests[self.scene]: |
| 206 | logging.debug('%s is not yet mandated.', self.current_test_info.name) |
| 207 | asserts.fail('Not yet mandated test', extras='Not yet mandated test') |
| 208 | |
| 209 | |