示例#1
0
 def _make_stream_transport(self):
     """Create an AdbStreamTransport with a newly allocated local_id."""
     msg_queue = Queue.Queue()
     with self._stream_transport_map_lock:
         # Start one past the last id we used, and grab the first available one.
         # This mimics the ADB behavior of 'increment an unsigned and let it
         # overflow', but with a check to ensure we don't reuse an id in use,
         # even though that's unlikely with 2^32 - 1 of them available.  We try
         # at most 64 id's, if we've wrapped around and there isn't one available
         # in the first 64, there's a problem, better to fail fast than hang for
         # a potentially very long time (STREAM_ID_LIMIT can be very large).
         self._last_id_used = (self._last_id_used % STREAM_ID_LIMIT) + 1
         for local_id in itertools.islice(
                 itertools.chain(
                     xrange(self._last_id_used, STREAM_ID_LIMIT),
                     xrange(1, self._last_id_used)), 64):
             if local_id not in self._stream_transport_map.keys():
                 self._last_id_used = local_id
                 break
         else:
             raise usb_exceptions.AdbStreamUnavailableError(
                 'Ran out of local ids!')
         # Ignore this warning - the for loop will always have at least one
         # iteration, so local_id will always be set.
         # pylint: disable=undefined-loop-variable
         stream_transport = AdbStreamTransport(self, local_id, msg_queue)
         self._stream_transport_map[local_id] = stream_transport
     return stream_transport
示例#2
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)
示例#3
0
    def async_command(self,
                      command,
                      stdin=None,
                      stdout=None,
                      raw=False,
                      timeout_ms=None):
        """Run the given command on the device asynchronously.

    Input will be read from stdin, output written to stdout.  ADB doesn't
    distinguish between stdout and stdin on the device, so they get interleaved
    into stdout here.  stdin and stdout should be file-like objects, so you
    could use sys.stdin and sys.stdout to emulate the 'adb shell' commandline.

    Args:
      command: The command to run, will be run with /bin/sh -c 'command' on
        the device.
      stdin: File-like object to read from to pipe to the command's stdin.  Can
        be None, in which case nothing will be written to the command's stdin.
      stdout: File-like object to write the command's output to.  Can be None,
        in which case the command's output will be buffered internally, and can
        be access via the return value of wait().
      raw: If True, run the command as per RawCommand (see above).
      timeout_ms: Timeout for the command, in milliseconds.

    Returns:
      An AsyncCommandHandle instance that can be used to send/receive data to
    and from the command or wait on the command to finish.

    Raises:
      AdbStreamUnavailableError: If the remote devices doesn't support the
        shell: service.
    """
        timeout = timeouts.PolledTimeout.from_millis(timeout_ms)
        if raw:
            command = self._to_raw_command(command)
        stream = self.adb_connection.open_stream('shell:%s' % command, timeout)
        if not stream:
            raise usb_exceptions.AdbStreamUnavailableError(
                '%s does not support service: shell', self)
        if raw and stdin is not None:
            # Short delay to make sure the ioctl to set raw mode happens before we do
            # any writes to the stream, if we don't do this bad things happen...
            time.sleep(.1)
        return AsyncCommandHandle(stream, stdin, stdout, timeout, raw)
示例#4
0
    def streaming_command(self, service, command='', timeout_ms=None):
        """One complete set of packets for a single command.

    Helper function to call open_stream and yield the output.  Sends
    service:command in a new connection, reading the data for the response. All
    the data is held in memory, large responses will be slow and can fill up
    memory.

    Args:
      service: The service on the device to talk to.
      command: The command to send to the service.
      timeout_ms: Timeout for the entire command, in milliseconds (or as a
        PolledTimeout object).

    Yields:
      The data contained in the responses from the service.
    """
        timeout = timeouts.PolledTimeout.from_millis(timeout_ms)
        stream = self.open_stream('%s:%s' % (service, command), timeout)
        if not stream:
            raise usb_exceptions.AdbStreamUnavailableError(
                '%s does not support service: %s', self, service)
        for data in stream.read_until_close(timeout):
            yield data