示例#1
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)
示例#2
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)