# Copyright 2013 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.
"""Utility functions to form an ItsSession and perform various camera actions.
"""


import collections
import json
import logging
import math
import os
import socket
import subprocess
import sys
import time
import unicodedata
import unittest

import numpy

import camera_properties_utils
import capture_request_utils
import error_util
import image_processing_utils
import opencv_processing_utils

ANDROID13_API_LEVEL = 33
LOAD_SCENE_DELAY_SEC = 3
SUB_CAMERA_SEPARATOR = '.'
_VALIDATE_LIGHTING_PATCH_H = 0.05
_VALIDATE_LIGHTING_PATCH_W = 0.05
_VALIDATE_LIGHTING_REGIONS = {
    'top-left': (0, 0),
    'top-right': (0, 1-_VALIDATE_LIGHTING_PATCH_H),
    'bottom-left': (1-_VALIDATE_LIGHTING_PATCH_W, 0),
    'bottom-right': (1-_VALIDATE_LIGHTING_PATCH_W,
                     1-_VALIDATE_LIGHTING_PATCH_H),
}
_VALIDATE_LIGHTING_THRESH = 0.05  # Determined empirically from scene[1:6] tests


class ItsSession(object):
  """Controls a device over adb to run ITS scripts.

    The script importing this module (on the host machine) prepares JSON
    objects encoding CaptureRequests, specifying sets of parameters to use
    when capturing an image using the Camera2 APIs. This class encapsulates
    sending the requests to the device, monitoring the device's progress, and
    copying the resultant captures back to the host machine when done. TCP
    forwarded over adb is the transport mechanism used.

    The device must have CtsVerifier.apk installed.

    Attributes:
        sock: The open socket.
  """

  # Open a connection to localhost:<host_port>, forwarded to port 6000 on the
  # device. <host_port> is determined at run-time to support multiple
  # connected devices.
  IPADDR = '127.0.0.1'
  REMOTE_PORT = 6000
  BUFFER_SIZE = 4096

  # LOCK_PORT is used as a mutex lock to protect the list of forwarded ports
  # among all processes. The script assumes LOCK_PORT is available and will
  # try to use ports between CLIENT_PORT_START and
  # CLIENT_PORT_START+MAX_NUM_PORTS-1 on host for ITS sessions.
  CLIENT_PORT_START = 6000
  MAX_NUM_PORTS = 100
  LOCK_PORT = CLIENT_PORT_START + MAX_NUM_PORTS

  # Seconds timeout on each socket operation.
  SOCK_TIMEOUT = 20.0
  # Seconds timeout on performance measurement socket operation
  SOCK_TIMEOUT_FOR_PERF_MEASURE = 40.0

  # Additional timeout in seconds when ITS service is doing more complicated
  # operations, for example: issuing warmup requests before actual capture.
  EXTRA_SOCK_TIMEOUT = 5.0

  PACKAGE = 'com.android.cts.verifier.camera.its'
  INTENT_START = 'com.android.cts.verifier.camera.its.START'

  # This string must be in sync with ItsService. Updated when interface
  # between script and ItsService is changed.
  ITS_SERVICE_VERSION = '1.0'

  SEC_TO_NSEC = 1000*1000*1000.0
  adb = 'adb -d'

  # Predefine camera props. Save props extracted from the function,
  # "get_camera_properties".
  props = None

  IMAGE_FORMAT_LIST_1 = [
      'jpegImage', 'rawImage', 'raw10Image', 'raw12Image', 'rawStatsImage',
      'dngImage', 'y8Image'
  ]

  IMAGE_FORMAT_LIST_2 = [
      'jpegImage', 'rawImage', 'raw10Image', 'raw12Image', 'rawStatsImage',
      'yuvImage'
  ]

  CAP_JPEG = {'format': 'jpeg'}
  CAP_RAW = {'format': 'raw'}
  CAP_YUV = {'format': 'yuv'}
  CAP_RAW_YUV = [{'format': 'raw'}, {'format': 'yuv'}]

  def __init_socket_port(self):
    """Initialize the socket port for the host to forward requests to the device.

    This method assumes localhost's LOCK_PORT is available and will try to
    use ports between CLIENT_PORT_START and CLIENT_PORT_START+MAX_NUM_PORTS-1
    """
    num_retries = 100
    retry_wait_time_sec = 0.05

    # Bind a socket to use as mutex lock
    socket_lock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    for i in range(num_retries):
      try:
        socket_lock.bind((ItsSession.IPADDR, ItsSession.LOCK_PORT))
        break
      except (socket.error, socket.timeout) as socket_issue:
        if i == num_retries - 1:
          raise error_util.CameraItsError(
              self._device_id, 'socket lock returns error') from socket_issue
        else:
          time.sleep(retry_wait_time_sec)

    # Check if a port is already assigned to the device.
    command = 'adb forward --list'
    proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    # pylint: disable=unused-variable
    output, error = proc.communicate()
    port = None
    used_ports = []
    for line  in output.decode('utf-8').split(os.linesep):
      # each line should be formatted as:
      # "<device_id> tcp:<host_port> tcp:<remote_port>"
      forward_info = line.split()
      if len(forward_info) >= 3 and len(
          forward_info[1]) > 4 and forward_info[1][:4] == 'tcp:' and len(
              forward_info[2]) > 4 and forward_info[2][:4] == 'tcp:':
        local_p = int(forward_info[1][4:])
        remote_p = int(forward_info[2][4:])
        if forward_info[
            0] == self._device_id and remote_p == ItsSession.REMOTE_PORT:
          port = local_p
          break
        else:
          used_ports.append(local_p)

      # Find the first available port if no port is assigned to the device.
    if port is None:
      for p in range(ItsSession.CLIENT_PORT_START,
                     ItsSession.CLIENT_PORT_START + ItsSession.MAX_NUM_PORTS):
        if self.check_port_availability(p, used_ports):
          port = p
          break

    if port is None:
      raise error_util.CameraItsError(self._device_id,
                                      ' cannot find an available ' + 'port')

    # Release the socket as mutex unlock
    socket_lock.close()

    # Connect to the socket
    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.connect((self.IPADDR, port))
    self.sock.settimeout(self.SOCK_TIMEOUT)

  def check_port_availability(self, check_port, used_ports):
    """Check if the port is available or not.

    Args:
      check_port: Port to check for availability
      used_ports: List of used ports

    Returns:
     True if the given port is available and can be assigned to the device.
    """
    if check_port not in used_ports:
      # Try to run "adb forward" with the port
      command = ('%s forward tcp:%d tcp:%d' %
                 (self.adb, check_port, self.REMOTE_PORT))
      proc = subprocess.Popen(
          command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      error = proc.communicate()[1]

      # Check if there is no error
      if error is None or error.find('error'.encode()) < 0:
        return True
      else:
        return False

  def __wait_for_service(self):
    """Wait for ItsService to be ready and reboot the device if needed.

    This also includes the optional reboot handling: if the user
    provides a "reboot" or "reboot=N" arg, then reboot the device,
    waiting for N seconds (default 30) before returning.
    """

    for s in sys.argv[1:]:
      if s[:6] == 'reboot':
        duration = 30
        if len(s) > 7 and s[6] == '=':
          duration = int(s[7:])
        logging.debug('Rebooting device')
        _run('%s reboot' % (self.adb))
        _run('%s wait-for-device' % (self.adb))
        time.sleep(duration)
        logging.debug('Reboot complete')

    # Flush logcat so following code won't be misled by previous
    # 'ItsService ready' log.
    _run('%s logcat -c' % (self.adb))
    time.sleep(1)

    _run('%s shell am force-stop --user 0 %s' % (self.adb, self.PACKAGE))
    _run(('%s shell am start-foreground-service --user 0 -t text/plain '
          '-a %s') % (self.adb, self.INTENT_START))

    # Wait until the socket is ready to accept a connection.
    proc = subprocess.Popen(
        self.adb.split() + ['logcat'], stdout=subprocess.PIPE)
    logcat = proc.stdout
    while True:
      line = logcat.readline().strip()
      if line.find(b'ItsService ready') >= 0:
        break
    proc.kill()
    proc.communicate()

  def __init__(self, device_id=None, camera_id=None, hidden_physical_id=None):
    self._camera_id = camera_id
    self._device_id = device_id
    self._hidden_physical_id = hidden_physical_id

    # Initialize device id and adb command.
    self.adb = 'adb -s ' + self._device_id
    self.__wait_for_service()
    self.__init_socket_port()

  def __enter__(self):
    self.__close_camera()
    self.__open_camera()
    return self

  def __exit__(self, exec_type, exec_value, exec_traceback):
    if hasattr(self, 'sock') and self.sock:
      self.__close_camera()
      self.sock.close()
    return False

  def override_with_hidden_physical_camera_props(self, props):
    """Check that it is a valid sub-camera backing the logical camera.

    If current session is for a hidden physical camera, check that it is a valid
    sub-camera backing the logical camera, override self.props, and return the
    characteristics of sub-camera. Otherwise, return "props" directly.

    Args:
     props: Camera properties object.

    Returns:
     The properties of the hidden physical camera if possible.
    """
    if self._hidden_physical_id:
      if not camera_properties_utils.logical_multi_camera(props):
        raise AssertionError(f'{self._camera_id} is not a logical multi-camera')
      physical_ids = camera_properties_utils.logical_multi_camera_physical_ids(
          props)
      if self._hidden_physical_id not in physical_ids:
        raise AssertionError(f'{self._hidden_physical_id} is not a hidden '
                             f'sub-camera of {self._camera_id}')
      props = self.get_camera_properties_by_id(self._hidden_physical_id)
      self.props = props
    return props

  def get_camera_properties(self):
    """Get the camera properties object for the device.

    Returns:
     The Python dictionary object for the CameraProperties object.
    """
    cmd = {}
    cmd['cmdName'] = 'getCameraProperties'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'cameraProperties':
      raise error_util.CameraItsError('Invalid command response')
    self.props = data['objValue']['cameraProperties']
    return data['objValue']['cameraProperties']

  def get_camera_properties_by_id(self, camera_id):
    """Get the camera properties object for device with camera_id.

    Args:
     camera_id: The ID string of the camera

    Returns:
     The Python dictionary object for the CameraProperties object. Empty
     if no such device exists.
    """
    cmd = {}
    cmd['cmdName'] = 'getCameraPropertiesById'
    cmd['cameraId'] = camera_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'cameraProperties':
      raise error_util.CameraItsError('Invalid command response')
    return data['objValue']['cameraProperties']

  def __read_response_from_socket(self):
    """Reads a line (newline-terminated) string serialization of JSON object.

    Returns:
     Deserialized json obj.
    """
    chars = []
    while not chars or chars[-1] != '\n':
      ch = self.sock.recv(1).decode('utf-8')
      if not ch:
        # Socket was probably closed; otherwise don't get empty strings
        raise error_util.CameraItsError('Problem with socket on device side')
      chars.append(ch)
    line = ''.join(chars)
    jobj = json.loads(line)
    # Optionally read a binary buffer of a fixed size.
    buf = None
    if 'bufValueSize' in jobj:
      n = jobj['bufValueSize']
      buf = bytearray(n)
      view = memoryview(buf)
      while n > 0:
        nbytes = self.sock.recv_into(view, n)
        view = view[nbytes:]
        n -= nbytes
      buf = numpy.frombuffer(buf, dtype=numpy.uint8)
    return jobj, buf

  def __open_camera(self):
    """Get the camera ID to open if it is an argument as a single camera.

    This allows passing camera=# to individual tests at command line
    and camera=#,#,# or an no camera argv with tools/run_all_tests.py.
    In case the camera is a logical multi-camera, to run ITS on the
    hidden physical sub-camera, pass camera=[logical ID]:[physical ID]
    to an individual test at the command line, and same applies to multiple
    camera IDs for tools/run_all_tests.py: camera=#,#:#,#:#,#
    """
    if not self._camera_id:
      self._camera_id = 0
      for s in sys.argv[1:]:
        if s[:7] == 'camera=' and len(s) > 7:
          camera_ids = s[7:].split(',')
          camera_id_combos = parse_camera_ids(camera_ids)
          if len(camera_id_combos) == 1:
            self._camera_id = camera_id_combos[0].id
            self._hidden_physical_id = camera_id_combos[0].sub_id

    logging.debug('Opening camera: %s', self._camera_id)
    cmd = {'cmdName': 'open', 'cameraId': self._camera_id}
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'cameraOpened':
      raise error_util.CameraItsError('Invalid command response')

  def __close_camera(self):
    cmd = {'cmdName': 'close'}
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'cameraClosed':
      raise error_util.CameraItsError('Invalid command response')

  def get_sensors(self):
    """Get all sensors on the device.

    Returns:
       A Python dictionary that returns keys and booleans for each sensor.
    """
    cmd = {}
    cmd['cmdName'] = 'checkSensorExistence'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'sensorExistence':
      raise error_util.CameraItsError('Invalid response for command: %s' %
                                      cmd['cmdName'])
    return data['objValue']

  def start_sensor_events(self):
    """Start collecting sensor events on the device.

    See get_sensor_events for more info.

    Returns:
       Nothing.
    """
    cmd = {}
    cmd['cmdName'] = 'startSensorEvents'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'sensorEventsStarted':
      raise error_util.CameraItsError('Invalid response for command: %s' %
                                      cmd['cmdName'])

  def get_sensor_events(self):
    """Get a trace of all sensor events on the device.

        The trace starts when the start_sensor_events function is called. If
        the test runs for a long time after this call, then the device's
        internal memory can fill up. Calling get_sensor_events gets all events
        from the device, and then stops the device from collecting events and
        clears the internal buffer; to start again, the start_sensor_events
        call must be used again.

        Events from the accelerometer, compass, and gyro are returned; each
        has a timestamp and x,y,z values.

        Note that sensor events are only produced if the device isn't in its
        standby mode (i.e.) if the screen is on.

    Returns:
            A Python dictionary with three keys ("accel", "mag", "gyro") each
            of which maps to a list of objects containing "time","x","y","z"
            keys.
    """
    cmd = {}
    cmd['cmdName'] = 'getSensorEvents'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
    self.sock.settimeout(timeout)
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'sensorEvents':
      raise error_util.CameraItsError('Invalid response for command: %s ' %
                                      cmd['cmdName'])
    self.sock.settimeout(self.SOCK_TIMEOUT)
    return data['objValue']

  def is_hlg10_recording_supported(self, profile_id):
    """Query whether the camera device supports HLG10 video recording.

    Args:
      profile_id: int; profile id corresponding to the quality level.
    Returns:
      Boolean: True, if device supports HLG10 video recording, False in
      all other cases.
    """
    cmd = {}
    cmd['cmdName'] = 'isHLG10Supported'
    cmd['cameraId'] = self._camera_id
    cmd['profileId'] = profile_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'hlg10Response':
      raise error_util.CameraItsError('Failed to query HLG10 support')
    return data['strValue'] == 'true'

  def do_basic_recording(self, profile_id, quality, duration,
                         video_stabilization_mode=0, hlg10_enabled=False):
    """Issue a recording request and read back the video recording object.

    The recording will be done with the format specified in quality. These
    quality levels correspond to the profiles listed in CamcorderProfile.
    The duration is the time in seconds for which the video will be recorded.
    The recorded object consists of a path on the device at which the
    recorded video is saved.

    Args:
      profile_id: int; profile id corresponding to the quality level.
      quality: Video recording quality such as High, Low, VGA.
      duration: The time in seconds for which the video will be recorded.
      video_stabilization_mode: Video stabilization mode ON/OFF. Value can be
      0: 'OFF', 1: 'ON', 2: 'PREVIEW'
      hlg10_enabled: boolean: True Enable 10-bit HLG video recording, False
      record using the regular SDR profile
    Returns:
      video_recorded_object: The recorded object returned from ItsService which
      contains path at which the recording is saved on the device, quality of
      the recorded video, video size of the recorded video, video frame rate
      and 'hlg10' if 'hlg10_enabled' is set to True.
      Ex:
      VideoRecordingObject: {
        'tag': 'recordingResponse',
        'objValue': {
          'recordedOutputPath':
            '/storage/emulated/0/Android/data/com.android.cts.verifier'
            '/files/VideoITS/VID_20220324_080414_0_CIF_352x288.mp4',
          'quality': 'CIF',
          'videoFrameRate': 30,
          'videoSize': '352x288'
        }
      }
    """
    cmd = {'cmdName': 'doBasicRecording', 'cameraId': self._camera_id,
           'profileId': profile_id, 'quality': quality,
           'recordingDuration': duration,
           'videoStabilizationMode': video_stabilization_mode,
           'hlg10Enabled': hlg10_enabled}
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
    self.sock.settimeout(timeout)
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'recordingResponse':
      raise error_util.CameraItsError(
          f'Invalid response for command: {cmd["cmdName"]}')
    logging.debug('VideoRecordingObject: %s', data)
    return data['objValue']

  def do_preview_recording(self, video_size, duration, stabilize):
    """Issue a preview request and read back the preview recording object.

    The resolution of the preview and its recording will be determined by
    video_size. The duration is the time in seconds for which the preview will
    be recorded. The recorded object consists of a path on the device at
    which the recorded video is saved.

    Args:
      video_size: str; Preview resolution at which to record. ex. "1920x1080"
      duration: int; The time in seconds for which the video will be recorded.
      stabilize: boolean; Whether the preview should be stabilized or not
    Returns:
      video_recorded_object: The recorded object returned from ItsService which
      contains path at which the recording is saved on the device, quality of
      the recorded video which is always set to "preview", video size of the
      recorded video, video frame rate.
      Ex:
      VideoRecordingObject: {
        'tag': 'recordingResponse',
        'objValue': {
          'recordedOutputPath': '/storage/emulated/0/Android/data/'
                                'com.android.cts.verifier/files/VideoITS/'
                                'VID_20220324_080414_0_CIF_352x288.mp4',
          'quality': 'preview',
          'videoSize': '352x288'
        }
      }
    """

    cmd = {
        'cmdName': 'doPreviewRecording',
        'cameraId': self._camera_id,
        'videoSize': video_size,
        'recordingDuration': duration,
        'stabilize': stabilize
    }
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
    self.sock.settimeout(timeout)

    data, _ = self.__read_response_from_socket()
    logging.debug('VideoRecordingObject: %s', str(data))
    if data['tag'] != 'recordingResponse':
      raise error_util.CameraItsError(
          f'Invalid response from command{cmd["cmdName"]}')
    return data['objValue']

  def get_supported_video_qualities(self, camera_id):
    """Get all supported video qualities for this camera device.

    ie. ['480:4', '1080:6', '2160:8', '720:5', 'CIF:3', 'HIGH:1', 'LOW:0',
         'QCIF:2', 'QVGA:7']

    Args:
      camera_id: device id
    Returns:
      List of all supported video qualities and corresponding profileIds.
    """
    cmd = {}
    cmd['cmdName'] = 'getSupportedVideoQualities'
    cmd['cameraId'] = camera_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'supportedVideoQualities':
      raise error_util.CameraItsError('Invalid command response')
    return data['strValue'].split(';')[:-1]  # remove the last appended ';'

  def get_supported_preview_sizes(self, camera_id):
    """Get all supported preview resolutions for this camera device.

    ie. ['640x480', '800x600', '1280x720', '1440x1080', '1920x1080']

    Args:
      camera_id: int; device id
    Returns:
      List of all supported video resolutions in ascending order.
    """
    cmd = {
        'cmdName': 'getSupportedPreviewSizes',
        'cameraId': camera_id
    }
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
    self.sock.settimeout(timeout)
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'supportedPreviewSizes':
      raise error_util.CameraItsError('Invalid command response')
    if not data['strValue']:
      raise error_util.CameraItsError('No supported preview sizes')
    return data['strValue'].split(';')

  def do_capture_with_flash(self,
                            preview_request_start,
                            preview_request_idle,
                            still_capture_req,
                            out_surface):
    """Issue capture request with flash and read back the image and metadata.

    Captures a single image with still_capture_req as capture request
    with flash. It triggers the precapture sequence with preview request
    preview_request_start with capture intent preview by setting aePrecapture
    trigger to Start. This is followed by repeated preview requests
    preview_request_idle with aePrecaptureTrigger set to IDLE.
    Once the AE is converged, a single image is captured still_capture_req
    during which the flash must be fired.
    Note: The part where we read output data from socket is cloned from
    do_capture and will be consolidated in U.

    Args:
      preview_request_start: Preview request with aePrecaptureTrigger set to
        Start
      preview_request_idle: Preview request with aePrecaptureTrigger set to Idle
      still_capture_req: Single still capture request.
      out_surface: Specifications of the output image formats and
        sizes to use for capture.
    Returns:
      An object which contains following fields:
      * data: the image data as a numpy array of bytes.
      * width: the width of the captured image.
      * height: the height of the captured image.
      * format: image format
      * metadata: the capture result object
    """
    cmd = {}
    cmd['cmdName'] = 'doCaptureWithFlash'
    cmd['previewRequestStart'] = [preview_request_start]
    cmd['previewRequestIdle'] = [preview_request_idle]
    cmd['stillCaptureRequest'] = [still_capture_req]
    cmd['outputSurfaces'] = [out_surface]

    cam_ids = self._camera_id
    self.sock.settimeout(self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT)
    logging.debug('Capturing image with ON_AUTO_FLASH.')
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    bufs = {}
    bufs[self._camera_id] = {'jpeg': []}
    formats = ['jpeg']
    rets = []
    nbufs = 0
    mds = []
    physical_mds = []
    widths = None
    heights = None
    ncap = 1
    capture_results_returned = False
    yuv_bufs = {}
    while not capture_results_returned:
      json_obj, buf = self.__read_response_from_socket()
      if json_obj['tag'] in ItsSession.IMAGE_FORMAT_LIST_1 and buf is not None:
        fmt = json_obj['tag'][:-5]
        bufs[self._camera_id][fmt].append(buf)
        nbufs += 1
      elif json_obj['tag'] == 'captureResults':
        capture_results_returned = True
        mds.append(json_obj['objValue']['captureResult'])
        physical_mds.append(json_obj['objValue']['physicalResults'])
        outputs = json_obj['objValue']['outputs']
        widths = [out['width'] for out in outputs]
        heights = [out['height'] for out in outputs]
      else:
        tag_string = unicodedata.normalize('NFKD', json_obj['tag']).encode(
            'ascii', 'ignore')
        for x in ItsSession.IMAGE_FORMAT_LIST_2:
          x = bytes(x, encoding='utf-8')
          if tag_string.startswith(x):
            if x == b'yuvImage':
              physical_id = json_obj['tag'][len(x):]
              if physical_id in cam_ids:
                buf_size = numpy.product(buf.shape)
                yuv_bufs[physical_id][buf_size].append(buf)
                nbufs += 1
            else:
              physical_id = json_obj['tag'][len(x):]
              if physical_id in cam_ids:
                fmt = x[:-5].decode('UTF-8')
                bufs[physical_id][fmt].append(buf)
                nbufs += 1
    rets = []
    for j, fmt in enumerate(formats):
      objs = []
      if 'physicalCamera' in cmd['outputSurfaces'][j]:
        cam_id = cmd['outputSurfaces'][j]['physicalCamera']
      else:
        cam_id = self._camera_id
      for i in range(ncap):
        obj = {}
        obj['width'] = widths[j]
        obj['height'] = heights[j]
        obj['format'] = fmt
        if cam_id == self._camera_id:
          obj['metadata'] = mds[i]
        else:
          for physical_md in physical_mds[i]:
            if cam_id in physical_md:
              obj['metadata'] = physical_md[cam_id]
              break
        obj['data'] = bufs[cam_id][fmt][i]
        objs.append(obj)
      rets.append(objs if ncap > 1 else objs[0])
    self.sock.settimeout(self.SOCK_TIMEOUT)
    if len(rets) > 1 or (isinstance(rets[0], dict) and
                         isinstance(still_capture_req, list)):
      return rets
    else:
      return rets[0]

  def do_capture(self,
                 cap_request,
                 out_surfaces=None,
                 reprocess_format=None,
                 repeat_request=None):
    """Issue capture request(s), and read back the image(s) and metadata.

    The main top-level function for capturing one or more images using the
    device. Captures a single image if cap_request is a single object, and
    captures a burst if it is a list of objects.

    The optional repeat_request field can be used to assign a repeating
    request list ran in background for 3 seconds to warm up the capturing
    pipeline before start capturing. The repeat_requests will be ran on a
    640x480 YUV surface without sending any data back. The caller needs to
    make sure the stream configuration defined by out_surfaces and
    repeat_request are valid or do_capture may fail because device does not
    support such stream configuration.

    The out_surfaces field can specify the width(s), height(s), and
    format(s) of the captured image. The formats may be "yuv", "jpeg",
    "dng", "raw", "raw10", "raw12", "rawStats" or "y8". The default is a
    YUV420 frame ("yuv") corresponding to a full sensor frame.

    1. Optionally the out_surfaces field can specify physical camera id(s) if
    the current camera device is a logical multi-camera. The physical camera
    id must refer to a physical camera backing this logical camera device.
    2. Optionally The output_surfaces field can also specify the use case(s) if
    the current camera device has STREAM_USE_CASE capability.

    Note that one or more surfaces can be specified, allowing a capture to
    request images back in multiple formats (e.g.) raw+yuv, raw+jpeg,
    yuv+jpeg, raw+yuv+jpeg. If the size is omitted for a surface, the
    default is the largest resolution available for the format of that
    surface. At most one output surface can be specified for a given format,
    and raw+dng, raw10+dng, and raw+raw10 are not supported as combinations.

    If reprocess_format is not None, for each request, an intermediate
    buffer of the given reprocess_format will be captured from camera and
    the intermediate buffer will be reprocessed to the output surfaces. The
    following settings will be turned off when capturing the intermediate
    buffer and will be applied when reprocessing the intermediate buffer.
    1. android.noiseReduction.mode
    2. android.edge.mode
    3. android.reprocess.effectiveExposureFactor

    Supported reprocess format are "yuv" and "private". Supported output
    surface formats when reprocessing is enabled are "yuv" and "jpeg".

    Example of a single capture request:

    {
     "android.sensor.exposureTime": 100*1000*1000,
     "android.sensor.sensitivity": 100
    }

    Example of a list of capture requests:
    [
     {
       "android.sensor.exposureTime": 100*1000*1000,
       "android.sensor.sensitivity": 100
     },
    {
      "android.sensor.exposureTime": 100*1000*1000,
       "android.sensor.sensitivity": 200
     }
    ]

    Example of output surface specifications:
    {
     "width": 640,
     "height": 480,
     "format": "yuv"
    }
    [
     {
       "format": "jpeg"
     },
     {
       "format": "raw"
     }
    ]

    The following variables defined in this class are shortcuts for
    specifying one or more formats where each output is the full size for
    that format; they can be used as values for the out_surfaces arguments:

    CAP_RAW
    CAP_DNG
    CAP_YUV
    CAP_JPEG
    CAP_RAW_YUV
    CAP_DNG_YUV
    CAP_RAW_JPEG
    CAP_DNG_JPEG
    CAP_YUV_JPEG
    CAP_RAW_YUV_JPEG
    CAP_DNG_YUV_JPEG

    If multiple formats are specified, then this function returns multiple
    capture objects, one for each requested format. If multiple formats and
    multiple captures (i.e. a burst) are specified, then this function
    returns multiple lists of capture objects. In both cases, the order of
    the returned objects matches the order of the requested formats in the
    out_surfaces parameter. For example:

    yuv_cap = do_capture(req1)
    yuv_cap = do_capture(req1,yuv_fmt)
    yuv_cap, raw_cap = do_capture(req1, [yuv_fmt,raw_fmt])
    yuv_caps = do_capture([req1,req2], yuv_fmt)
    yuv_caps, raw_caps = do_capture([req1,req2], [yuv_fmt,raw_fmt])

    The "rawStats" format processes the raw image and returns a new image
    of statistics from the raw image. The format takes additional keys,
    "gridWidth" and "gridHeight" which are size of grid cells in a 2D grid
    of the raw image. For each grid cell, the mean and variance of each raw
    channel is computed, and the do_capture call returns two 4-element float
    images of dimensions (rawWidth / gridWidth, rawHeight / gridHeight),
    concatenated back-to-back, where the first image contains the 4-channel
    means and the second contains the 4-channel variances. Note that only
    pixels in the active array crop region are used; pixels outside this
    region (for example optical black rows) are cropped out before the
    gridding and statistics computation is performed.

    For the rawStats format, if the gridWidth is not provided then the raw
    image width is used as the default, and similarly for gridHeight. With
    this, the following is an example of a output description that computes
    the mean and variance across each image row:
    {
      "gridHeight": 1,
      "format": "rawStats"
    }

    Args:
      cap_request: The Python dict/list specifying the capture(s), which will be
        converted to JSON and sent to the device.
      out_surfaces: (Optional) specifications of the output image formats and
        sizes to use for each capture.
      reprocess_format: (Optional) The reprocessing format. If not
        None,reprocessing will be enabled.
      repeat_request: Repeating request list.

    Returns:
      An object, list of objects, or list of lists of objects, where each
      object contains the following fields:
      * data: the image data as a numpy array of bytes.
      * width: the width of the captured image.
      * height: the height of the captured image.
      * format: image the format, in [
                        "yuv","jpeg","raw","raw10","raw12","rawStats","dng"].
      * metadata: the capture result object (Python dictionary).
    """
    cmd = {}
    if reprocess_format is not None:
      if repeat_request is not None:
        raise error_util.CameraItsError(
            'repeating request + reprocessing is not supported')
      cmd['cmdName'] = 'doReprocessCapture'
      cmd['reprocessFormat'] = reprocess_format
    else:
      cmd['cmdName'] = 'doCapture'

    if repeat_request is None:
      cmd['repeatRequests'] = []
    elif not isinstance(repeat_request, list):
      cmd['repeatRequests'] = [repeat_request]
    else:
      cmd['repeatRequests'] = repeat_request

    if not isinstance(cap_request, list):
      cmd['captureRequests'] = [cap_request]
    else:
      cmd['captureRequests'] = cap_request

    if out_surfaces is not None:
      if not isinstance(out_surfaces, list):
        cmd['outputSurfaces'] = [out_surfaces]
      else:
        cmd['outputSurfaces'] = out_surfaces
      formats = [
          c['format'] if 'format' in c else 'yuv' for c in cmd['outputSurfaces']
      ]
      formats = [s if s != 'jpg' else 'jpeg' for s in formats]
    else:
      max_yuv_size = capture_request_utils.get_available_output_sizes(
          'yuv', self.props)[0]
      formats = ['yuv']
      cmd['outputSurfaces'] = [{
          'format': 'yuv',
          'width': max_yuv_size[0],
          'height': max_yuv_size[1]
      }]

    ncap = len(cmd['captureRequests'])
    nsurf = 1 if out_surfaces is None else len(cmd['outputSurfaces'])

    cam_ids = []
    bufs = {}
    yuv_bufs = {}
    for i, s in enumerate(cmd['outputSurfaces']):
      if self._hidden_physical_id:
        s['physicalCamera'] = self._hidden_physical_id

      if 'physicalCamera' in s:
        cam_id = s['physicalCamera']
      else:
        cam_id = self._camera_id

      if cam_id not in cam_ids:
        cam_ids.append(cam_id)
        bufs[cam_id] = {
            'raw': [],
            'raw10': [],
            'raw12': [],
            'rawStats': [],
            'dng': [],
            'jpeg': [],
            'y8': []
        }

    for cam_id in cam_ids:
       # Only allow yuv output to multiple targets
      if cam_id == self._camera_id:
        yuv_surfaces = [
            s for s in cmd['outputSurfaces']
            if s['format'] == 'yuv' and 'physicalCamera' not in s
        ]
        formats_for_id = [
            s['format']
            for s in cmd['outputSurfaces']
            if 'physicalCamera' not in s
        ]
      else:
        yuv_surfaces = [
            s for s in cmd['outputSurfaces'] if s['format'] == 'yuv' and
            'physicalCamera' in s and s['physicalCamera'] == cam_id
        ]
        formats_for_id = [
            s['format']
            for s in cmd['outputSurfaces']
            if 'physicalCamera' in s and s['physicalCamera'] == cam_id
        ]

      n_yuv = len(yuv_surfaces)
      # Compute the buffer size of YUV targets
      yuv_maxsize_1d = 0
      for s in yuv_surfaces:
        if ('width' not in s and 'height' not in s):
          if self.props is None:
            raise error_util.CameraItsError('Camera props are unavailable')
          yuv_maxsize_2d = capture_request_utils.get_available_output_sizes(
              'yuv', self.props)[0]
          # YUV420 size = 1.5 bytes per pixel
          yuv_maxsize_1d = (yuv_maxsize_2d[0] * yuv_maxsize_2d[1] * 3) // 2
          break
      yuv_sizes = [
          (c['width'] * c['height'] * 3) // 2
          if 'width' in c and 'height' in c else yuv_maxsize_1d
          for c in yuv_surfaces
      ]
      # Currently we don't pass enough metadta from ItsService to distinguish
      # different yuv stream of same buffer size
      if len(yuv_sizes) != len(set(yuv_sizes)):
        raise error_util.CameraItsError(
            'ITS does not support yuv outputs of same buffer size')
      if len(formats_for_id) > len(set(formats_for_id)):
        if n_yuv != len(formats_for_id) - len(set(formats_for_id)) + 1:
          raise error_util.CameraItsError('Duplicate format requested')

      yuv_bufs[cam_id] = {size: [] for size in yuv_sizes}

    raw_formats = 0
    raw_formats += 1 if 'dng' in formats else 0
    raw_formats += 1 if 'raw' in formats else 0
    raw_formats += 1 if 'raw10' in formats else 0
    raw_formats += 1 if 'raw12' in formats else 0
    raw_formats += 1 if 'rawStats' in formats else 0
    if raw_formats > 1:
      raise error_util.CameraItsError('Different raw formats not supported')

    # Detect long exposure time and set timeout accordingly
    longest_exp_time = 0
    for req in cmd['captureRequests']:
      if 'android.sensor.exposureTime' in req and req[
          'android.sensor.exposureTime'] > longest_exp_time:
        longest_exp_time = req['android.sensor.exposureTime']

    extended_timeout = longest_exp_time // self.SEC_TO_NSEC + self.SOCK_TIMEOUT
    if repeat_request:
      extended_timeout += self.EXTRA_SOCK_TIMEOUT
    self.sock.settimeout(extended_timeout)

    logging.debug('Capturing %d frame%s with %d format%s [%s]', ncap,
                  's' if ncap > 1 else '', nsurf, 's' if nsurf > 1 else '',
                  ','.join(formats))
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    # Wait for ncap*nsurf images and ncap metadata responses.
    # Assume that captures come out in the same order as requested in
    # the burst, however individual images of different formats can come
    # out in any order for that capture.
    nbufs = 0
    mds = []
    physical_mds = []
    widths = None
    heights = None
    while nbufs < ncap * nsurf or len(mds) < ncap:
      json_obj, buf = self.__read_response_from_socket()
      if json_obj['tag'] in ItsSession.IMAGE_FORMAT_LIST_1 and buf is not None:
        fmt = json_obj['tag'][:-5]
        bufs[self._camera_id][fmt].append(buf)
        nbufs += 1
      elif json_obj['tag'] == 'yuvImage':
        buf_size = numpy.product(buf.shape)
        yuv_bufs[self._camera_id][buf_size].append(buf)
        nbufs += 1
      elif json_obj['tag'] == 'captureResults':
        mds.append(json_obj['objValue']['captureResult'])
        physical_mds.append(json_obj['objValue']['physicalResults'])
        outputs = json_obj['objValue']['outputs']
        widths = [out['width'] for out in outputs]
        heights = [out['height'] for out in outputs]
      else:
        tag_string = unicodedata.normalize('NFKD', json_obj['tag']).encode(
            'ascii', 'ignore')
        for x in ItsSession.IMAGE_FORMAT_LIST_2:
          x = bytes(x, encoding='utf-8')
          if tag_string.startswith(x):
            if x == b'yuvImage':
              physical_id = json_obj['tag'][len(x):]
              if physical_id in cam_ids:
                buf_size = numpy.product(buf.shape)
                yuv_bufs[physical_id][buf_size].append(buf)
                nbufs += 1
            else:
              physical_id = json_obj['tag'][len(x):]
              if physical_id in cam_ids:
                fmt = x[:-5].decode('UTF-8')
                bufs[physical_id][fmt].append(buf)
                nbufs += 1
    rets = []
    for j, fmt in enumerate(formats):
      objs = []
      if 'physicalCamera' in cmd['outputSurfaces'][j]:
        cam_id = cmd['outputSurfaces'][j]['physicalCamera']
      else:
        cam_id = self._camera_id

      for i in range(ncap):
        obj = {}
        obj['width'] = widths[j]
        obj['height'] = heights[j]
        obj['format'] = fmt
        if cam_id == self._camera_id:
          obj['metadata'] = mds[i]
        else:
          for physical_md in physical_mds[i]:
            if cam_id in physical_md:
              obj['metadata'] = physical_md[cam_id]
              break

        if fmt == 'yuv':
          buf_size = (widths[j] * heights[j] * 3) // 2
          obj['data'] = yuv_bufs[cam_id][buf_size][i]
        else:
          obj['data'] = bufs[cam_id][fmt][i]
        objs.append(obj)
      rets.append(objs if ncap > 1 else objs[0])
    self.sock.settimeout(self.SOCK_TIMEOUT)
    if len(rets) > 1 or (isinstance(rets[0], dict) and
                         isinstance(cap_request, list)):
      return rets
    else:
      return rets[0]

  def do_vibrate(self, pattern):
    """Cause the device to vibrate to a specific pattern.

    Args:
      pattern: Durations (ms) for which to turn on or off the vibrator.
      The first value indicates the number of milliseconds to wait
      before turning the vibrator on. The next value indicates the
      number of milliseconds for which to keep the vibrator on
      before turning it off. Subsequent values alternate between
      durations in milliseconds to turn the vibrator off or to turn
      the vibrator on.

    Returns:
      Nothing.
    """
    cmd = {}
    cmd['cmdName'] = 'doVibrate'
    cmd['pattern'] = pattern
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'vibrationStarted':
      raise error_util.CameraItsError('Invalid response for command: %s' %
                                      cmd['cmdName'])

  def set_audio_restriction(self, mode):
    """Set the audio restriction mode for this camera device.

    Args:
     mode: int; the audio restriction mode. See CameraDevice.java for valid
     value.
    Returns:
     Nothing.
    """
    cmd = {}
    cmd['cmdName'] = 'setAudioRestriction'
    cmd['mode'] = mode
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())
    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'audioRestrictionSet':
      raise error_util.CameraItsError('Invalid response for command: %s' %
                                      cmd['cmdName'])

  # pylint: disable=dangerous-default-value
  def do_3a(self,
            regions_ae=[[0, 0, 1, 1, 1]],
            regions_awb=[[0, 0, 1, 1, 1]],
            regions_af=[[0, 0, 1, 1, 1]],
            do_ae=True,
            do_awb=True,
            do_af=True,
            lock_ae=False,
            lock_awb=False,
            get_results=False,
            ev_comp=0,
            auto_flash=False,
            mono_camera=False):
    """Perform a 3A operation on the device.

    Triggers some or all of AE, AWB, and AF, and returns once they have
    converged. Uses the vendor 3A that is implemented inside the HAL.
    Note: do_awb is always enabled regardless of do_awb flag

    Throws an assertion if 3A fails to converge.

    Args:
      regions_ae: List of weighted AE regions.
      regions_awb: List of weighted AWB regions.
      regions_af: List of weighted AF regions.
      do_ae: Trigger AE and wait for it to converge.
      do_awb: Wait for AWB to converge.
      do_af: Trigger AF and wait for it to converge.
      lock_ae: Request AE lock after convergence, and wait for it.
      lock_awb: Request AWB lock after convergence, and wait for it.
      get_results: Return the 3A results from this function.
      ev_comp: An EV compensation value to use when running AE.
      auto_flash: AE control boolean to enable auto flash.
      mono_camera: Boolean for monochrome camera.

      Region format in args:
         Arguments are lists of weighted regions; each weighted region is a
         list of 5 values, [x, y, w, h, wgt], and each argument is a list of
         these 5-value lists. The coordinates are given as normalized
         rectangles (x, y, w, h) specifying the region. For example:
         [[0.0, 0.0, 1.0, 0.5, 5], [0.0, 0.5, 1.0, 0.5, 10]].
         Weights are non-negative integers.

    Returns:
      Five values are returned if get_results is true:
      * AE sensitivity; None if do_ae is False
      * AE exposure time; None if do_ae is False
      * AWB gains (list);
      * AWB transform (list);
      * AF focus position; None if do_af is false
      Otherwise, it returns five None values.
    """
    logging.debug('Running vendor 3A on device')
    cmd = {}
    cmd['cmdName'] = 'do3A'
    cmd['regions'] = {
        'ae': sum(regions_ae, []),
        'awb': sum(regions_awb, []),
        'af': sum(regions_af, [])
    }
    cmd['triggers'] = {'ae': do_ae, 'af': do_af}
    if lock_ae:
      cmd['aeLock'] = True
    if lock_awb:
      cmd['awbLock'] = True
    if ev_comp != 0:
      cmd['evComp'] = ev_comp
    if auto_flash:
      cmd['autoFlash'] = True
    if self._hidden_physical_id:
      cmd['physicalId'] = self._hidden_physical_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    # Wait for each specified 3A to converge.
    ae_sens = None
    ae_exp = None
    awb_gains = None
    awb_transform = None
    af_dist = None
    converged = False
    while True:
      data, _ = self.__read_response_from_socket()
      vals = data['strValue'].split()
      if data['tag'] == 'aeResult':
        if do_ae:
          ae_sens, ae_exp = [int(i) for i in vals]
      elif data['tag'] == 'afResult':
        if do_af:
          af_dist = float(vals[0])
      elif data['tag'] == 'awbResult':
        awb_gains = [float(f) for f in vals[:4]]
        awb_transform = [float(f) for f in vals[4:]]
      elif data['tag'] == '3aConverged':
        converged = True
      elif data['tag'] == '3aDone':
        break
      else:
        raise error_util.CameraItsError('Invalid command response')
    if converged and not get_results:
      return None, None, None, None, None
    if (do_ae and ae_sens is None or
        (not mono_camera and do_awb and awb_gains is None) or
        do_af and af_dist is None or not converged):
      raise error_util.CameraItsError('3A failed to converge')
    return ae_sens, ae_exp, awb_gains, awb_transform, af_dist

  def calc_camera_fov(self, props):
    """Determine the camera field of view from internal params.

    Args:
      props: Camera properties object.

    Returns:
      camera_fov: string; field of view for camera.
    """

    focal_ls = props['android.lens.info.availableFocalLengths']
    if len(focal_ls) > 1:
      logging.debug('Doing capture to determine logical camera focal length')
      cap = self.do_capture(capture_request_utils.auto_capture_request())
      focal_l = cap['metadata']['android.lens.focalLength']
    else:
      focal_l = focal_ls[0]

    sensor_size = props['android.sensor.info.physicalSize']
    diag = math.sqrt(sensor_size['height']**2 + sensor_size['width']**2)
    try:
      fov = str(round(2 * math.degrees(math.atan(diag / (2 * focal_l))), 2))
    except ValueError:
      fov = str(0)
    logging.debug('Calculated FoV: %s', fov)
    return fov

  def get_file_name_to_load(self, chart_distance, camera_fov, scene):
    """Get the image to load on the tablet depending on fov and chart_distance.

    Args:
     chart_distance: float; distance in cm from camera of displayed chart
     camera_fov: float; camera field of view.
     scene: String; Scene to be used in the test.

    Returns:
     file_name: file name to display on the tablet.

    """
    chart_scaling = opencv_processing_utils.calc_chart_scaling(
        chart_distance, camera_fov)
    if numpy.isclose(
        chart_scaling,
        opencv_processing_utils.SCALE_RFOV_IN_WFOV_BOX,
        atol=0.01):
      file_name = '%s_%sx_scaled.png' % (
          scene, str(opencv_processing_utils.SCALE_RFOV_IN_WFOV_BOX))
    elif numpy.isclose(
        chart_scaling,
        opencv_processing_utils.SCALE_TELE_IN_WFOV_BOX,
        atol=0.01):
      file_name = '%s_%sx_scaled.png' % (
          scene, str(opencv_processing_utils.SCALE_TELE_IN_WFOV_BOX))
    elif numpy.isclose(
        chart_scaling,
        opencv_processing_utils.SCALE_TELE25_IN_RFOV_BOX,
        atol=0.01):
      file_name = '%s_%sx_scaled.png' % (
          scene, str(opencv_processing_utils.SCALE_TELE25_IN_RFOV_BOX))
    elif numpy.isclose(
        chart_scaling,
        opencv_processing_utils.SCALE_TELE40_IN_RFOV_BOX,
        atol=0.01):
      file_name = '%s_%sx_scaled.png' % (
          scene, str(opencv_processing_utils.SCALE_TELE40_IN_RFOV_BOX))
    elif numpy.isclose(
        chart_scaling,
        opencv_processing_utils.SCALE_TELE_IN_RFOV_BOX,
        atol=0.01):
      file_name = '%s_%sx_scaled.png' % (
          scene, str(opencv_processing_utils.SCALE_TELE_IN_RFOV_BOX))
    else:
      file_name = '%s.png' % scene
    logging.debug('Scene to load: %s', file_name)
    return file_name

  def is_stream_combination_supported(self, out_surfaces):
    """Query whether out_surfaces combination is supported by the camera device.

    This function hooks up to the isSessionConfigurationSupported() camera API
    to query whether a particular stream combination is supported.

    Args:
      out_surfaces: dict; see do_capture() for specifications on out_surfaces

    Returns:
      Boolean
    """
    cmd = {}
    cmd['cmdName'] = 'isStreamCombinationSupported'

    if not isinstance(out_surfaces, list):
      cmd['outputSurfaces'] = [out_surfaces]
    else:
      cmd['outputSurfaces'] = out_surfaces
    formats = [c['format'] if 'format' in c else 'yuv'
               for c in cmd['outputSurfaces']]
    formats = [s if s != 'jpg' else 'jpeg' for s in formats]

    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'streamCombinationSupport':
      raise error_util.CameraItsError('Failed to query stream combination')

    return data['strValue'] == 'supportedCombination'

  def is_camera_privacy_mode_supported(self):
    """Query whether the mobile device supports camera privacy mode.

    This function checks whether the mobile device has FEATURE_CAMERA_TOGGLE
    feature support, which indicates the camera device can run in privacy mode.

    Returns:
      Boolean
    """
    cmd = {}
    cmd['cmdName'] = 'isCameraPrivacyModeSupported'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'cameraPrivacyModeSupport':
      raise error_util.CameraItsError('Failed to query camera privacy mode'
                                      ' support')
    return data['strValue'] == 'true'

  def is_primary_camera(self):
    """Query whether the camera device is a primary rear/front camera.

    A primary rear/front facing camera is a camera device with the lowest
    camera Id for that facing.

    Returns:
      Boolean
    """
    cmd = {}
    cmd['cmdName'] = 'isPrimaryCamera'
    cmd['cameraId'] = self._camera_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'primaryCamera':
      raise error_util.CameraItsError('Failed to query primary camera')
    return data['strValue'] == 'true'

  def is_performance_class(self):
    """Query whether the mobile device is an R or S performance class device.

    Returns:
      Boolean
    """
    cmd = {}
    cmd['cmdName'] = 'isPerformanceClass'
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    data, _ = self.__read_response_from_socket()
    if data['tag'] != 'performanceClass':
      raise error_util.CameraItsError('Failed to query performance class')
    return data['strValue'] == 'true'

  def measure_camera_launch_ms(self):
    """Measure camera launch latency in millisecond, from open to first frame.

    Returns:
      Camera launch latency from camera open to receipt of first frame
    """
    cmd = {}
    cmd['cmdName'] = 'measureCameraLaunchMs'
    cmd['cameraId'] = self._camera_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
    self.sock.settimeout(timeout)
    data, _ = self.__read_response_from_socket()
    self.sock.settimeout(self.SOCK_TIMEOUT)

    if data['tag'] != 'cameraLaunchMs':
      raise error_util.CameraItsError('Failed to measure camera launch latency')
    return float(data['strValue'])

  def measure_camera_1080p_jpeg_capture_ms(self):
    """Measure camera 1080P jpeg capture latency in milliseconds.

    Returns:
      Camera jpeg capture latency in milliseconds
    """
    cmd = {}
    cmd['cmdName'] = 'measureCamera1080pJpegCaptureMs'
    cmd['cameraId'] = self._camera_id
    self.sock.send(json.dumps(cmd).encode() + '\n'.encode())

    timeout = self.SOCK_TIMEOUT_FOR_PERF_MEASURE
    self.sock.settimeout(timeout)
    data, _ = self.__read_response_from_socket()
    self.sock.settimeout(self.SOCK_TIMEOUT)

    if data['tag'] != 'camera1080pJpegCaptureMs':
      raise error_util.CameraItsError(
          'Failed to measure camera 1080p jpeg capture latency')
    return float(data['strValue'])


def parse_camera_ids(ids):
  """Parse the string of camera IDs into array of CameraIdCombo tuples.

  Args:
   ids: List of camera ids.

  Returns:
   Array of CameraIdCombo
  """
  camera_id_combo = collections.namedtuple('CameraIdCombo', ['id', 'sub_id'])
  id_combos = []
  for one_id in ids:
    one_combo = one_id.split(SUB_CAMERA_SEPARATOR)
    if len(one_combo) == 1:
      id_combos.append(camera_id_combo(one_combo[0], None))
    elif len(one_combo) == 2:
      id_combos.append(camera_id_combo(one_combo[0], one_combo[1]))
    else:
      raise AssertionError('Camera id parameters must be either ID or '
                           f'ID{SUB_CAMERA_SEPARATOR}SUB_ID')
  return id_combos


def _run(cmd):
  """Replacement for os.system, with hiding of stdout+stderr messages.

  Args:
    cmd: Command to be executed in string format.
  """
  with open(os.devnull, 'wb') as devnull:
    subprocess.check_call(cmd.split(), stdout=devnull, stderr=subprocess.STDOUT)


def do_capture_with_latency(cam, req, sync_latency, fmt=None):
  """Helper function to take enough frames to allow sync latency.

  Args:
    cam: camera object
    req: request for camera
    sync_latency: integer number of frames
    fmt: format for the capture
  Returns:
    single capture with the unsettled frames discarded
  """
  caps = cam.do_capture([req]*(sync_latency+1), fmt)
  return caps[-1]


def load_scene(cam, props, scene, tablet, chart_distance, lighting_check=True):
  """Load the scene for the camera based on the FOV.

  Args:
    cam: camera object
    props: camera properties
    scene: scene to be loaded
    tablet: tablet to load scene on
    chart_distance: distance to tablet
    lighting_check: Boolean for lighting check enabled
  """
  if not tablet:
    logging.info('Manual run: no tablet to load scene on.')
    return
  # Calculate camera_fov which will determine the image to load on tablet.
  camera_fov = cam.calc_camera_fov(props)
  file_name = cam.get_file_name_to_load(chart_distance, camera_fov, scene)
  logging.debug('Displaying %s on the tablet', file_name)
  # Display the scene on the tablet depending on camera_fov
  tablet.adb.shell(
      'am start -a android.intent.action.VIEW -t image/png '
      f'-d file://mnt/sdcard/Download/{file_name}')
  time.sleep(LOAD_SCENE_DELAY_SEC)
  rfov_camera_in_rfov_box = (
      numpy.isclose(
          chart_distance,
          opencv_processing_utils.CHART_DISTANCE_RFOV, rtol=0.1) and
      opencv_processing_utils.FOV_THRESH_TELE <= float(camera_fov)
      <= opencv_processing_utils.FOV_THRESH_WFOV)
  wfov_camera_in_wfov_box = (
      numpy.isclose(
          chart_distance,
          opencv_processing_utils.CHART_DISTANCE_WFOV, rtol=0.1) and
      float(camera_fov) > opencv_processing_utils.FOV_THRESH_WFOV)
  if (rfov_camera_in_rfov_box or wfov_camera_in_wfov_box) and lighting_check:
    cam.do_3a()
    cap = cam.do_capture(
        capture_request_utils.auto_capture_request(), cam.CAP_YUV)
    y_plane, _, _ = image_processing_utils.convert_capture_to_planes(cap)
    validate_lighting(y_plane, scene)


def validate_lighting(y_plane, scene, state='ON'):
  """Validates the lighting level in scene corners based on empirical values.

  Args:
    y_plane: Y plane of YUV image
    scene: scene name
    state: string 'ON' or 'OFF'

  Returns:
    boolean True if lighting validated, else raise AssertionError
  """
  logging.debug('Validating lighting levels.')

  # Test patches from each corner.
  for location, coordinates in _VALIDATE_LIGHTING_REGIONS.items():
    patch = image_processing_utils.get_image_patch(
        y_plane, coordinates[0], coordinates[1],
        _VALIDATE_LIGHTING_PATCH_W, _VALIDATE_LIGHTING_PATCH_H)
    y_mean = image_processing_utils.compute_image_means(patch)[0]
    logging.debug('%s corner Y mean: %.3f', location, y_mean)
    if state == 'ON':
      if y_mean > _VALIDATE_LIGHTING_THRESH:
        logging.debug('Lights ON in test rig.')
        return True
      else:
        image_processing_utils.write_image(
            y_plane, f'validate_lighting_{scene}.jpg')
        raise AssertionError('Lights OFF in test rig. Turn ON and retry.')
    elif state == 'OFF':
      if y_mean < _VALIDATE_LIGHTING_THRESH:
        logging.debug('Lights OFF in test rig.')
        return True
      else:
        image_processing_utils.write_image(
            y_plane, f'validate_lighting_{scene}.jpg')
        raise AssertionError('Lights ON in test rig. Turn OFF and retry.')
    else:
      raise AssertionError('Invalid lighting state string. '
                           "Valid strings: 'ON', 'OFF'.")


def get_build_sdk_version(device_id):
  """Return the int build version of the device."""
  cmd = 'adb -s %s shell getprop ro.build.version.sdk' % device_id
  try:
    build_sdk_version = int(subprocess.check_output(cmd.split()).rstrip())
    logging.debug('Build SDK version: %d', build_sdk_version)
  except (subprocess.CalledProcessError, ValueError) as exp_errors:
    raise AssertionError('No build_sdk_version.') from exp_errors
  return build_sdk_version


def get_first_api_level(device_id):
  """Return the int value for the first API level of the device."""
  cmd = 'adb -s %s shell getprop ro.product.first_api_level' % device_id
  try:
    first_api_level = int(subprocess.check_output(cmd.split()).rstrip())
    logging.debug('First API level: %d', first_api_level)
  except (subprocess.CalledProcessError, ValueError):
    logging.error('No first_api_level. Setting to build version.')
    first_api_level = get_build_sdk_version(device_id)
  return first_api_level


class ItsSessionUtilsTests(unittest.TestCase):
  """Run a suite of unit tests on this module."""

  _BRIGHTNESS_CHECKS = (0.0,
                        _VALIDATE_LIGHTING_THRESH-0.01,
                        _VALIDATE_LIGHTING_THRESH,
                        _VALIDATE_LIGHTING_THRESH+0.01,
                        1.0)
  _TEST_IMG_W = 640
  _TEST_IMG_H = 480

  def _generate_test_image(self, brightness):
    """Creates a Y plane array with pixel values of brightness.

    Args:
      brightness: float between [0.0, 1.0]

    Returns:
      Y plane array with elements of value brightness
    """
    test_image = numpy.zeros((self._TEST_IMG_W, self._TEST_IMG_H, 1),
                             dtype=float)
    test_image.fill(brightness)
    return test_image

  def test_validate_lighting(self):
    """Tests validate_lighting() works correctly."""
    # Run with different brightnesses to validate.
    for brightness in self._BRIGHTNESS_CHECKS:
      logging.debug('Testing validate_lighting with brightness %.1f',
                    brightness)
      test_image = self._generate_test_image(brightness)
      print(f'Testing brightness: {brightness}')
      if brightness <= _VALIDATE_LIGHTING_THRESH:
        self.assertRaises(
            AssertionError, validate_lighting, test_image, 'unittest')
      else:
        self.assertTrue(validate_lighting(test_image, 'unittest'),
                        f'image value {brightness} should PASS')


if __name__ == '__main__':
  unittest.main()
