xref: /aosp_15_r20/cts/apps/CameraITS/tests/its_base_test.py (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker# Copyright 2020 The Android Open Source Project
2*b7c941bbSAndroid Build Coastguard Worker#
3*b7c941bbSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*b7c941bbSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*b7c941bbSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*b7c941bbSAndroid Build Coastguard Worker#
7*b7c941bbSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*b7c941bbSAndroid Build Coastguard Worker#
9*b7c941bbSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*b7c941bbSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*b7c941bbSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*b7c941bbSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*b7c941bbSAndroid Build Coastguard Worker# limitations under the License.
14*b7c941bbSAndroid Build Coastguard Worker
15*b7c941bbSAndroid Build Coastguard Worker
16*b7c941bbSAndroid Build Coastguard Workerimport logging
17*b7c941bbSAndroid Build Coastguard Workerimport os
18*b7c941bbSAndroid Build Coastguard Workerimport time
19*b7c941bbSAndroid Build Coastguard Workerimport cv2
20*b7c941bbSAndroid Build Coastguard Worker
21*b7c941bbSAndroid Build Coastguard Workerimport its_session_utils
22*b7c941bbSAndroid Build Coastguard Workerimport lighting_control_utils
23*b7c941bbSAndroid Build Coastguard Workerfrom mobly import base_test
24*b7c941bbSAndroid Build Coastguard Workerfrom mobly import utils
25*b7c941bbSAndroid Build Coastguard Workerfrom mobly.controllers import android_device
26*b7c941bbSAndroid Build Coastguard Workerfrom snippet_uiautomator import uiautomator
27*b7c941bbSAndroid Build Coastguard Worker
28*b7c941bbSAndroid Build Coastguard Worker
29*b7c941bbSAndroid Build Coastguard WorkerADAPTIVE_BRIGHTNESS_OFF = '0'
30*b7c941bbSAndroid Build Coastguard WorkerTABLET_CMD_DELAY_SEC = 0.5  # found empirically
31*b7c941bbSAndroid Build Coastguard WorkerTABLET_DIMMER_TIMEOUT_MS = 1800000  # this is max setting possible
32*b7c941bbSAndroid Build Coastguard WorkerCTS_VERIFIER_PKG = 'com.android.cts.verifier'
33*b7c941bbSAndroid Build Coastguard WorkerWAIT_TIME_SEC = 5
34*b7c941bbSAndroid Build Coastguard WorkerSCROLLER_TIMEOUT_MS = 3000
35*b7c941bbSAndroid Build Coastguard WorkerVALID_NUM_DEVICES = (1, 2)
36*b7c941bbSAndroid Build Coastguard WorkerFRONT_CAMERA_ID_PREFIX = '1'
37*b7c941bbSAndroid Build Coastguard Worker
38*b7c941bbSAndroid Build Coastguard Workerlogging.getLogger('matplotlib.font_manager').disabled = True
39*b7c941bbSAndroid Build Coastguard Worker
40*b7c941bbSAndroid Build Coastguard Worker
41*b7c941bbSAndroid Build Coastguard Workerclass ItsBaseTest(base_test.BaseTestClass):
42*b7c941bbSAndroid Build Coastguard Worker  """Base test for CameraITS tests.
43*b7c941bbSAndroid Build Coastguard Worker
44*b7c941bbSAndroid Build Coastguard Worker  Tests inherit from this class execute in the Camera ITS automation systems.
45*b7c941bbSAndroid Build Coastguard Worker  These systems consist of either:
46*b7c941bbSAndroid Build Coastguard Worker    1. a device under test (dut) and an external rotation controller
47*b7c941bbSAndroid Build Coastguard Worker    2. a device under test (dut) and one screen device(tablet)
48*b7c941bbSAndroid Build Coastguard Worker    3. a device under test (dut) and manual charts
49*b7c941bbSAndroid Build Coastguard Worker
50*b7c941bbSAndroid Build Coastguard Worker  Attributes:
51*b7c941bbSAndroid Build Coastguard Worker    dut: android_device.AndroidDevice, the device under test.
52*b7c941bbSAndroid Build Coastguard Worker    tablet: android_device.AndroidDevice, the tablet device used to display
53*b7c941bbSAndroid Build Coastguard Worker        scenes.
54*b7c941bbSAndroid Build Coastguard Worker  """
55*b7c941bbSAndroid Build Coastguard Worker
56*b7c941bbSAndroid Build Coastguard Worker  def setup_class(self):
57*b7c941bbSAndroid Build Coastguard Worker    devices = self.register_controller(android_device, min_number=1)
58*b7c941bbSAndroid Build Coastguard Worker    self.dut = devices[0]
59*b7c941bbSAndroid Build Coastguard Worker    self.camera = str(self.user_params['camera'])
60*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Camera_id: %s', self.camera)
61*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('chart_distance'):
62*b7c941bbSAndroid Build Coastguard Worker      self.chart_distance = float(self.user_params['chart_distance'])
63*b7c941bbSAndroid Build Coastguard Worker      logging.debug('Chart distance: %s cm', self.chart_distance)
64*b7c941bbSAndroid Build Coastguard Worker    if (self.user_params.get('lighting_cntl') and
65*b7c941bbSAndroid Build Coastguard Worker        self.user_params.get('lighting_ch')):
66*b7c941bbSAndroid Build Coastguard Worker      self.lighting_cntl = self.user_params['lighting_cntl']
67*b7c941bbSAndroid Build Coastguard Worker      self.lighting_ch = str(self.user_params['lighting_ch'])
68*b7c941bbSAndroid Build Coastguard Worker    else:
69*b7c941bbSAndroid Build Coastguard Worker      self.lighting_cntl = 'None'
70*b7c941bbSAndroid Build Coastguard Worker      self.lighting_ch = '1'
71*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('tablet_device'):
72*b7c941bbSAndroid Build Coastguard Worker      self.tablet_device = self.user_params['tablet_device'] == 'True'
73*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('debug_mode'):
74*b7c941bbSAndroid Build Coastguard Worker      self.debug_mode = self.user_params['debug_mode'] == 'True'
75*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('scene'):
76*b7c941bbSAndroid Build Coastguard Worker      self.scene = self.user_params['scene']
77*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('log_feature_combo_support'):
78*b7c941bbSAndroid Build Coastguard Worker      self.log_feature_combo_support = (
79*b7c941bbSAndroid Build Coastguard Worker          self.user_params['log_feature_combo_support'] == 'True'
80*b7c941bbSAndroid Build Coastguard Worker      )
81*b7c941bbSAndroid Build Coastguard Worker    camera_id_combo = self.parse_hidden_camera_id()
82*b7c941bbSAndroid Build Coastguard Worker    self.camera_id = camera_id_combo[0]
83*b7c941bbSAndroid Build Coastguard Worker    if len(camera_id_combo) == 2:
84*b7c941bbSAndroid Build Coastguard Worker      self.hidden_physical_id = camera_id_combo[1]
85*b7c941bbSAndroid Build Coastguard Worker    else:
86*b7c941bbSAndroid Build Coastguard Worker      self.hidden_physical_id = None
87*b7c941bbSAndroid Build Coastguard Worker
88*b7c941bbSAndroid Build Coastguard Worker    num_devices = len(devices)
89*b7c941bbSAndroid Build Coastguard Worker    if num_devices == 2:  # scenes [0,1,2,3,4,5,6]
90*b7c941bbSAndroid Build Coastguard Worker      try:
91*b7c941bbSAndroid Build Coastguard Worker        self.tablet = devices[1]
92*b7c941bbSAndroid Build Coastguard Worker        self.tablet_screen_brightness = self.user_params['brightness']
93*b7c941bbSAndroid Build Coastguard Worker        tablet_name_unencoded = self.tablet.adb.shell(
94*b7c941bbSAndroid Build Coastguard Worker            ['getprop', 'ro.product.device']
95*b7c941bbSAndroid Build Coastguard Worker        )
96*b7c941bbSAndroid Build Coastguard Worker        tablet_name = str(tablet_name_unencoded.decode('utf-8')).strip()
97*b7c941bbSAndroid Build Coastguard Worker        logging.debug('tablet name: %s', tablet_name)
98*b7c941bbSAndroid Build Coastguard Worker        its_session_utils.validate_tablet(
99*b7c941bbSAndroid Build Coastguard Worker            tablet_name, self.tablet_screen_brightness,
100*b7c941bbSAndroid Build Coastguard Worker            self.tablet.serial)
101*b7c941bbSAndroid Build Coastguard Worker      except KeyError:
102*b7c941bbSAndroid Build Coastguard Worker        logging.debug('Not all tablet arguments set.')
103*b7c941bbSAndroid Build Coastguard Worker    else:  # sensor_fusion or manual run
104*b7c941bbSAndroid Build Coastguard Worker      try:
105*b7c941bbSAndroid Build Coastguard Worker        self.fps = int(self.user_params['fps'])
106*b7c941bbSAndroid Build Coastguard Worker        img_size = self.user_params['img_size'].split(',')
107*b7c941bbSAndroid Build Coastguard Worker        self.img_w = int(img_size[0])
108*b7c941bbSAndroid Build Coastguard Worker        self.img_h = int(img_size[1])
109*b7c941bbSAndroid Build Coastguard Worker        self.test_length = float(self.user_params['test_length'])
110*b7c941bbSAndroid Build Coastguard Worker        self.rotator_cntl = self.user_params['rotator_cntl']
111*b7c941bbSAndroid Build Coastguard Worker        self.rotator_ch = str(self.user_params['rotator_ch'])
112*b7c941bbSAndroid Build Coastguard Worker      except KeyError:
113*b7c941bbSAndroid Build Coastguard Worker        self.tablet = None
114*b7c941bbSAndroid Build Coastguard Worker        logging.debug('Not all arguments set. Manual run.')
115*b7c941bbSAndroid Build Coastguard Worker
116*b7c941bbSAndroid Build Coastguard Worker    self._setup_devices(num_devices)
117*b7c941bbSAndroid Build Coastguard Worker
118*b7c941bbSAndroid Build Coastguard Worker    arduino_serial_port = lighting_control_utils.lighting_control(
119*b7c941bbSAndroid Build Coastguard Worker        self.lighting_cntl, self.lighting_ch)
120*b7c941bbSAndroid Build Coastguard Worker    if arduino_serial_port and self.scene != 'scene0':
121*b7c941bbSAndroid Build Coastguard Worker      lighting_control_utils.set_light_brightness(
122*b7c941bbSAndroid Build Coastguard Worker          self.lighting_ch, 255, arduino_serial_port)
123*b7c941bbSAndroid Build Coastguard Worker      logging.debug('Light is turned ON.')
124*b7c941bbSAndroid Build Coastguard Worker
125*b7c941bbSAndroid Build Coastguard Worker    # Check if current foldable state matches scene, if applicable
126*b7c941bbSAndroid Build Coastguard Worker    if self.user_params.get('foldable_device', 'False') == 'True':
127*b7c941bbSAndroid Build Coastguard Worker      foldable_state_unencoded = self.dut.adb.shell(
128*b7c941bbSAndroid Build Coastguard Worker          ['cmd', 'device_state', 'state']
129*b7c941bbSAndroid Build Coastguard Worker      )
130*b7c941bbSAndroid Build Coastguard Worker      foldable_state = str(foldable_state_unencoded.decode('utf-8')).strip()
131*b7c941bbSAndroid Build Coastguard Worker      is_folded = 'CLOSE' in foldable_state
132*b7c941bbSAndroid Build Coastguard Worker      scene_with_suffix = self.user_params.get('scene_with_suffix')
133*b7c941bbSAndroid Build Coastguard Worker      if scene_with_suffix:
134*b7c941bbSAndroid Build Coastguard Worker        if 'folded' in scene_with_suffix and not is_folded:
135*b7c941bbSAndroid Build Coastguard Worker          raise AssertionError(
136*b7c941bbSAndroid Build Coastguard Worker              f'Testing folded scene {scene_with_suffix} with unfolded device!')
137*b7c941bbSAndroid Build Coastguard Worker        if ('folded' not in scene_with_suffix and is_folded and
138*b7c941bbSAndroid Build Coastguard Worker            self.camera.startswith(FRONT_CAMERA_ID_PREFIX)):  # Not rear camera
139*b7c941bbSAndroid Build Coastguard Worker          raise AssertionError(
140*b7c941bbSAndroid Build Coastguard Worker              f'Testing unfolded scene {scene_with_suffix} with a '
141*b7c941bbSAndroid Build Coastguard Worker              'non-rear camera while device is folded!'
142*b7c941bbSAndroid Build Coastguard Worker          )
143*b7c941bbSAndroid Build Coastguard Worker      else:
144*b7c941bbSAndroid Build Coastguard Worker        logging.debug('Testing without `run_all_tests`')
145*b7c941bbSAndroid Build Coastguard Worker
146*b7c941bbSAndroid Build Coastguard Worker    cv2_version = cv2.__version__
147*b7c941bbSAndroid Build Coastguard Worker    logging.debug('cv2_version: %s', cv2_version)
148*b7c941bbSAndroid Build Coastguard Worker
149*b7c941bbSAndroid Build Coastguard Worker  def _setup_devices(self, num):
150*b7c941bbSAndroid Build Coastguard Worker    """Sets up each device in parallel if more than one device."""
151*b7c941bbSAndroid Build Coastguard Worker    if num not in VALID_NUM_DEVICES:
152*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError(
153*b7c941bbSAndroid Build Coastguard Worker          f'Incorrect number of devices! Must be in {str(VALID_NUM_DEVICES)}')
154*b7c941bbSAndroid Build Coastguard Worker    if num == 1:
155*b7c941bbSAndroid Build Coastguard Worker      self.setup_dut(self.dut)
156*b7c941bbSAndroid Build Coastguard Worker    else:
157*b7c941bbSAndroid Build Coastguard Worker      logic = lambda d: self.setup_dut(d) if d else self.setup_tablet()
158*b7c941bbSAndroid Build Coastguard Worker      utils.concurrent_exec(
159*b7c941bbSAndroid Build Coastguard Worker          logic, [(self.dut,), (None,)],
160*b7c941bbSAndroid Build Coastguard Worker          max_workers=2,
161*b7c941bbSAndroid Build Coastguard Worker          raise_on_exception=True)
162*b7c941bbSAndroid Build Coastguard Worker
163*b7c941bbSAndroid Build Coastguard Worker  def setup_dut(self, device):
164*b7c941bbSAndroid Build Coastguard Worker    self.dut.adb.shell(
165*b7c941bbSAndroid Build Coastguard Worker        'am start -n com.android.cts.verifier/.CtsVerifierActivity')
166*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Setting up device: %s', str(device))
167*b7c941bbSAndroid Build Coastguard Worker    # Wait for the app screen to appear.
168*b7c941bbSAndroid Build Coastguard Worker    time.sleep(WAIT_TIME_SEC)
169*b7c941bbSAndroid Build Coastguard Worker
170*b7c941bbSAndroid Build Coastguard Worker  def setup_tablet(self):
171*b7c941bbSAndroid Build Coastguard Worker    # KEYCODE_POWER to reset dimmer timer. KEYCODE_WAKEUP no effect if ON.
172*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(['input', 'keyevent', 'KEYCODE_POWER'])
173*b7c941bbSAndroid Build Coastguard Worker    time.sleep(TABLET_CMD_DELAY_SEC)
174*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(['input', 'keyevent', 'KEYCODE_WAKEUP'])
175*b7c941bbSAndroid Build Coastguard Worker    time.sleep(TABLET_CMD_DELAY_SEC)
176*b7c941bbSAndroid Build Coastguard Worker    # Dismiss keyguard
177*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(['wm', 'dismiss-keyguard'])
178*b7c941bbSAndroid Build Coastguard Worker    time.sleep(TABLET_CMD_DELAY_SEC)
179*b7c941bbSAndroid Build Coastguard Worker    # Turn off the adaptive brightness on tablet.
180*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(
181*b7c941bbSAndroid Build Coastguard Worker        ['settings', 'put', 'system', 'screen_brightness_mode',
182*b7c941bbSAndroid Build Coastguard Worker         ADAPTIVE_BRIGHTNESS_OFF])
183*b7c941bbSAndroid Build Coastguard Worker    # Set the screen brightness
184*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(
185*b7c941bbSAndroid Build Coastguard Worker        ['settings', 'put', 'system', 'screen_brightness',
186*b7c941bbSAndroid Build Coastguard Worker         str(self.tablet_screen_brightness)])
187*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Tablet brightness set to: %s',
188*b7c941bbSAndroid Build Coastguard Worker                  format(self.tablet_screen_brightness))
189*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('settings put system screen_off_timeout {}'.format(
190*b7c941bbSAndroid Build Coastguard Worker        TABLET_DIMMER_TIMEOUT_MS))
191*b7c941bbSAndroid Build Coastguard Worker    self.set_tablet_landscape_orientation()
192*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('am force-stop com.google.android.apps.docs')
193*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('am force-stop com.google.android.apps.photos')
194*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('am force-stop com.android.gallery3d')
195*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('am force-stop com.sec.android.gallery3d')
196*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell('am force-stop com.miui.gallery')
197*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(
198*b7c941bbSAndroid Build Coastguard Worker        'settings put global policy_control immersive.full=*')
199*b7c941bbSAndroid Build Coastguard Worker
200*b7c941bbSAndroid Build Coastguard Worker  def set_tablet_landscape_orientation(self):
201*b7c941bbSAndroid Build Coastguard Worker    """Sets the screen orientation to landscape.
202*b7c941bbSAndroid Build Coastguard Worker    """
203*b7c941bbSAndroid Build Coastguard Worker    # Get the landscape orientation value.
204*b7c941bbSAndroid Build Coastguard Worker    # This value is different for Pixel C/Huawei/Samsung tablets.
205*b7c941bbSAndroid Build Coastguard Worker    output = self.tablet.adb.shell('dumpsys window | grep mLandscapeRotation')
206*b7c941bbSAndroid Build Coastguard Worker    logging.debug('dumpsys window output: %s', output.decode('utf-8').strip())
207*b7c941bbSAndroid Build Coastguard Worker    output_list = str(output.decode('utf-8')).strip().split(' ')
208*b7c941bbSAndroid Build Coastguard Worker    for val in output_list:
209*b7c941bbSAndroid Build Coastguard Worker      if 'LandscapeRotation' in val:
210*b7c941bbSAndroid Build Coastguard Worker        landscape_val = str(val.split('=')[-1])
211*b7c941bbSAndroid Build Coastguard Worker        # For some tablets the values are in constant forms such as ROTATION_90
212*b7c941bbSAndroid Build Coastguard Worker        if 'ROTATION_90' in landscape_val:
213*b7c941bbSAndroid Build Coastguard Worker          landscape_val = '1'
214*b7c941bbSAndroid Build Coastguard Worker        elif 'ROTATION_0' in landscape_val:
215*b7c941bbSAndroid Build Coastguard Worker          landscape_val = '0'
216*b7c941bbSAndroid Build Coastguard Worker        logging.debug('Changing the orientation to landscape mode.')
217*b7c941bbSAndroid Build Coastguard Worker        self.tablet.adb.shell(['settings', 'put', 'system', 'user_rotation',
218*b7c941bbSAndroid Build Coastguard Worker                               landscape_val])
219*b7c941bbSAndroid Build Coastguard Worker        break
220*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Reported tablet orientation is: %d',
221*b7c941bbSAndroid Build Coastguard Worker                  int(self.tablet.adb.shell(
222*b7c941bbSAndroid Build Coastguard Worker                      'settings get system user_rotation')))
223*b7c941bbSAndroid Build Coastguard Worker
224*b7c941bbSAndroid Build Coastguard Worker  def set_screen_brightness(self, brightness_level):
225*b7c941bbSAndroid Build Coastguard Worker    """Sets the screen brightness to desired level.
226*b7c941bbSAndroid Build Coastguard Worker
227*b7c941bbSAndroid Build Coastguard Worker    Args:
228*b7c941bbSAndroid Build Coastguard Worker       brightness_level : brightness level to set.
229*b7c941bbSAndroid Build Coastguard Worker    """
230*b7c941bbSAndroid Build Coastguard Worker    # Turn off the adaptive brightness on tablet.
231*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell(
232*b7c941bbSAndroid Build Coastguard Worker        ['settings', 'put', 'system', 'screen_brightness_mode', '0'])
233*b7c941bbSAndroid Build Coastguard Worker    # Set the screen brightness
234*b7c941bbSAndroid Build Coastguard Worker    self.tablet.adb.shell([
235*b7c941bbSAndroid Build Coastguard Worker        'settings', 'put', 'system', 'screen_brightness',
236*b7c941bbSAndroid Build Coastguard Worker        brightness_level
237*b7c941bbSAndroid Build Coastguard Worker    ])
238*b7c941bbSAndroid Build Coastguard Worker    logging.debug('Tablet brightness set to: %s', brightness_level)
239*b7c941bbSAndroid Build Coastguard Worker    actual_brightness = self.tablet.adb.shell(
240*b7c941bbSAndroid Build Coastguard Worker        'settings get system screen_brightness')
241*b7c941bbSAndroid Build Coastguard Worker    if int(actual_brightness) != int(brightness_level):
242*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('Brightness was not set as expected! '
243*b7c941bbSAndroid Build Coastguard Worker                           f'Requested brightness: {brightness_level}, '
244*b7c941bbSAndroid Build Coastguard Worker                           f'Actual brightness: {actual_brightness}')
245*b7c941bbSAndroid Build Coastguard Worker
246*b7c941bbSAndroid Build Coastguard Worker  def turn_off_tablet(self):
247*b7c941bbSAndroid Build Coastguard Worker    """Turns off tablet, raising AssertionError if tablet is not found."""
248*b7c941bbSAndroid Build Coastguard Worker    if self.tablet:
249*b7c941bbSAndroid Build Coastguard Worker      lighting_control_utils.turn_off_device_screen(self.tablet)
250*b7c941bbSAndroid Build Coastguard Worker    else:
251*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError('Test must be run with tablet.')
252*b7c941bbSAndroid Build Coastguard Worker
253*b7c941bbSAndroid Build Coastguard Worker  def parse_hidden_camera_id(self):
254*b7c941bbSAndroid Build Coastguard Worker    """Parse the string of camera ID into an array.
255*b7c941bbSAndroid Build Coastguard Worker
256*b7c941bbSAndroid Build Coastguard Worker    Returns:
257*b7c941bbSAndroid Build Coastguard Worker      Array with camera id and hidden_physical camera id.
258*b7c941bbSAndroid Build Coastguard Worker    """
259*b7c941bbSAndroid Build Coastguard Worker    camera_id_combo = self.camera.split(its_session_utils.SUB_CAMERA_SEPARATOR)
260*b7c941bbSAndroid Build Coastguard Worker    return camera_id_combo
261*b7c941bbSAndroid Build Coastguard Worker
262*b7c941bbSAndroid Build Coastguard Worker  def on_pass(self, record):
263*b7c941bbSAndroid Build Coastguard Worker    logging.debug('%s on PASS.', record.test_name)
264*b7c941bbSAndroid Build Coastguard Worker
265*b7c941bbSAndroid Build Coastguard Worker  def on_fail(self, record):
266*b7c941bbSAndroid Build Coastguard Worker    logging.debug('%s on FAIL.', record.test_name)
267*b7c941bbSAndroid Build Coastguard Worker
268*b7c941bbSAndroid Build Coastguard Worker  def teardown_class(self):
269*b7c941bbSAndroid Build Coastguard Worker    # edit root_output_path and summary_writer path
270*b7c941bbSAndroid Build Coastguard Worker    # to add test name to output directory
271*b7c941bbSAndroid Build Coastguard Worker    logging.debug('summary_writer._path: %s', self.summary_writer._path)
272*b7c941bbSAndroid Build Coastguard Worker    summary_head, summary_tail = os.path.split(self.summary_writer._path)
273*b7c941bbSAndroid Build Coastguard Worker    self.summary_writer._path = os.path.join(
274*b7c941bbSAndroid Build Coastguard Worker        f'{summary_head}_{self.__class__.__name__}', summary_tail)
275*b7c941bbSAndroid Build Coastguard Worker    os.rename(self.root_output_path,
276*b7c941bbSAndroid Build Coastguard Worker              f'{self.root_output_path}_{self.__class__.__name__}')
277*b7c941bbSAndroid Build Coastguard Worker    # print root_output_path so that it can be written to report log.
278*b7c941bbSAndroid Build Coastguard Worker    # Note: Do not replace print with logging.debug here.
279*b7c941bbSAndroid Build Coastguard Worker    print('root_output_path:',
280*b7c941bbSAndroid Build Coastguard Worker          f'{self.root_output_path}_{self.__class__.__name__}')
281*b7c941bbSAndroid Build Coastguard Worker
282*b7c941bbSAndroid Build Coastguard Worker
283*b7c941bbSAndroid Build Coastguard Workerclass UiAutomatorItsBaseTest(ItsBaseTest):
284*b7c941bbSAndroid Build Coastguard Worker  def setup_class(self):
285*b7c941bbSAndroid Build Coastguard Worker    super().setup_class()
286*b7c941bbSAndroid Build Coastguard Worker    self.ui_app = None
287*b7c941bbSAndroid Build Coastguard Worker    self.dut.services.register(
288*b7c941bbSAndroid Build Coastguard Worker        uiautomator.ANDROID_SERVICE_NAME, uiautomator.UiAutomatorService
289*b7c941bbSAndroid Build Coastguard Worker    )
290*b7c941bbSAndroid Build Coastguard Worker
291*b7c941bbSAndroid Build Coastguard Worker  def setup_test(self):
292*b7c941bbSAndroid Build Coastguard Worker    super().setup_test()
293*b7c941bbSAndroid Build Coastguard Worker    if not self.ui_app:
294*b7c941bbSAndroid Build Coastguard Worker      raise AssertionError(
295*b7c941bbSAndroid Build Coastguard Worker          'UiAutomator ITS tests must specify an app for UI interaction!')
296*b7c941bbSAndroid Build Coastguard Worker    its_session_utils.check_apk_installed(self.dut.serial, self.ui_app)
297