Comments (3)
Looks like dhcp discover service
from adbutils.
Looks like mDNS can be implemented with this lib: https://github.com/python-zeroconf/python-zeroconf
from adbutils.
adbdevices.py
import re
import pprint
import socket
import weakref
import subprocess
import threading
import string
import secrets
from io import BytesIO
#pip install adbutils zeroconf qrcode
import adbutils
from adbutils import adb
from zeroconf import ServiceBrowser, ServiceListener, Zeroconf
from adbutils.errors import AdbError,AdbTimeout
import qrcode
def create_passwd():
alphabet = string.ascii_letters + string.digits
return ''.join(secrets.choice(alphabet) for i in range(8))
def adb_start_server():
subprocess.run('adb start-server')
class MDnsListener(ServiceListener):
def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
info = zc.get_service_info(type_, name)
if info:
AdbMDns.update(info)
def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
info = zc.get_service_info(type_, name)
if info:
AdbMDns.remove(info)
def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
info = zc.get_service_info(type_, name)
if info:
AdbMDns.add(info)
class AdbMDnsError(Exception):
pass
class AdbMDns:
_devices={}
started=False
type="_adb-tls-connect._tcp.local."
# type='_adb._tcp.local.'
lock = threading.Lock()
zeroconf=None
finalize=None
@staticmethod
def start():
if AdbMDns.started==False:
AdbMDns.zeroconf = Zeroconf()
ServiceBrowser(AdbMDns.zeroconf, AdbMDns.type, MDnsListener())
def atexit(zeroconf):
zeroconf.close()
AdbMDns.finalize = weakref.finalize(AdbMDns.zeroconf, atexit, AdbMDns.zeroconf)
AdbMDns.started=True
@staticmethod
def update(info):
info=AdbMDns._info(info)
AdbMDns.remove(info)
AdbMDns.add(info)
# AdbMDns.print()
@staticmethod
def add(info):
if not isinstance(info,tuple):
info=AdbMDns._info(info)
ip,serialno=info
AdbMDns.lock.acquire()
AdbMDns._devices[serialno]=ip
AdbMDns.lock.release()
# AdbMDns.print()
@staticmethod
def remove(info):
if not isinstance(info,tuple):
info=AdbMDns._info(info)
ip,serialno=info
ip,port=ip.split(':')
AdbMDns.lock.acquire()
for serialno_,ip_ in tuple(AdbMDns._devices.items()):
ip_,port=ip_.split(':')
if ip_==ip or serialno_==serialno:
del AdbMDns._devices[serialno_]
AdbMDns.lock.release()
# AdbMDns.print()
@staticmethod
def _info(info):
ip = f'{socket.inet_ntoa(info.addresses[0])}:{info.port}'
if (m:=re.match(fr'adb\-(\w+)\-\w+\.{AdbMDns.type}',info.name)):
serialno = m.group(1)
else:
serialno = ''
raise AdbMDnsError(f'AdbMDns not match: {info.name}')
return ip,serialno
@staticmethod
def devices():
AdbMDns.lock.acquire()
d=tuple(AdbMDns._devices.items())
AdbMDns.lock.release()
return d
@staticmethod
def print():
pprint.pprint(['mDns',AdbMDns.devices()])
def adb_devices():
serialnos=[]
serials=[]
ds=[]
key_serialno='ro.serialno'
# key_guid='persist.adb.wifi.guid' #could be ''
def devices():
yield from adb_devices.ds
a = adb.device_list()
for d in adb.device_list():
serials.append(d.serial)
yield d
for serialno,ip in AdbMDns.devices():
if ip not in serials and serialno not in serialnos:
output = adb.connect(ip)
if re.match(f'^(already )?connected to {ip}',output):
d = adb.device(serial=ip)
if serialno:
d._properties[key_serialno]=serialno
serials.append(ip)
yield d
else:
print(output)
# cannot connect to 10.1.1.1:100: No connection could be made because the target machine actively refused it. (10061)
def devices_available():
for d in devices():
if d and d not in ds:
try:
model = d.shell('getprop ro.product.model') or '' #check avaliable
serialno = d.prop.get(key_serialno, cache=True)
if not serialno:
raise AdbMDnsError(f'serialno {serialno}')
except:
continue
if serialno not in serialnos:
if serialno: serialnos.append(serialno)
ds.append(d)
yield d,(serialno,model)
try:
yield from devices_available()
adb_devices.ds=ds
except GeneratorExit:
adb_devices.ds=ds
return
adb_devices.ds=[]
class PairListener(ServiceListener):
def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
pass
def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
pass
def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
info = zc.get_service_info(type_, name)
AdbPair.pair(info)
class AdbPair:
name='name'
passwd=create_passwd()
type="_adb-tls-pairing._tcp.local."
def __init__(self):
self.start_pair()
self.qrcode()
def start_pair(self):
self.zeroconf = Zeroconf()
ServiceBrowser(self.zeroconf, AdbPair.type, PairListener())
def qrcode(self):
s=f'WIFI:T:ADB;S:{AdbPair.name};P:{AdbPair.passwd};;'
qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=20, border=2)
qr.add_data(s)
qr.print_ascii(tty=True)
self.img = qr.make_image(fill_color="black", back_color="white")
@property
def img_pil(self):
return self.img.convert('RGB')
@property
def img_cv(self):
import cv2 as cv
import numpy as np
return cv.cvtColor(np.array(self.img_pil), cv.COLOR_RGB2BGR)
@property
def img_buf(self):
buf = BytesIO()
self.img.save(buf, "PNG")
return buf
@staticmethod
def pair(info):
ip=AdbPair._info(info)
subprocess.run(f'adb pair {ip} {AdbPair.passwd}')
@staticmethod
def _info(info):
ip = f'{socket.inet_ntoa(info.addresses[0])}:{info.port}'
return ip
def stop_pair(self):
self.zeroconf.close()
def ui_qt():
from PyQt6 import QtWidgets, QtGui, QtCore
class UiQrCode(QtWidgets.QDialog):
def __init__(self,parent=None):
super().__init__(parent)
self.setWindowTitle(f"adb pair")
self.pair=adbdevices.AdbPair()
img = QtGui.QPixmap()
img.loadFromData(self.pair.img_buf.getvalue(), "PNG")
label=QtWidgets.QLabel()
vlayout = QtWidgets.QVBoxLayout()
label.setPixmap(img)
self.setLayout(vlayout)
vlayout.addWidget(label)
def closeEvent(self,event):
self.pair.stop_pair()
app = QtWidgets.QApplication([])
root = UiQrCode()
root.show()
ret = app.exec()
def ui_cv():
import cv2 as cv
pair=adbdevices.AdbPair()
cv.imshow('pair',pair.img_cv)
cv.waitKey(0)
cv.destroyAllWindows()
pair.stop_pair()
AdbMDns.start()
adb_start_server()
if __name__ == "__main__":
import sys
adbdevices = sys.modules[__name__]
ui_qt()
ui_cv()
# import adbdevices
while True:
try:
for d,(serialno,model) in adbdevices.adb_devices():
print(d.serial,(serialno,model))
print(d.shell('date'))
except (adbdevices.AdbError,adbdevices.AdbTimeout) as e:
adbdevices.adb_start_server()
print('adbdevices',type(e),e)
except Exception as e:
print('adbdevices',type(e),e)
input()
from adbutils.
Related Issues (20)
- [Feature request] Provides the usb-device-to-tcp function HOT 4
- AdbConnection创建连接超时 HOT 2
- 脚本退出后还残留一个后台adb.exe HOT 2
- 停止录屏windows系统报错 HOT 2
- Package is missing py.typed HOT 4
- internal exception occurred when using device.install() for some apks
- windows平台adb服务未启动时会报错,不能自动启动 HOT 1
- Since 2.6.0, shell command with serial on ubuntu system will raise adbutils.errors.AdbError: unknown host service HOT 1
- ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
- Merge `adbutils_async` as an Asynchronous Version of `adbutils`? HOT 2
- Screenshots not working with Android 23 HOT 2
- 是否有支持文件pull/push文件的传输进度的功能
- ValueError when using the .battery() method
- stop_recording() ERROR:adbutils.errors.AdbError: ('scrcpy error', -2)
- 命令行push失败
- Shell session?
- How to get touch coordinates?
- adb install form URl fails HOT 1
- Ability to set device clipboard with specific text HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from adbutils.