# Path: android_env/components/adb_controller.py
# _MAX_INIT_RETRIES = 20
# _INIT_RETRY_SLEEP_SEC = 2.0
# _DEFAULT_TIMEOUT_SECONDS = 120.0
# class AdbController():
#   def __init__(self,
#                device_name: str = '',
#                adb_path: str = 'adb',
#                adb_server_port: int = 5037,
#                prompt_regex: str = r'generic_x86:/ \$',
#                default_timeout: float = _DEFAULT_TIMEOUT_SECONDS):
#   def command_prefix(self) -> List[str]:
#   def init_server(self, timeout: Optional[float] = None):
#   def close(self) -> None:
#   def _execute_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None) -> Optional[bytes]:
#   def _execute_normal_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None) -> Optional[bytes]:
#   def _execute_shell_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None,
#       max_num_retries: int = 3) -> Optional[bytes]:
#   def _init_shell(self, timeout: Optional[float] = None) -> None:
#   def _wait_for_device(self,
#                        max_tries: int = 20,
#                        sleep_time: float = 1.0,
#                        timeout: Optional[float] = None) -> None:
#   def _check_device_is_ready(self, timeout: Optional[float] = None) -> bool:
#   def _resolve_timeout(self, timeout: Optional[float]) -> float:
#   def install_binary(self,
#                      src: str,
#                      dest_dir: str,
#                      timeout: Optional[float] = None):
#   def install_apk(self,
#                   local_apk_path: str,
#                   timeout: Optional[float] = None) -> None:
#   def uninstall_package(self,
#                         package_name: str,
#                         timeout: Optional[float] = None) -> None:
#   def is_package_installed(self,
#                            package_name: str,
#                            timeout: Optional[float] = None) -> bool:
#   def start_activity(self,
#                      full_activity: str,
#                      extra_args: Optional[List[str]],
#                      timeout: Optional[float] = None):
#   def start_intent(self,
#                    action: str,
#                    data_uri: str,
#                    package_name: str,
#                    timeout: Optional[float] = None):
#   def start_accessibility_service(self,
#                                   accessibility_service_full_name,
#                                   timeout: Optional[float] = None):
#   def broadcast(self,
#                 receiver: str,
#                 action: str,
#                 extra_args: Optional[List[str]],
#                 timeout: Optional[float] = None):
#   def setprop(self,
#               prop_name: str,
#               value: str,
#               timeout: Optional[float] = None):
#   def push_file(self, src: str, dest: str, timeout: Optional[float] = None):
#   def force_stop(self, package: str, timeout: Optional[float] = None):
#   def clear_cache(self, package: str, timeout: Optional[float] = None):
#   def grant_permissions(self,
#                         package: str,
#                         permissions: Sequence[str],
#                         timeout: Optional[float] = None):
#   def get_activity_dumpsys(self,
#                            package_name: str,
#                            timeout: Optional[float] = None) -> Optional[str]:
#   def get_current_activity(self,
#                            timeout: Optional[float] = None) -> Optional[str]:
#   def start_screen_pinning(self,
#                            full_activity: str,
#                            timeout: Optional[float] = None):
#   def _fetch_current_task_id(self,
#                              full_activity_name: str,
#                              timeout: Optional[float] = None) -> int:
#   def get_screen_dimensions(self,
#                             timeout: Optional[float] = None) -> Tuple[int, int]:
#   def get_orientation(self, timeout: Optional[float] = None) -> Optional[str]:
#   def rotate_device(self,
#                     orientation: adb_pb2.AdbCall.Rotate.Orientation,
#                     timeout: Optional[float] = None) -> None:
#   def set_touch_indicators(self,
#                            show_touches: bool = True,
#                            pointer_location: bool = True,
#                            timeout: Optional[float] = None) -> None:
#   def set_bar_visibility(self,
#                          navigation: bool = False,
#                          status: bool = False,
#                          timeout: Optional[float] = None) -> Optional[bytes]:
#   def disable_animations(self, timeout: Optional[float] = None):
#   def input_tap(self, x: int, y: int, timeout: Optional[float] = None) -> None:
#   def input_text(self,
#                  input_text: str,
#                  timeout: Optional[float] = None) -> Optional[bytes]:
#   def input_key(self,
#                 key_code: str,
#                 timeout: Optional[float] = None) -> Optional[bytes]:


import enum
import re
from typing import Callable, List, Optional, Sequence, Pattern
from absl import logging
from android_env.components import adb_controller as adb_control
from android_env.proto import task_pb2

    child = current_node.find_child(regex_predicate)
    if child is None:
      logging.error('Mismatched regex (%i, %s). current_node: %s', i,
                    regex.pattern, current_node)
      logging.error('Dumpsys activity output: %s', str(dumpsys_activity_output))
      logging.error('Tree root: %s', str(root))
      return None
    else:
      current_node = child
  return True


class AppScreenChecker():
  """Checks that the current app screen matches an expected screen."""

  class Outcome(enum.IntEnum):
    """Possible return vales from checking the current app screen."""
    # The current app screen matches the expected app screen.
    SUCCESS = 0
    # There's no activity to check.
    EMPTY_EXPECTED_ACTIVITY = 1
    # We were unable to determine the current activity.
    FAILED_ACTIVITY_EXTRACTION = 2
    # The current activity does not match the expected activity.
    UNEXPECTED_ACTIVITY = 3
    # The current view hierarchy does not match the expected view hierarchy.
    UNEXPECTED_VIEW_HIERARCHY = 4

  def __init__(self,

# Path: android_env/components/adb_controller.py
# _MAX_INIT_RETRIES = 20
# _INIT_RETRY_SLEEP_SEC = 2.0
# _DEFAULT_TIMEOUT_SECONDS = 120.0
# class AdbController():
#   def __init__(self,
#                device_name: str = '',
#                adb_path: str = 'adb',
#                adb_server_port: int = 5037,
#                prompt_regex: str = r'generic_x86:/ \$',
#                default_timeout: float = _DEFAULT_TIMEOUT_SECONDS):
#   def command_prefix(self) -> List[str]:
#   def init_server(self, timeout: Optional[float] = None):
#   def close(self) -> None:
#   def _execute_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None) -> Optional[bytes]:
#   def _execute_normal_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None) -> Optional[bytes]:
#   def _execute_shell_command(
#       self,
#       args: List[str],
#       timeout: Optional[float] = None,
#       max_num_retries: int = 3) -> Optional[bytes]:
#   def _init_shell(self, timeout: Optional[float] = None) -> None:
#   def _wait_for_device(self,
#                        max_tries: int = 20,
#                        sleep_time: float = 1.0,
#                        timeout: Optional[float] = None) -> None:
#   def _check_device_is_ready(self, timeout: Optional[float] = None) -> bool:
#   def _resolve_timeout(self, timeout: Optional[float]) -> float:
#   def install_binary(self,
#                      src: str,
#                      dest_dir: str,
#                      timeout: Optional[float] = None):
#   def install_apk(self,
#                   local_apk_path: str,
#                   timeout: Optional[float] = None) -> None:
#   def uninstall_package(self,
#                         package_name: str,
#                         timeout: Optional[float] = None) -> None:
#   def is_package_installed(self,
#                            package_name: str,
#                            timeout: Optional[float] = None) -> bool:
#   def start_activity(self,
#                      full_activity: str,
#                      extra_args: Optional[List[str]],
#                      timeout: Optional[float] = None):
#   def start_intent(self,
#                    action: str,
#                    data_uri: str,
#                    package_name: str,
#                    timeout: Optional[float] = None):
#   def start_accessibility_service(self,
#                                   accessibility_service_full_name,
#                                   timeout: Optional[float] = None):
#   def broadcast(self,
#                 receiver: str,
#                 action: str,
#                 extra_args: Optional[List[str]],
#                 timeout: Optional[float] = None):
#   def setprop(self,
#               prop_name: str,
#               value: str,
#               timeout: Optional[float] = None):
#   def push_file(self, src: str, dest: str, timeout: Optional[float] = None):
#   def force_stop(self, package: str, timeout: Optional[float] = None):
#   def clear_cache(self, package: str, timeout: Optional[float] = None):
#   def grant_permissions(self,
#                         package: str,
#                         permissions: Sequence[str],
#                         timeout: Optional[float] = None):
#   def get_activity_dumpsys(self,
#                            package_name: str,
#                            timeout: Optional[float] = None) -> Optional[str]:
#   def get_current_activity(self,
#                            timeout: Optional[float] = None) -> Optional[str]:
#   def start_screen_pinning(self,
#                            full_activity: str,
#                            timeout: Optional[float] = None):
#   def _fetch_current_task_id(self,
#                              full_activity_name: str,
#                              timeout: Optional[float] = None) -> int:
#   def get_screen_dimensions(self,
#                             timeout: Optional[float] = None) -> Tuple[int, int]:
#   def get_orientation(self, timeout: Optional[float] = None) -> Optional[str]:
#   def rotate_device(self,
#                     orientation: adb_pb2.AdbCall.Rotate.Orientation,
#                     timeout: Optional[float] = None) -> None:
#   def set_touch_indicators(self,
#                            show_touches: bool = True,
#                            pointer_location: bool = True,
#                            timeout: Optional[float] = None) -> None:
#   def set_bar_visibility(self,
#                          navigation: bool = False,
#                          status: bool = False,
#                          timeout: Optional[float] = None) -> Optional[bytes]:
#   def disable_animations(self, timeout: Optional[float] = None):
#   def input_tap(self, x: int, y: int, timeout: Optional[float] = None) -> None:
#   def input_text(self,
#                  input_text: str,
#                  timeout: Optional[float] = None) -> Optional[bytes]:
#   def input_key(self,
#                 key_code: str,
#                 timeout: Optional[float] = None) -> Optional[bytes]:


# Path: android_env/components/app_screen_checker.py
import enum
import re
from typing import Callable, List, Optional, Sequence, Pattern
from absl import logging
from android_env.components import adb_controller as adb_control
from android_env.proto import task_pb2


    child = current_node.find_child(regex_predicate)
    if child is None:
      logging.error('Mismatched regex (%i, %s). current_node: %s', i,
                    regex.pattern, current_node)
      logging.error('Dumpsys activity output: %s', str(dumpsys_activity_output))
      logging.error('Tree root: %s', str(root))
      return None
    else:
      current_node = child
  return True


class AppScreenChecker():
  """Checks that the current app screen matches an expected screen."""

  class Outcome(enum.IntEnum):
    """Possible return vales from checking the current app screen."""
    # The current app screen matches the expected app screen.
    SUCCESS = 0
    # There's no activity to check.
    EMPTY_EXPECTED_ACTIVITY = 1
    # We were unable to determine the current activity.
    FAILED_ACTIVITY_EXTRACTION = 2
    # The current activity does not match the expected activity.
    UNEXPECTED_ACTIVITY = 3
    # The current view hierarchy does not match the expected view hierarchy.
    UNEXPECTED_VIEW_HIERARCHY = 4

  def __init__(self,

               adb_controller: adb_control.AdbController,