Beispiel #1
0
  def _check_remote_command(self, destination, timeout_ms, success_msgs=None):
    """Open a stream to destination, check for remote errors.

    Used for reboot, remount, and root services.  If this method returns, the
    command was successful, otherwise an appropriate error will have been
    raised.

    Args:
      destination: Stream destination to open.
      timeout_ms: Timeout in milliseconds for the operation.
      success_msgs: If provided, a list of messages that, if returned from the
        device, indicate success, so don't treat them as errors.

    Raises:
      AdbRemoteError: If the remote command fails, will contain any message we
        got back from the device.
      AdbStreamUnavailableError: The service requested isn't supported.
    """
    timeout = timeouts.PolledTimeout.from_millis(timeout_ms)
    stream = self._adb_connection.open_stream(destination, timeout)
    if not stream:
      raise usb_exceptions.AdbStreamUnavailableError(
          'Service %s not supported', destination)
    try:
      message = stream.read(timeout_ms=timeout)
      # Some commands report success messages, ignore them.
      if any([m in message for m in success_msgs]):
        return
    except usb_exceptions.CommonUsbError:
      if destination.startswith('reboot:'):
        # We expect this if the device is rebooting.
        return
      raise
    raise usb_exceptions.AdbRemoteError('Device message: %s', message)
    def read_message(self, timeout=None):
        """Read a message from this transport and return it.

    Reads a message of RECV_MSG_TYPE and returns it.  Note that this method
    abstracts the data length and data read so that the caller simply gets the
    data along with the header in the returned message.

    Args:
      timeout: timeouts.PolledTimeout to use for the operation.

    Returns:
      An instance of self.RECV_MSG_TYPE that was read from self.stream.

    Raises:
      AdbProtocolError: If an invalid response is received.
      AdbRemoteError: If a FAIL response is received.
    """
        raw_data = self.stream.read(
            struct.calcsize(self.RECV_MSG_TYPE.struct_format), timeout)
        try:
            raw_message = struct.unpack(self.RECV_MSG_TYPE.struct_format,
                                        raw_data)
        except struct.error:
            raise usb_exceptions.AdbProtocolError(
                '%s expected format "%s", got data %s' %
                (self, self.RECV_MSG_TYPE.struct_format, raw_data))

        if raw_message[0] not in self.WIRE_TO_CMD:
            raise usb_exceptions.AdbProtocolError(
                'Unrecognized command id: %s' % raw_message)

        # Swap out the wire command with the string equivalent.
        raw_message = (self.WIRE_TO_CMD[raw_message[0]], ) + raw_message[1:]

        if self.RECV_MSG_TYPE.has_data and raw_message[-1]:
            # For messages that have data, the length of the data is the last field
            # in the struct.  We do another read and swap out that length for the
            # actual data read before we create the namedtuple to return.
            data_len = raw_message[-1]
            raw_message = raw_message[:-1] + (self.stream.read(
                data_len, timeout), )

        if raw_message[0] not in self.VALID_RESPONSES:
            raise usb_exceptions.AdbProtocolError(
                '%s not a valid response for %s' % (raw_message[0], self))
        if raw_message[0] == 'FAIL':
            raise usb_exceptions.AdbRemoteError('Remote ADB failure: %s' %
                                                raw_message)
        return self.RECV_MSG_TYPE(*raw_message)