Eric Lin | a26582d | 2022-02-16 19:08:47 +0000 | [diff] [blame] | 1 | """This is a shared library to help handling Mobly event waiting logic.""" |
| 2 | |
| 3 | import time |
| 4 | from typing import Callable |
| 5 | |
| 6 | from mobly.controllers.android_device_lib import callback_handler |
| 7 | from mobly.controllers.android_device_lib import snippet_event |
| 8 | |
| 9 | # Abbreviations for common use type |
| 10 | CallbackHandler = callback_handler.CallbackHandler |
| 11 | SnippetEvent = snippet_event.SnippetEvent |
| 12 | |
| 13 | # Type definition for the callback functions to make code formatted nicely |
| 14 | OnReceivedCallback = Callable[[SnippetEvent, int], bool] |
| 15 | OnWaitingCallback = Callable[[int], None] |
| 16 | OnMissedCallback = Callable[[], None] |
| 17 | |
| 18 | |
| 19 | def wait_callback_event(callback_event_handler: CallbackHandler, |
| 20 | event_name: str, timeout_seconds: int, |
| 21 | on_received: OnReceivedCallback, |
| 22 | on_waiting: OnWaitingCallback, |
| 23 | on_missed: OnMissedCallback) -> None: |
| 24 | """Waits until the matched event has been received or timeout. |
| 25 | |
| 26 | Here we keep waitAndGet for event callback from EventSnippet. |
| 27 | We loop until over timeout_seconds instead of directly |
| 28 | waitAndGet(timeout=teardown_timeout_seconds). Because there is |
| 29 | MAX_TIMEOUT limitation in callback_handler of Mobly. |
| 30 | |
| 31 | Args: |
| 32 | callback_event_handler: Mobly callback events handler. |
| 33 | event_name: the specific name of the event to wait. |
| 34 | timeout_seconds: the number of seconds to wait before giving up. |
| 35 | on_received: calls when event received, return false to keep waiting. |
| 36 | on_waiting: calls when waitAndGet timeout. |
| 37 | on_missed: calls when giving up. |
| 38 | """ |
| 39 | start_time = time.perf_counter() |
| 40 | deadline = start_time + timeout_seconds |
| 41 | while time.perf_counter() < deadline: |
| 42 | remaining_time_sec = min(callback_handler.DEFAULT_TIMEOUT, |
| 43 | deadline - time.perf_counter()) |
| 44 | try: |
| 45 | event = callback_event_handler.waitAndGet( |
| 46 | event_name, timeout=remaining_time_sec) |
| 47 | except callback_handler.TimeoutError: |
| 48 | elapsed_time = int(time.perf_counter() - start_time) |
| 49 | on_waiting(elapsed_time) |
| 50 | else: |
| 51 | elapsed_time = int(time.perf_counter() - start_time) |
| 52 | if on_received(event, elapsed_time): |
| 53 | break |
| 54 | else: |
| 55 | on_missed() |