Пример #1
0
    def _start_mnt(self):
        """ fork a process to start minicap on android """
        # adb shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P 540x960@340x720/0
        size = self._get_size().split('x')
        real_x = int(size[0])
        real_y = int(size[1])
        virtual_x = real_x
        virtual_y = real_y
        # if real_x >= 1080 and real_y >= 1920:
        #     virtual_x = int(real_x * config.VIRTUAL_X)
        #     virtual_y = int(real_y * config.VIRTUAL_Y)

        command_list = [
            _ADB,
            "-s",
            self.device_id,
            "shell",
            "LD_LIBRARY_PATH=/data/local/tmp",
            "/data/local/tmp/minicap",
            "-P",
            "{}x{}@{}x{}/0".format(real_x, real_y, virtual_x, virtual_y),
        ]

        logger.info("start minicap: {}".format(" ".join(command_list)))
        self.mncap_process = subprocess.Popen(command_list,
                                              stdout=subprocess.DEVNULL)
        logger.info("start minicap: {}".format(self.mncap_process))
Пример #2
0
    def __init__(self, device_id):
        self.device_id = device_id
        self.abi = self.get_abi()
        self.sdk = self.get_sdk()
        if self.is_mnc_existed():
            logger.info("minicap already existed in {}".format(device_id))
        else:
            self.download_target_mnc()

        if self.is_mnc_so_existed():
            logger.info("minicap.so already existed in {}".format(device_id))
        else:
            self.download_target_mnc_so()
Пример #3
0
def is_device_connected(device_id):
    """ return True if device connected, else return False """
    _ADB = config.ADB_EXECUTOR
    try:
        device_name = subprocess.check_output(
            [_ADB, "-s", device_id, "shell", "getprop", "ro.product.model"]
        )
        device_name = (
            device_name.decode(config.DEFAULT_CHARSET)
            .replace("\n", "")
            .replace("\r", "")
        )
        logger.info("device {} online".format(device_name))
    except subprocess.CalledProcessError:
        return False
    return True
Пример #4
0
    def download_target_mnc(self):
        # minicap文件
        abi = self.get_abi()
        target_url = "{}/{}/bin/minicap".format(config.MNT_PREBUILT_URL, abi)

        logger.info("target minicap url: " + target_url)
        curPath = os.path.abspath(os.path.dirname(__file__))
        mnc_path = curPath + os.sep + 'prebuilt' + os.sep + abi + os.sep + 'bin' + os.sep + 'minicap'

        # push and grant
        subprocess.check_call(
            [_ADB, "-s", self.device_id, "push", mnc_path, config.MNC_HOME])
        subprocess.check_call([
            _ADB, "-s", self.device_id, "shell", "chmod", "777",
            config.MNC_HOME
        ])

        logger.info("minicap already installed in {}".format(config.MNC_HOME))
Пример #5
0
    def download_target_mnc_so(self):

        # minicap.so文件
        abi = self.get_abi()
        sdk = self.get_sdk()
        so_target_url = "{}/{}/lib/android-{}/minicap.so".format(
            config.MNT_PREBUILT_URL, abi, sdk)
        logger.info("target minicap.so url: " + so_target_url)
        curPath = os.path.abspath(os.path.dirname(__file__))
        so_path = curPath + os.sep + 'prebuilt' + os.sep + abi + os.sep + 'lib' + os.sep + 'android-{}'.format(
            sdk) + os.sep + 'minicap.so'
        # push and grant
        subprocess.check_call(
            [_ADB, "-s", self.device_id, "push", so_path, config.SO_HOME])
        subprocess.check_call([
            _ADB, "-s", self.device_id, "shell", "chmod", "777", config.SO_HOME
        ])
        logger.info("minicap.so already installed in {}".format(
            config.MNC_HOME))
Пример #6
0
    def __init__(self, device_id):
        assert is_device_connected(device_id)

        self.device_id = device_id
        logger.info("searching a usable port ...")
        self.port = self._get_port()
        logger.info("device {} bind to port {}".format(device_id, self.port))

        # check minicap
        self.installer = MNTInstaller(device_id)

        # keep minicap alive
        self._forward_port()
        self.mncap_process = None
        self._start_mnt()

        # make sure it's up
        time.sleep(1)
        assert (
            self.heartbeat()
        ), "minicap did not work. see https://github.com/williamfzc/pyminicap/issues/11"
Пример #7
0
 def get_sdk(self):
     sdk = subprocess.getoutput(
         "{} -s {} shell getprop ro.build.version.sdk".format(
             _ADB, self.device_id))
     logger.info("device_sdk {} is {}".format(self.device_id, sdk))
     return sdk.strip()
Пример #8
0
 def get_abi(self):
     abi = subprocess.getoutput(
         "{} -s {} shell getprop ro.product.cpu.abi".format(
             _ADB, self.device_id))
     logger.info("device_abi {} is {}".format(self.device_id, abi))
     return abi.strip()
Пример #9
0
 def send(self, content):
     """ send message and get its response """
     byte_content = str2byte(content)
     self.client.sendall(byte_content)
     logger.info("touch: {}".format(byte_content))
     return self.client.recv(self._DEFAULT_BUFFER_SIZE)
Пример #10
0
 def disconnect(self):
     self.client and self.client.close()
     self.client = None
     logger.info("minicap disconnected")
Пример #11
0
 def ReadImageStream(self):
     # get minicap server info
     readBannerBytes = 0
     bannerLength = 2
     readFrameBytes = 0
     frameBodylength = 0
     dataBody = b""
     while self.client:
         try:
             reallen = self.client.recv(4096)
             length = len(reallen)
             if not length:
                 continue
             cursor = 0
             while cursor < length:
                 # 获取图片头部信息
                 if readBannerBytes < bannerLength:
                     if readBannerBytes == 0:
                         self.banner.Version = reallen[cursor]
                     elif readBannerBytes == 1:
                         bannerLength = reallen[cursor]
                         self.banner.Length = bannerLength
                     elif readBannerBytes in [2, 3, 4, 5]:
                         self.banner.Pid += (reallen[cursor] << (
                             (readBannerBytes - 2) * 8)) >> 0
                     elif readBannerBytes in [6, 7, 8, 9]:
                         self.banner.RealWidth += (reallen[cursor] << (
                             (readBannerBytes - 6) * 8)) >> 0
                     elif readBannerBytes in [10, 11, 12, 13]:
                         self.banner.RealHeight += (reallen[cursor] << (
                             (readBannerBytes - 10) * 8)) >> 0
                     elif readBannerBytes in [14, 15, 16, 17]:
                         self.banner.VirtualWidth += (reallen[cursor] << (
                             (readBannerBytes - 14) * 8)) >> 0
                     elif readBannerBytes in [18, 19, 20, 21]:
                         self.banner.VirtualHeight += (reallen[cursor] << (
                             (readBannerBytes - 18) * 8)) >> 0
                     elif readBannerBytes == 22:
                         self.banner.Orientation = reallen[cursor] * 90
                     elif readBannerBytes == 23:
                         self.banner.Quirks = reallen[cursor]
                     cursor += 1
                     readBannerBytes += 1
                     if readBannerBytes == bannerLength:
                         logger.info(self.banner.toString())
                 elif readFrameBytes < 4:
                     # 第一个过来的图片信息的前4个字符不是图片的二进制信息,而是携带着图片大小的信息
                     frameBodylength = frameBodylength + (
                         (reallen[cursor] << (readFrameBytes * 8)) >> 0)
                     cursor += 1
                     readFrameBytes += 1
                     # print('{} - {} '.format(cursor,frameBodylength))
                 else:
                     # 真正获取图片信息,比如我们接受到的信息长度为n,4~n部分是图片的信息,需要保存下来。
                     # print('{} - {} - {} '.format(length,cursor, frameBodylength))
                     if length - cursor >= frameBodylength:
                         dataBody = dataBody + (reallen[cursor:(
                             cursor + frameBodylength)])
                         if dataBody[0] != 0xFF or dataBody[1] != 0xD8:
                             return
                         self.picture.put(dataBody)
                         # self.save_file('d:/pic.png', dataBody)
                         cursor += frameBodylength
                         frameBodylength = 0
                         readFrameBytes = 0
                         dataBody = b""
                     else:
                         dataBody = dataBody + reallen[cursor:length]
                         frameBodylength -= length - cursor
                         readFrameBytes += length - cursor
                         cursor = length
         except:
             logger.info('退出线程')
             break
Пример #12
0
 def _get_size(self):
     out_put = subprocess.check_output(
         [_ADB, "-s", self.device_id, "shell", "wm", "size"])
     logger.info("当前设备分辨率为: {}".format(out_put.decode('utf-8')))
     size = out_put.decode('utf-8').split(': ')[1].strip()
     return size
Пример #13
0
 def stop(self):
     self.mncap_process and self.mncap_process.kill()
     self._PORT_SET.add(self.port)
     logger.info("device {} unbind to {}".format(self.device_id, self.port))