Exemplo n.º 1
0
    def __init__(self, config):
        """
        Args:
            config (AzurLaneConfig, str): Name of the user config under ./config
        """
        logger.hr('Device')
        if isinstance(config, str):
            self.config = AzurLaneConfig(config, task=None)
        else:
            self.config = config

        self.serial = str(self.config.Emulator_Serial)
        if "bluestacks4-hyperv" in self.serial:
            self.serial = self.find_bluestacks4_hyperv(self.serial)
        if "bluestacks5-hyperv" in self.serial:
            self.serial = self.find_bluestacks5_hyperv(self.serial)
        if "127.0.0.1:58526" in self.serial:
            raise RequestHumanTakeover('Serial 127.0.0.1:58526 seems to be WSA, please use "wsa-0" or others to instead')
        if "wsa" in self.serial:
            self.serial = '127.0.0.1:58526'

        logger.attr('Adb_binary', self.adb_binary)

        # Monkey patch to custom adb
        adbutils.adb_path = lambda: self.adb_binary
        # Remove global proxies, or uiautomator2 will go through it
        for k in list(os.environ.keys()):
            if k.lower().endswith('_proxy'):
                del os.environ[k]

        self.adb_client = AdbClient('127.0.0.1', 5037)
        self.adb_connect(self.serial)

        self.adb = AdbDevice(self.adb_client, self.serial)
        logger.attr('Adb_device', self.adb)
Exemplo n.º 2
0
def screencap_h264(device: AdbDevice, executor: Executor):
    start = time()
    device.push("../scrcpy-win64/scrcpy-server.jar",
                "/data/local/tmp/scrcpy-server.jar")
    print("Pushed server component")
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    port = device.adb_output("reverse", "tcp:5556", "localabstract:scrcpy")
    print("[ADB]", port)
    # sock.bind(("127.0.0.1", 5556))
    # sock.listen()

    executor.submit(lambda: print(
        "[SCRCPY]",
        device.shell("CLASSPATH=/data/local/tmp/scrcpy-server.jar "
                     "app_process / com.genymobile.scrcpy.Server 0 8000000 "
                     "false - false true")))
    print("Executed scrcpy")

    print("Waiting for connection")
    # conn, info = sock.accept()
    # print(info)
    # print(conn.recv(1))
    # print(conn.recv(64))
    # print(conn.recv(2))
    # print(conn.recv(2))
    # print("Closing transmission")
    # device.shell("\x03")
    # conn.close()
    # sock.close()
    print("Recv h264 took %f seconds" % (time() - start))
Exemplo n.º 3
0
def main(device: AdbDevice = None):
    """
    Initializes the global state, sets up a ThreadPoolExecutor and launches the Nimses app.

    :param device: the device to control, if `None`, chooses the first and only device
    """
    executor = ThreadPoolExecutor(3)
    state = {
        "device": device if device is not None else
        adb.device(),  # The Android device to control
        "executor": executor,  # The executor where the magic happens
        "last_image": None,  # The last image
        "last_ad": 0,  # The amount of updates since the last ad
        "ad_closed": True,  # Whether the last ad has been closed
        "ad_time": 0  # When to close the app (in the future)
    }

    device.app_start(NIMSES_PACKAGE, NIMSES_MAIN_ACTIVITY)

    # Prepare future variable
    future = Future()
    future.set_result(None)
    while True:
        if future.done():
            future = executor.submit(lambda: log_error(lambda: handle_new_ad(
                find_inline_ads(screen_shot_android(device)), device, state)))
        sleep(0.1)
Exemplo n.º 4
0
    def __init__(self, config):
        """
        Args:
            config (AzurLaneConfig):
        """
        logger.hr('Device')
        self.config = config
        self.serial = str(self.config.Emulator_Serial)
        if "bluestacks4-hyperv" in self.serial:
            self.serial = self.find_bluestacks4_hyperv(self.serial)
        if "bluestacks5-hyperv" in self.serial:
            self.serial = self.find_bluestacks5_hyperv(self.serial)

        logger.attr('Adb_binary', self.adb_binary)

        # Monkey patch to custom adb
        adbutils.adb_path = lambda: self.adb_binary
        # Remove global proxies, or uiautomator2 will go through it
        for k in list(os.environ.keys()):
            if k.lower().endswith('_proxy'):
                del os.environ[k]

        self.adb_client = AdbClient('127.0.0.1', 5037)
        self.adb_connect(self.serial)

        self.adb = AdbDevice(self.adb_client, self.serial)
        logger.attr('Adb_device', self.adb)
Exemplo n.º 5
0
def _setup_minicap(d: adbutils.AdbDevice):
    def cache_download(url, dst):
        if os.path.exists(dst):
            print("Use cached", dst)
            return
        print("Download {} from {}".format(dst, url))
        resp = requests.get(url, stream=True)
        resp.raise_for_status()
        length = int(resp.headers.get("Content-Length", 0))
        r = ReadProgress(resp.raw, length)
        with open(dst + ".cached", "wb") as f:
            shutil.copyfileobj(r, f)
        shutil.move(dst + ".cached", dst)

    def push_zipfile(path: str,
                     dest: str,
                     mode=0o755,
                     zipfile_path: str = "vendor/stf-binaries-master.zip"):
        """ push minicap and minitouch from zip """
        with zipfile.ZipFile(zipfile_path) as z:
            if path not in z.namelist():
                print("WARNING: stf stuff %s not found", path)
                return
            with z.open(path) as f:
                d.sync.push(f, dest, mode)

    zipfile_path = "stf-binaries.zip"
    cache_download("https://github.com/openatx/stf-binaries/archive/0.2.zip",
                   zipfile_path)
    zip_folder = "stf-binaries-0.2"

    sdk = d.getprop("ro.build.version.sdk")  # eg 26
    abi = d.getprop('ro.product.cpu.abi')  # eg arm64-v8a
    abis = (d.getprop('ro.product.cpu.abilist').strip() or abi).split(",")
    # return
    print("sdk: %s, abi: %s, support-abis: %s" % (sdk, abi, ','.join(abis)))
    print("Push minicap+minicap.so to device")
    prefix = zip_folder + "/node_modules/minicap-prebuilt/prebuilt/"
    push_zipfile(prefix + abi + "/lib/android-" + sdk + "/minicap.so",
                 "/data/local/tmp/minicap.so", 0o644, zipfile_path)
    push_zipfile(prefix + abi + "/bin/minicap", "/data/local/tmp/minicap",
                 0o0755, zipfile_path)

    print("Push minitouch to device")
    prefix = zip_folder + "/node_modules/minitouch-prebuilt/prebuilt/"
    push_zipfile(prefix + abi + "/bin/minitouch", "/data/local/tmp/minitouch",
                 0o0755, zipfile_path)

    # check if minicap installed
    output = d.shell(
        ["LD_LIBRARY_PATH=/data/local/tmp", "/data/local/tmp/minicap", "-i"])
    print(output)
    print("If you see JSON output, it means minicap installed successfully")
Exemplo n.º 6
0
def test_reverse(device: adbutils.AdbDevice):
    """
    Test commands:
    
        adb reverse --list
        adb -s xxxxx reverse --list
    """
    device.reverse("tcp:12345", "tcp:4000")
    exists = False
    for item in device.reverse_list():
        if item.remote == "tcp:12345" and item.local == "tcp:4000":
            exists = True
    assert exists
Exemplo n.º 7
0
def test_logcat(device: AdbDevice):
    pc_dst = './something1.txt'
    android_dst = '/sdcard/something.txt'

    device.logcat.start(android_dst)

    time.sleep(2)
    device.logcat.sync_to_pc(pc_dst)
    assert device.say_hello(), 'should not abort other actions'
    time.sleep(2)

    device.logcat.stop(pc_dst, remove=True)
    assert os.path.isfile(pc_dst)
    os.remove(pc_dst)
Exemplo n.º 8
0
def test_switch_airplane(device: AdbDevice):
    device.switch_airplane(True)
    device.switch_airplane(False)
Exemplo n.º 9
0
        required=False,
        dest='repeatProcedure',
        default='')
    parser.add_argument(
        '--stop-pattern',
        metavar='STOP_PATTERN',
        help=
        'the path of stop pattern which can triger droid stop. ex: ./pattern.png',
        required=False,
        dest='stopPatternPath',
        default='')

    args = parser.parse_args()

    adb_robot = AdbRobot()
    adb_device = AdbDevice()

    if args.serial is None:
        serial = adb_device.getDevices()
        if serial is None:
            print("No devices is connected.")
            exit()
    adb_device.setSerial(serial)
    adb_robot.setDevice(adb_device)

    repeatCount = args.repeatCount
    adb_robot.setRepeatCount(repeatCount)
    adb_robot.setTouchActionTable(args.touchTable)
    adb_robot.setSwipeActionTable(args.swipeTable)
    default_timing = args.interval
    adb_robot.setCmdInterval(default_timing)
Exemplo n.º 10
0
def test_current_app(device: AdbDevice):
    info = device.current_app()
    assert 'package' in info
    assert 'activity' in info
Exemplo n.º 11
0
    __author__ = 'Balaji Muhammad'

    #configure parser
    parser = argparse.ArgumentParser(description='This is broken from Baliji, but crashed by Muhammand')
    parser.add_argument('actions',metavar='ACTION', nargs='*', help='actions to be performed in a single flow. Format: action_name,delay_ms', default='')
    parser.add_argument('-s','--serial', help='serial# of the device, use this argument if you have 2+ devices', required=False, dest='serial', default=None)
    parser.add_argument('--touch-table', metavar='TOUCH_ACTION_TABLE', help='the name of touch action table. default: touchActions.tab', required=False, dest='touchTable', default='touchActions.tab')
    parser.add_argument('--swipe-table',metavar='SWIPE_ACTION_TABLE', help='the name of swipe action table. default: swipeActions.tab', required=False, dest='swipeTable', default='swipeActions.tab')
    parser.add_argument('--interval', metavar='ACTION_INTERVAL', help='the internal between two actions. default: 2s', required=False, dest='interval', default='2')
    parser.add_argument('-t', '--repeat', metavar='REPEAT_COUNT', help='the number of times to repeat assigned actions. default: 10', required=False, dest='repeatCount', default=1, type=int)
    parser.add_argument('-p', metavar='PROCEDURE', help='the name of repeat procedure. ex: example.procedure', required=False, dest='repeatProcedure', default='')
    
    args = parser.parse_args()
    
    adb_robot = AdbRobot()
    adb_device = AdbDevice()
    
    if args.serial is None:
        serial = adb_device.getDevices()
        if serial is None:
            print "No devices is connected."
            exit()
    adb_device.setSerial(serial)   
    adb_robot.setDevice(adb_device)

    repeatCount = args.repeatCount
    adb_robot.setRepeatCount(repeatCount)
    adb_robot.setTouchActionTable(args.touchTable)
    adb_robot.setSwipeActionTable(args.swipeTable)
    default_timing = args.interval
    adb_robot.setCmdInterval(default_timing)
Exemplo n.º 12
0
def test_wlan_ip(device: AdbDevice):
    device.switch_airplane(True)
    device.switch_wifi(True)
    time.sleep(3)
    ip = device.wlan_ip()
    assert ip, 'ip is empty'
Exemplo n.º 13
0
class Connection:
    config: AzurLaneConfig
    serial: str

    adb_binary_list = [
        './bin/adb/adb.exe',
        './toolkit/Lib/site-packages/adbutils/binaries/adb.exe',
        '/usr/bin/adb'
    ]

    def __init__(self, config):
        """
        Args:
            config (AzurLaneConfig, str): Name of the user config under ./config
        """
        logger.hr('Device')
        if isinstance(config, str):
            self.config = AzurLaneConfig(config, task=None)
        else:
            self.config = config

        self.serial = str(self.config.Emulator_Serial)
        if "bluestacks4-hyperv" in self.serial:
            self.serial = self.find_bluestacks4_hyperv(self.serial)
        if "bluestacks5-hyperv" in self.serial:
            self.serial = self.find_bluestacks5_hyperv(self.serial)
        if "127.0.0.1:58526" in self.serial:
            raise RequestHumanTakeover('Serial 127.0.0.1:58526 seems to be WSA, please use "wsa-0" or others to instead')
        if "wsa" in self.serial:
            self.serial = '127.0.0.1:58526'

        logger.attr('Adb_binary', self.adb_binary)

        # Monkey patch to custom adb
        adbutils.adb_path = lambda: self.adb_binary
        # Remove global proxies, or uiautomator2 will go through it
        for k in list(os.environ.keys()):
            if k.lower().endswith('_proxy'):
                del os.environ[k]

        self.adb_client = AdbClient('127.0.0.1', 5037)
        self.adb_connect(self.serial)

        self.adb = AdbDevice(self.adb_client, self.serial)
        logger.attr('Adb_device', self.adb)

    @staticmethod
    def find_bluestacks4_hyperv(serial):
        """
        Find dynamic serial of Bluestacks4 Hyper-v Beta.

        Args:
            serial (str): 'bluestacks4-hyperv', 'bluestacks4-hyperv-2' for multi instance, and so on.

        Returns:
            str: 127.0.0.1:{port}
        """
        from winreg import ConnectRegistry, OpenKey, QueryInfoKey, EnumValue, CloseKey, HKEY_LOCAL_MACHINE

        logger.info("Use Bluestacks4 Hyper-v Beta")
        if serial == "bluestacks4-hyperv":
            folder_name = "Android"
        else:
            folder_name = f"Android_{serial[19:]}"

        logger.info("Reading Realtime adb port")
        reg_root = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
        sub_dir = f"SOFTWARE\\BlueStacks_bgp64_hyperv\\Guests\\{folder_name}\\Config"
        bs_keys = OpenKey(reg_root, sub_dir)
        bs_keys_count = QueryInfoKey(bs_keys)[1]
        for i in range(bs_keys_count):
            key_name, key_value, key_type = EnumValue(bs_keys, i)
            if key_name == "BstAdbPort":
                logger.info(f"New adb port: {key_value}")
                serial = f"127.0.0.1:{key_value}"
                break

        CloseKey(bs_keys)
        CloseKey(reg_root)
        return serial

    @staticmethod
    def find_bluestacks5_hyperv(serial):
        """
        Find dynamic serial of Bluestacks5 Hyper-v.

        Args:
            serial (str): 'bluestacks5-hyperv', 'bluestacks5-hyperv-1' for multi instance, and so on.

        Returns:
            str: 127.0.0.1:{port}
        """
        from winreg import ConnectRegistry, OpenKey, QueryInfoKey, EnumValue, CloseKey, HKEY_LOCAL_MACHINE

        logger.info("Use Bluestacks5 Hyper-v")
        logger.info("Reading Realtime adb port")

        if serial == "bluestacks5-hyperv":
            parameter_name = "bst.instance.Nougat64.status.adb_port"
        else:
            parameter_name = f"bst.instance.Nougat64_{serial[19:]}.status.adb_port"

        reg_root = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
        sub_dir = f"SOFTWARE\\BlueStacks_nxt"
        bs_keys = OpenKey(reg_root, sub_dir)
        bs_keys_count = QueryInfoKey(bs_keys)[1]
        for i in range(bs_keys_count):
            key_name, key_value, key_type = EnumValue(bs_keys, i)
            if key_name == "UserDefinedDir":
                logger.info(f"Configuration file directory: {key_value}")
                with open(f"{key_value}\\bluestacks.conf", 'r', encoding='utf-8') as f:
                    content = f.read()
                    port = re.findall(rf'{parameter_name}="(.*?)"\n', content, re.S)
                    if len(port) > 0:
                        logger.info(f"Match to dynamic port: {port[0]}")
                        serial = f"127.0.0.1:{port[0]}"
                    else:
                        logger.warning(f"Did not match the result: {serial}.")
                break

        CloseKey(bs_keys)
        CloseKey(reg_root)
        return serial

    @cached_property
    def adb_binary(self):
        # Try adb in deploy.yaml
        config = poor_yaml_read(DEPLOY_CONFIG)
        if 'AdbExecutable' in config:
            file = config['AdbExecutable'].replace('\\', '/')
            if os.path.exists(file):
                return os.path.abspath(file)

        # Try existing adb.exe
        for file in self.adb_binary_list:
            if os.path.exists(file):
                return os.path.abspath(file)

        # Use adb.exe in system PATH
        file = 'adb.exe'
        return file

    def adb_command(self, cmd, timeout=10):
        """
        Execute ADB commands in a subprocess,
        usually to be used when pulling or pushing large files.

        Args:
            cmd (list):
            timeout (int):

        Returns:
            str:
        """
        cmd = list(map(str, cmd))
        cmd = [self.adb_binary, '-s', self.serial] + cmd

        # Use shell=True to disable console window when using GUI.
        # Although, there's still a window when you stop running in GUI, which cause by gooey.
        # To disable it, edit gooey/gui/util/taskkill.py

        # No gooey anymore, just shell=False
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False)
        return process.communicate(timeout=timeout)[0]

    def adb_shell(self, cmd, **kwargs):
        """
        Equivalent to `adb -s <serial> shell <*cmd>`

        Args:
            cmd (list):
            **kwargs:
                rstrip (bool): strip the last empty line (Default: True)
                stream (bool): return stream instead of string output (Default: False)

        Returns:
            str or socket if stream=True
        """
        cmd = list(map(str, cmd))
        result = self.adb.shell(cmd, timeout=10, **kwargs)
        return result

    @cached_property
    def reverse_server(self):
        """
        Setup a server on Alas, access it from emulator.
        This will bypass adb shell and be faster.
        """
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._server_port = self.adb_reverse(f'tcp:{self.config.REVERSE_SERVER_PORT}')
        server.bind(('127.0.0.1', self._server_port))
        server.listen(5)
        logger.info(f'Reverse server listening on {self._server_port}')
        return server

    def adb_shell_nc(self, cmd, timeout=5, chunk_size=262144):
        """
        Args:
            cmd (list):
            timeout (int):
            chunk_size (int): Default to 262144

        Returns:
            bytes:
        """
        # <command> | nc 127.0.0.1 {port}
        cmd += ['|', 'nc', '127.0.0.1', self.config.REVERSE_SERVER_PORT]

        # Server start listening
        server = self.reverse_server
        server.settimeout(timeout)
        # Client send data, waiting for server accept
        _ = self.adb_shell(cmd, stream=True)
        try:
            # Server accept connection
            conn, conn_port = server.accept()
        except socket.timeout:
            raise AdbTimeout('reverse server accept timeout')

        # Server receive data
        data = recv_all(conn, chunk_size=chunk_size)

        # Server close connection
        conn.close()
        return data

    def adb_exec_out(self, cmd, serial=None):
        cmd.insert(0, 'exec-out')
        return self.adb_command(cmd, serial)

    def adb_forward(self, remote):
        """
        Do `adb forward <local> <remote>`.
        choose a random port in FORWARD_PORT_RANGE or reuse an existing forward,
        and also remove redundant forwards.

        Args:
            remote (str):
                tcp:<port>
                localabstract:<unix domain socket name>
                localreserved:<unix domain socket name>
                localfilesystem:<unix domain socket name>
                dev:<character device name>
                jdwp:<process pid> (remote only)

        Returns:
            int: Port
        """
        port = 0
        for forward in self.adb.forward_list():
            if forward.serial == self.serial and forward.remote == remote and forward.local.startswith('tcp:'):
                if not port:
                    logger.info(f'Reuse forward: {forward}')
                    port = int(forward.local[4:])
                else:
                    logger.info(f'Remove redundant forward: {forward}')
                    self.adb_forward_remove(forward.local)

        if port:
            return port
        else:
            # Create new forward
            port = random_port(self.config.FORWARD_PORT_RANGE)
            forward = ForwardItem(self.serial, f'tcp:{port}', remote)
            logger.info(f'Create forward: {forward}')
            self.adb.forward(forward.local, forward.remote)
            return port

    def adb_reverse(self, remote):
        port = 0
        for reverse in self.adb.reverse_list():
            if reverse.remote == remote and reverse.local.startswith('tcp:'):
                if not port:
                    logger.info(f'Reuse reverse: {reverse}')
                    port = int(reverse.local[4:])
                else:
                    logger.info(f'Remove redundant forward: {reverse}')
                    self.adb_forward_remove(reverse.local)

        if port:
            return port
        else:
            # Create new reverse
            port = random_port(self.config.FORWARD_PORT_RANGE)
            reverse = ReverseItem(f'tcp:{port}', remote)
            logger.info(f'Create reverse: {reverse}')
            self.adb.reverse(reverse.local, reverse.remote)
            return port

    def adb_forward_remove(self, local):
        """
        Equivalent to `adb -s <serial> forward --remove <local>`
        More about the commands send to ADB server, see:
        https://cs.android.com/android/platform/superproject/+/master:packages/modules/adb/SERVICES.TXT

        Args:
            local (str): Such as 'tcp:2437'
        """
        with self.adb_client._connect() as c:
            list_cmd = f"host-serial:{self.serial}:killforward:{local}"
            c.send_command(list_cmd)
            c.check_okay()

    def adb_reverse_remove(self, local):
        """
        Equivalent to `adb -s <serial> reverse --remove <local>`

        Args:
            local (str): Such as 'tcp:2437'
        """
        with self.adb_client._connect() as c:
            c.send_command(f"host:transport:{self.serial}")
            c.check_okay()
            list_cmd = f"reverse:killforward:{local}"
            c.send_command(list_cmd)
            c.check_okay()

    def adb_push(self, local, remote):
        """
        Args:
            local (str):
            remote (str):

        Returns:
            str:
        """
        cmd = ['push', local, remote]
        return self.adb_command(cmd)

    def adb_connect(self, serial):
        """
        Connect to a serial, try 3 times at max.
        If there's an old ADB server running while Alas is using a newer one, which happens on Chinese emulators,
        the first connection is used to kill the other one, and the second is the real connect.

        Args:
            serial (str):

        Returns:
            bool: If success
        """
        if 'emulator' in serial:
            return True
        else:
            for _ in range(3):
                msg = self.adb_client.connect(serial)
                logger.info(msg)
                if 'connected' in msg:
                    # Connected to 127.0.0.1:59865
                    # Already connected to 127.0.0.1:59865
                    return True
                elif 'bad port' in msg:
                    # bad port number '598265' in '127.0.0.1:598265'
                    logger.error(msg)
                    possible_reasons('Serial incorrect, might be a typo')
                    raise RequestHumanTakeover
            logger.warning(f'Failed to connect {serial} after 3 trial, assume connected')
            return False

    def adb_disconnect(self, serial):
        msg = self.adb_client.disconnect(serial)
        if msg:
            logger.info(msg)

        del_cached_property(self, 'hermit_session')
        del_cached_property(self, 'minitouch_builder')
        del_cached_property(self, 'reverse_server')

    def install_uiautomator2(self):
        """
        Init uiautomator2 and remove minicap.
        """
        logger.info('Install uiautomator2')
        init = u2.init.Initer(self.adb, loglevel=logging.DEBUG)
        init.set_atx_agent_addr('127.0.0.1:7912')
        init.install()
        self.uninstall_minicap()

    def uninstall_minicap(self):
        """ minicap can't work or will send compressed images on some emulators. """
        logger.info('Removing minicap')
        self.adb_shell(["rm", "/data/local/tmp/minicap"])
        self.adb_shell(["rm", "/data/local/tmp/minicap.so"])

    def restart_atx(self):
        """
        Minitouch supports only one connection at a time.
        Restart ATX to kick the existing one.
        """
        logger.info('Restart ATX')
        atx_agent_path = '/data/local/tmp/atx-agent'
        self.adb_shell([atx_agent_path, 'server', '--stop'])
        self.adb_shell([atx_agent_path, 'server', '--nouia', '-d', '--addr', '127.0.0.1:7912'])

    @staticmethod
    def sleep(second):
        """
        Args:
            second(int, float, tuple):
        """
        time.sleep(ensure_time(second))

    _orientation_description = {
        0: 'Normal',
        1: 'HOME key on the right',
        2: 'HOME key on the top',
        3: 'HOME key on the left',
    }
    orientation = 0

    def get_orientation(self):
        """
        Rotation of the phone

        Returns:
            int:
                0: 'Normal'
                1: 'HOME key on the right'
                2: 'HOME key on the top'
                3: 'HOME key on the left'
        """
        _DISPLAY_RE = re.compile(
            r'.*DisplayViewport{valid=true, .*orientation=(?P<orientation>\d+), .*deviceWidth=(?P<width>\d+), deviceHeight=(?P<height>\d+).*'
        )
        output = self.adb_shell(['dumpsys', 'display'])

        res = _DISPLAY_RE.search(output, 0)

        if res:
            o = int(res.group('orientation'))
            if o in Connection._orientation_description:
                pass
            else:
                o = 0
                logger.warning(f'Invalid device orientation: {o}, assume it is normal')
        else:
            o = 0
            logger.warning('Unable to get device orientation, assume it is normal')

        self.orientation = o
        logger.attr('Device Orientation', f'{o} ({Connection._orientation_description.get(o, "Unknown")})')
        return o
Exemplo n.º 14
0
def test_adb_connect(device: adbutils.AdbDevice):
    with pytest.raises(adbutils.AdbTimeout):
        device.shell("sleep 10", timeout=1.0)
Exemplo n.º 15
0
def test_say_hello(device: AdbDevice):
    assert device.say_hello() == 'hello from {}'.format(device.serial)
Exemplo n.º 16
0
def test_switch_screen(device: AdbDevice):
    device.switch_screen(False)
    device.switch_screen(True)
Exemplo n.º 17
0
def test_keyevent(device: AdbDevice):
    # make sure no error raised
    device.keyevent(4)
Exemplo n.º 18
0
def handle_new_ad(ad: Tuple[Tuple[int, int], np.ndarray], device: AdbDevice,
                  state: dict):
    """
    Handles a newly identified ad, whether or not there actually is one.
    This method also makes sure, that ads are closed again.
    Some ads open the Play Store, so this method also moves back to Nimses.

    :param ad: a tuple with the ad location (optional) and the screen shot.
    :param device: the Android device that should be controlled
    :param state: the global state of this application
    """
    def close_ad():
        """
        Closes the currently open ad (really just switches to the main activity)
        """
        if not state["ad_closed"] and state["ad_time"] < time():
            device.app_start(NIMSES_PACKAGE, NIMSES_MAIN_ACTIVITY)
            state["ad_closed"] = True
            logger.info("Closed ad")

    pt, image = ad
    app = device.current_app()
    logger.info("Current app %s", app)
    logger.info("Ad open? %s", not state["ad_closed"])

    if np.array_equal(image, state["last_image"]) \
            or state["last_ad"] > 10:
        output = device.shell(["am", "force-stop", NIMSES_PACKAGE])
        logger.info(f"[ADB] {output}")
        device.app_start(NIMSES_PACKAGE, NIMSES_MAIN_ACTIVITY)
        state["last_ad"] = 0
        state["ad_closed"] = True
        logger.info("Restarted Nimses")
    elif app["package"] == NIMSES_PACKAGE:
        if app["activity"] == NIMSES_MAIN_ACTIVITY:
            # Ad found, click it
            if pt:
                device.click(pt[0], pt[1])
                state["last_ad"] = 0
                state["ad_closed"] = True
                logger.info("Clicked %d, %d", pt[0], pt[1])
            # No ad, scroll along
            else:
                state["last_ad"] += 1
                w, h = device.window_size()
                sx = w // 2
                sy = h // 4 * 3
                dx = w // 2
                dy = h // 4 * 1
                device.swipe(sx, sy, dx, dy, 1.0)
                logger.info("Scrolled from %d %d to %d %d", sx, sy, dx, dy)
        elif app["activity"] in NIMSES_AD_ACTIVITIES:
            if state["ad_closed"]:
                state["ad_time"] = time() + 35
                state["ad_closed"] = False
                logger.info("Close ad at: %s",
                            strftime("%H:%M:%S", localtime(state["ad_time"])))
            else:
                close_ad()
    elif app["package"] == PLAYSTORE_PACKAGE:
        device.app_start(NIMSES_PACKAGE, NIMSES_MAIN_ACTIVITY)
        logger.info("Closed Play Store")
    else:
        device.app_start(NIMSES_PACKAGE, NIMSES_MAIN_ACTIVITY)
Exemplo n.º 19
0
def test_switch_wifi(device: AdbDevice):
    device.switch_wifi(False)
    device.switch_wifi(True)
Exemplo n.º 20
0
def test_get_xxx(device: adbutils.AdbDevice):
    assert device.get_serialno()
    assert device.get_state() == "device"
    assert device.get_devpath().startswith("usb:")
Exemplo n.º 21
0
def test_swipe(device: AdbDevice):
    device.swipe(100, 100, 400, 400)
Exemplo n.º 22
0
def test_click(device: AdbDevice):
    device.click(100, 100)
Exemplo n.º 23
0
 def adb(self) -> AdbDevice:
     return AdbDevice(self.adb_client, self.serial)