Read an AdbMessage from this transport.

    Args:
      timeout: Timeout for the entire read operation, in the form of a
        timeouts.PolledTimeout instance.  Note that for packets with a data
        payload, two USB reads are performed.

    Returns:
      The ADB message read from the device.

    Raises:
      UsbReadFailedError: There's an error during read, including timeout.
      AdbProtocolError: A message is incorrectly formatted.
      AdbTimeoutError: timeout is already expired, or expires before we read the
        entire message, specifically between reading header and data packets.

def read_message(self, timeout):
    """Read an AdbMessage from this transport.

    Args:
      timeout: Timeout for the entire read operation, in the form of a
        timeouts.PolledTimeout instance.  Note that for packets with a data
        payload, two USB reads are performed.

    Returns:
      The ADB message read from the device.

    Raises:
      UsbReadFailedError: There's an error during read, including timeout.
      AdbProtocolError: A message is incorrectly formatted.
      AdbTimeoutError: timeout is already expired, or expires before we read the
        entire message, specifically between reading header and data packets.
    """
    with self._reader_lock:
      raw_header = self._transport.read(
          struct.calcsize(AdbMessage.HEADER_STRUCT_FORMAT),
          timeout.remaining_ms)
      if not raw_header:
        raise usb_exceptions.AdbProtocolError('Adb connection lost')

      try:
        raw_message = RawAdbMessage(*struct.unpack(
            AdbMessage.HEADER_STRUCT_FORMAT, raw_header))
      except struct.error as exception:
        raise usb_exceptions.AdbProtocolError(
            'Unable to unpack ADB command (%s): %s (%s)',
            AdbMessage.HEADER_STRUCT_FORMAT, raw_header, exception)

      if raw_message.data_length > 0:
        if timeout.has_expired():
          _LOG.warning('Timed out between AdbMessage header and data, reading '
                       'data anyway with 10ms timeout')
          timeout = timeouts.PolledTimeout.from_millis(10)
        data = self._transport.read(raw_message.data_length,
                                    timeout.remaining_ms)
      else:
        data = ''

      return raw_message.to_adb_message(data)