ADB Client
| 78 | """Duck-typed ``tubes.remote`` object to add properties of a ``tubes.process``""" |
| 79 | |
| 80 | class AdbClient(Logger): |
| 81 | """ADB Client""" |
| 82 | def __init__(self, level=None): |
| 83 | super(AdbClient, self).__init__() |
| 84 | |
| 85 | if level is not None: |
| 86 | self.setLevel(level) |
| 87 | |
| 88 | self.host = context.adb_host |
| 89 | self.port = context.adb_port |
| 90 | self._c = None |
| 91 | |
| 92 | @property |
| 93 | def c(self): |
| 94 | """AdbClient's connection to the ADB server""" |
| 95 | if not self._c: |
| 96 | try: |
| 97 | # Squelch the first '[ERROR] Could not connect to localhost on port 5037' |
| 98 | level = self.level |
| 99 | with context.quiet: |
| 100 | if not self.isEnabledFor(logging.INFO): |
| 101 | level = logging.FATAL |
| 102 | self._c = Connection(self.host, self.port, level=level) |
| 103 | except Exception: |
| 104 | # If the connection fails, try starting a server on that port |
| 105 | # as long as it's the *default* port. |
| 106 | if self.host == context.defaults['adb_host'] \ |
| 107 | and self.port == context.defaults['adb_port']: |
| 108 | log.warn("Could not connect to ADB server, trying to start it") |
| 109 | process(context.adb + ['start-server']).recvall() |
| 110 | time.sleep(0.3) |
| 111 | else: |
| 112 | log.exception('Could not connect to ADB server (%s:%s)', |
| 113 | self.host, self.port) |
| 114 | |
| 115 | # Final attempt... |
| 116 | if not self._c: |
| 117 | self._c = Connection(self.host, self.port, level=self.level) |
| 118 | return self._c |
| 119 | |
| 120 | def _autoclose(fn): |
| 121 | """Decorator which automatically closes the connection to the ADB server |
| 122 | after calling the decorated function.""" |
| 123 | @functools.wraps(fn) |
| 124 | def wrapper(self, *a, **kw): |
| 125 | rv = fn(self, *a, **kw) |
| 126 | if self._c: |
| 127 | self._c.close() |
| 128 | self._c = None |
| 129 | return rv |
| 130 | return wrapper |
| 131 | |
| 132 | def _with_transport(fn): |
| 133 | """Decorator which automatically selects a device transport before calling |
| 134 | the decorated function, and closes the connection afterward.""" |
| 135 | @functools.wraps(fn) |
| 136 | def wrapper(self, *a, **kw): |
| 137 | self.transport() |
no outgoing calls
no test coverage detected