예제 #1
0
    def create_ssh_tunnel(self, port, local_port=None):
        """Create an ssh tunnel from local_port to port.

        This securely forwards traffic from local_port on this machine to the
        remote SSH host at port.

        Args:
            port: remote port on the host.
            local_port: local forwarding port, or None to pick an available
                        port.

        Returns:
            the created tunnel process.
        """
        if local_port is None:
            local_port = host_utils.get_available_host_port()
        else:
            for tunnel in self._tunnels:
                if tunnel.remote_port == port:
                    return tunnel.local_port

        extra_flags = {
            '-n': None,  # Read from /dev/null for stdin
            '-N': None,  # Do not execute a remote command
            '-q': None,  # Suppress warnings and diagnostic commands
            '-L': '%d:localhost:%d' % (local_port, port),
        }
        extra_options = dict()
        if self._master_ssh_proc:
            extra_options['ControlPath'] = self.socket_path
        tunnel_cmd = self._formatter.format_ssh_local_command(
            self._settings,
            extra_flags=extra_flags,
            extra_options=extra_options)
        self.log.debug('Full tunnel command: %s', tunnel_cmd)
        # Exec the ssh process directly so that when we deliver signals, we
        # deliver them straight to the child process.
        tunnel_proc = job.run_async(tunnel_cmd)
        self.log.debug(
            'Started ssh tunnel, local = %d'
            ' remote = %d, pid = %d', local_port, port, tunnel_proc.pid)
        self._tunnels.append(_Tunnel(local_port, port, tunnel_proc))
        return local_port
예제 #2
0
    def get_droid(self, handle_event=True):
        """Create an sl4n connection to the device.

        Return the connection handler 'droid'. By default, another connection
        on the same session is made for EventDispatcher, and the dispatcher is
        returned to the caller as well.
        If sl4n server is not started on the device, try to start it.

        Args:
            handle_event: True if this droid session will need to handle
                events.

        Returns:
            droid: Android object useds to communicate with sl4n on the android
                device.
            ed: An optional EventDispatcher to organize events for this droid.

        Examples:
            Don't need event handling:
            >>> ad = NativeAndroidDevice()
            >>> droid = ad.get_droid(False)

            Need event handling:
            >>> ad = NativeAndroidDevice()
            >>> droid, ed = ad.get_droid()
        """
        if not self.h_port or not host_utils.is_port_available(self.h_port):
            self.h_port = host_utils.get_available_host_port()
        self.adb.tcp_forward(self.h_port, self.d_port)
        pid = self.adb.shell("pidof -s sl4n", ignore_status=True)
        while (pid):
            self.adb.shell("kill {}".format(pid))
            pid = self.adb.shell("pidof -s sl4n", ignore_status=True)
        call(
            ["adb -s " + self.serial + " shell sh -c \"/system/bin/sl4n\" &"],
            shell=True)
        try:
            time.sleep(3)
            droid = self.start_new_session()
        except:
            droid = self.start_new_session()
        return droid
    def get_droid(self, handle_event=True):
        """Create an sl4a connection to the device.

        Return the connection handler 'droid'. By default, another connection
        on the same session is made for EventDispatcher, and the dispatcher is
        returned to the caller as well.
        If sl4a server is not started on the device, try to start it.

        Args:
            handle_event: True if this droid session will need to handle
                events.

        Returns:
            droid: Android object used to communicate with sl4a on the android
                device.
            ed: An optional EventDispatcher to organize events for this droid.

        Examples:
            Don't need event handling:
            >>> ad = AndroidDevice()
            >>> droid = ad.get_droid(False)

            Need event handling:
            >>> ad = AndroidDevice()
            >>> droid, ed = ad.get_droid()
        """
        forward_success = False
        last_error = None
        for _ in range(PORT_RETRY_COUNT):
            if not self.h_port or not host_utils.is_port_available(
                    self.h_port):
                self.h_port = host_utils.get_available_host_port()
            try:
                self.adb.tcp_forward(self.h_port, self.d_port)
                forward_success = True
                break
            except adb.AdbError as e:
                last_error = e
                pass
        if not forward_success:
            self.log.error(last_error)
            raise last_error

        for i in range(PORT_RETRY_COUNT):
            try:
                if self.is_sl4a_running():
                    self.log.info("Stop sl4a apk")
                    self.stop_sl4a()
                    time.sleep(15)
                self.log.info("Start sl4a apk")
                self.start_sl4a()
                time.sleep(5)
                droid = self.start_new_session()
                if handle_event:
                    ed = self.get_dispatcher(droid)
                    return droid, ed
                return droid
            except Exception as e:
                self.log.warning("get_droid with exception: %s", e)
                if i == PORT_RETRY_COUNT - 1:
                    raise