diff --git a/README.md b/README.md index 483ff8d..0a4c61b 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,8 @@ $ bazel run //android_env/playground:playground -- \ ### 4. Reinforcement Learning (`dm_env`) -To define MDP tasks with rewards and episode resets, see the +To define MDP tasks with rewards and episode resets (after +`pip install "android-env[rl]"`), see the [Tasks guide](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/tasks_guide.md), [Example tasks](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/example_tasks.md), and diff --git a/README.zh.md b/README.zh.md index 95c8c50..b515ddb 100644 --- a/README.zh.md +++ b/README.zh.md @@ -120,7 +120,8 @@ $ bazel run //android_env/playground:playground -- \ ### 4. 强化学习接入 (`dm_env`) -如需定义包含奖励机制与回合重置的 MDP 任务,请参阅[任务指南](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/tasks_guide.md)、[示例任务库](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/example_tasks.md)以及[详细操作说明](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/instructions.md)。 +如需定义包含奖励机制与回合重置的 MDP 任务(通过 `pip install "android-env[rl]"` +安装后),请参阅[任务指南](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/tasks_guide.md)、[示例任务库](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/example_tasks.md)以及[详细操作说明](https://github.com/google-deepmind/android_env/blob/gh-pages/docs/instructions.md)。 ## 关于 AndroidEnv (About) diff --git a/android_env/BUILD.bazel b/android_env/BUILD.bazel index 4c94cf9..4d9fb19 100644 --- a/android_env/BUILD.bazel +++ b/android_env/BUILD.bazel @@ -3,35 +3,6 @@ load("@rules_python//python:packaging.bzl", "py_package", "py_wheel") package(default_visibility = ["//visibility:public"]) -py_library( - name = "android_env", - srcs = ["__init__.py"], - deps = [ - ":env_interface", - ":loader", - "//android_env/components:android_device", - "//android_env/components:android_device_loader", - "//android_env/components:config_classes", - "//android_env/rl:environment", - ], -) - -py_test( - name = "init_test", - srcs = ["init_test.py"], - legacy_create_init = False, - deps = [ - ":android_env", - ":env_interface", - ":loader", - "//android_env/components:android_device", - "//android_env/components:android_device_loader", - "//android_env/components:config_classes", - "//android_env/rl:environment", - "@pip//absl_py", - ], -) - py_library( name = "env_interface", srcs = ["env_interface.py"], @@ -78,7 +49,6 @@ py_package( name = "android_env_pkg", packages = ["android_env"], deps = [ - ":android_env", ":loader", "//android_env/components:android_device_loader", "//android_env/mcp:android_mcp_server_lib", @@ -112,16 +82,19 @@ py_wheel( ], }, extra_requires = { - "gym": ["gymnasium>=0.29.1"], + "gym": [ + "dm-env>=1.6", + "gymnasium>=0.29.1", + ], "mcp": ["mcp>=1.26,<2"], "playground": ["ml-collections"], + "rl": ["dm-env>=1.6"], }, homepage = "https://github.com/google-deepmind/android_env", license = "Apache License, Version 2.0", python_requires = ">=3.10", requires = [ "absl-py>=2.1.0", - "dm-env>=1.6", "numpy>=2.1.0", "portpicker>=1.6.0", "pillow>=10.4.0", diff --git a/android_env/__init__.py b/android_env/__init__.py deleted file mode 100644 index 24a0301..0000000 --- a/android_env/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""AndroidEnv: The Android Interaction & Learning Platform.""" - -from android_env import env_interface -from android_env import loader -from android_env.components import android_device -from android_env.components import android_device_loader -from android_env.components import config_classes -from android_env.rl import environment as rl_environment - -__version__ = '2.0.0' - -AdbControllerConfig = config_classes.AdbControllerConfig -AndroidDevice = android_device.AndroidDevice -AndroidDeviceConfig = config_classes.AndroidDeviceConfig -AndroidEnv = rl_environment.AndroidEnv -AndroidEnvConfig = config_classes.AndroidEnvConfig -AndroidEnvInterface = env_interface.AndroidEnvInterface -DeviceConnectionConfig = config_classes.DeviceConnectionConfig -EmulatorLauncherConfig = config_classes.EmulatorLauncherConfig -FilesystemTaskConfig = config_classes.FilesystemTaskConfig -TaskConfig = config_classes.TaskConfig -load = loader.load -load_android_device = android_device_loader.load_android_device - -__all__ = ( - '__version__', - 'AdbControllerConfig', - 'AndroidDevice', - 'AndroidDeviceConfig', - 'AndroidEnv', - 'AndroidEnvConfig', - 'AndroidEnvInterface', - 'DeviceConnectionConfig', - 'EmulatorLauncherConfig', - 'FilesystemTaskConfig', - 'TaskConfig', - 'load', - 'load_android_device', -) diff --git a/android_env/components/BUILD.bazel b/android_env/components/BUILD.bazel index e091d93..65fd64d 100644 --- a/android_env/components/BUILD.bazel +++ b/android_env/components/BUILD.bazel @@ -2,11 +2,6 @@ load("@rules_python//python:defs.bzl", "py_library", "py_test") package(default_visibility = ["//visibility:public"]) -py_library( - name = "action_type", - srcs = ["action_type.py"], -) - py_library( name = "adb_call_parser", srcs = ["adb_call_parser.py"], diff --git a/android_env/components/__init__.py b/android_env/components/__init__.py deleted file mode 100644 index 0256ac6..0000000 --- a/android_env/components/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - diff --git a/android_env/components/adb_controller.py b/android_env/components/adb_controller.py index 8273757..863187e 100644 --- a/android_env/components/adb_controller.py +++ b/android_env/components/adb_controller.py @@ -72,7 +72,7 @@ def init_server(self, timeout: float | None = None): """Initialize the ADB server deamon on the given port. This function should be called immediately after initializing the first - adb_controller, and before launching the simulator. + adb_controller, and before launching the emulator or connecting to a device. Args: timeout: A timeout to use for this operation. If not set the default diff --git a/android_env/components/config_classes.py b/android_env/components/config_classes.py index 247e275..9260756 100644 --- a/android_env/components/config_classes.py +++ b/android_env/components/config_classes.py @@ -176,6 +176,6 @@ class AndroidEnvConfig: task_manager: TaskManagerConfig = dataclasses.field( default_factory=TaskManagerConfig ) - simulator: AndroidDeviceConfig = dataclasses.field( + device: AndroidDeviceConfig = dataclasses.field( default_factory=AndroidDeviceConfig ) diff --git a/android_env/components/errors.py b/android_env/components/errors.py index 17b5971..82edc0b 100644 --- a/android_env/components/errors.py +++ b/android_env/components/errors.py @@ -25,35 +25,17 @@ class AndroidEnvError(Exception): class ReadObservationError(AndroidEnvError): - """When the environment is unable to obtain an observation from a simulator.""" + """When the environment is unable to obtain an observation from the device.""" ERROR_CODE = 1 -class CoordinatorError(AndroidEnvError): - """Error raised by the Coordinator.""" - - ERROR_CODE = 2 - - -class TooManyRestartsError(CoordinatorError): - """The number of restarts has exceeded _MAX_RESTART_TRIES.""" - - ERROR_CODE = 3 - - class AdbControllerError(AndroidEnvError): """Errors that can be raised by ADBController.""" ERROR_CODE = 4 -class SimulatorError(AndroidEnvError): - """Errors that can be raised by a simulator.""" - - ERROR_CODE = 5 - - class SendActionError(AndroidEnvError): """Raised when action couldn't be sent successfully.""" @@ -90,10 +72,7 @@ def from_code(code: int, msg: str = '') -> AndroidEnvError | None: code_to_error = { 0: AndroidEnvError, 1: ReadObservationError, - 2: CoordinatorError, - 3: TooManyRestartsError, 4: AdbControllerError, - 5: SimulatorError, 6: SendActionError, 7: StepCommandError, 8: WaitForAppScreenError, diff --git a/android_env/components/errors_test.py b/android_env/components/errors_test.py index b2c7be6..98af9dc 100644 --- a/android_env/components/errors_test.py +++ b/android_env/components/errors_test.py @@ -24,10 +24,7 @@ class ErrorsTest(parameterized.TestCase): @parameterized.parameters( (errors.ReadObservationError, 1), - (errors.CoordinatorError, 2), - (errors.TooManyRestartsError, 3), (errors.AdbControllerError, 4), - (errors.SimulatorError, 5), (errors.SendActionError, 6), (errors.StepCommandError, 7), (errors.WaitForAppScreenError, 8), @@ -42,10 +39,7 @@ def test_error_codes_unique(self): error_codes = set() errors_list = ( errors.ReadObservationError, - errors.CoordinatorError, - errors.TooManyRestartsError, errors.AdbControllerError, - errors.SimulatorError, errors.SendActionError, errors.StepCommandError, errors.WaitForAppScreenError, @@ -57,10 +51,7 @@ def test_error_codes_unique(self): @parameterized.parameters([ errors.ReadObservationError(), - errors.CoordinatorError(), - errors.TooManyRestartsError(), errors.AdbControllerError(), - errors.SimulatorError(), errors.SendActionError(), errors.StepCommandError(), errors.WaitForAppScreenError(), @@ -86,10 +77,7 @@ def test_from_code_unsupported_code(self, code: int): (0, errors.AndroidEnvError, 'hello'), (0, errors.AndroidEnvError, ''), (1, errors.ReadObservationError, 'Could not read obs.'), - (2, errors.CoordinatorError, 'Some error'), - (3, errors.TooManyRestartsError, 'Too many already...'), (4, errors.AdbControllerError, 'Some adb error...'), - (5, errors.SimulatorError, 'Simulator is not coping.'), (6, errors.SendActionError, 'Could not send action.'), (7, errors.StepCommandError, 'Some issue setting up the task.'), (8, errors.WaitForAppScreenError, 'Waited for too long!'), diff --git a/android_env/init_test.py b/android_env/init_test.py deleted file mode 100644 index 91f57de..0000000 --- a/android_env/init_test.py +++ /dev/null @@ -1,70 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tests for top-level android_env package exports.""" - -from absl.testing import absltest -import android_env -from android_env import env_interface -from android_env import loader -from android_env.components import android_device -from android_env.components import android_device_loader -from android_env.components import config_classes -from android_env.rl import environment as rl_environment - - -class InitTest(absltest.TestCase): - - def test_version(self): - self.assertEqual(android_env.__version__, '2.0.0') - - def test_public_exports(self): - self.assertIs( - android_env.AdbControllerConfig, config_classes.AdbControllerConfig - ) - self.assertIs(android_env.AndroidDevice, android_device.AndroidDevice) - self.assertIs( - android_env.AndroidDeviceConfig, config_classes.AndroidDeviceConfig - ) - self.assertIs(android_env.AndroidEnv, rl_environment.AndroidEnv) - self.assertIs(android_env.AndroidEnvConfig, config_classes.AndroidEnvConfig) - self.assertIs( - android_env.AndroidEnvInterface, env_interface.AndroidEnvInterface - ) - self.assertIs( - android_env.DeviceConnectionConfig, - config_classes.DeviceConnectionConfig, - ) - self.assertIs( - android_env.EmulatorLauncherConfig, - config_classes.EmulatorLauncherConfig, - ) - self.assertIs( - android_env.FilesystemTaskConfig, config_classes.FilesystemTaskConfig - ) - self.assertIs(android_env.TaskConfig, config_classes.TaskConfig) - self.assertIs(android_env.load, loader.load) - self.assertIs( - android_env.load_android_device, - android_device_loader.load_android_device, - ) - - def test_all_exports_present_on_module(self): - for symbol in android_env.__all__: - self.assertTrue(hasattr(android_env, symbol), msg=f'Missing {symbol}') - - -if __name__ == '__main__': - absltest.main() diff --git a/android_env/loader.py b/android_env/loader.py index 4392ec0..bb1bbda 100644 --- a/android_env/loader.py +++ b/android_env/loader.py @@ -46,12 +46,12 @@ def load( ) -> env_interface.AndroidEnvInterface: """Loads an AndroidEnv instance.""" - if isinstance(config.simulator, config_classes.AndroidDeviceConfig): - device = android_device_loader.load_android_device(config.simulator) + if isinstance(config.device, config_classes.AndroidDeviceConfig): + device = android_device_loader.load_android_device(config.device) env = rl_environment.AndroidEnv(device=device) if config.task != config_classes.TaskConfig(): task = _load_task(config.task) env = task_wrapper.TaskWrapper(env, task=task, config=config.task_manager) return env - raise ValueError(f'Unsupported simulator config: {config.simulator}') + raise ValueError(f'Unsupported device config: {config.device}') diff --git a/android_env/loader_test.py b/android_env/loader_test.py index 46a99d2..829f915 100644 --- a/android_env/loader_test.py +++ b/android_env/loader_test.py @@ -34,10 +34,10 @@ class LoaderTest(absltest.TestCase): @mock.patch.object(rl_environment, 'AndroidEnv', autospec=True) def test_load_android_device(self, mock_android_env, mock_loader): config = config_classes.AndroidEnvConfig( - simulator=config_classes.AndroidDeviceConfig() + device=config_classes.AndroidDeviceConfig() ) env = loader.load(config) - mock_loader.assert_called_once_with(config.simulator) + mock_loader.assert_called_once_with(config.device) mock_android_env.assert_called_once_with(device=mock_loader.return_value) self.assertEqual(env, mock_android_env.return_value) @@ -54,11 +54,11 @@ def test_load_android_device_with_task( mock_open.return_value.read.return_value = 'id: "device_task"' config = config_classes.AndroidEnvConfig( task=config_classes.FilesystemTaskConfig(path='~/some/path.textproto'), - simulator=config_classes.AndroidDeviceConfig(), + device=config_classes.AndroidDeviceConfig(), ) env = loader.load(config) mock_open.assert_any_call(os.path.expanduser('~/some/path.textproto'), 'r') - mock_loader.assert_called_once_with(config.simulator) + mock_loader.assert_called_once_with(config.device) mock_android_env.assert_called_once_with(device=mock_loader.return_value) expected_task = task_pb2.Task(id='device_task') mock_task_wrapper.assert_called_once_with( @@ -68,11 +68,11 @@ def test_load_android_device_with_task( ) self.assertEqual(env, mock_task_wrapper.return_value) - def test_load_unsupported_simulator_raises(self): + def test_load_unsupported_config_raises(self): config = config_classes.AndroidEnvConfig( - simulator=None + device=None ) - with self.assertRaisesRegex(ValueError, 'Unsupported simulator config'): + with self.assertRaisesRegex(ValueError, 'Unsupported .* config'): loader.load(config) diff --git a/android_env/playground/device_runner.py b/android_env/playground/device_runner.py index e1553cb..48192d8 100644 --- a/android_env/playground/device_runner.py +++ b/android_env/playground/device_runner.py @@ -469,7 +469,7 @@ def set_status(text: str): # Extract device config if wrapped in an AndroidEnvConfig. if isinstance(config, config_classes.AndroidEnvConfig): - device_config = config.simulator + device_config = config.device else: device_config = config diff --git a/android_env/playground/device_runner_test.py b/android_env/playground/device_runner_test.py index 218ba82..016b409 100644 --- a/android_env/playground/device_runner_test.py +++ b/android_env/playground/device_runner_test.py @@ -532,7 +532,7 @@ def test_setup_device_success(self, mock_loader): state = state_lib.PlaygroundState() config = config_classes.AndroidEnvConfig( - simulator=config_classes.AndroidDeviceConfig() + device=config_classes.AndroidDeviceConfig() ) dev, orientation, pixels = device_runner.setup_device(state, config) diff --git a/android_env/proto/__init__.py b/android_env/proto/__init__.py deleted file mode 100644 index 0256ac6..0000000 --- a/android_env/proto/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - diff --git a/android_env/proto/a11y/__init__.py b/android_env/proto/a11y/__init__.py deleted file mode 100644 index 0256ac6..0000000 --- a/android_env/proto/a11y/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - diff --git a/android_env/rl/BUILD.bazel b/android_env/rl/BUILD.bazel index 4250cde..6ea63d8 100644 --- a/android_env/rl/BUILD.bazel +++ b/android_env/rl/BUILD.bazel @@ -2,6 +2,11 @@ load("@rules_python//python:defs.bzl", "py_library", "py_test") package(default_visibility = ["//visibility:public"]) +py_library( + name = "action_type", + srcs = ["action_type.py"], +) + py_library( name = "dumpsys_thread", srcs = ["dumpsys_thread.py"], @@ -26,9 +31,9 @@ py_library( name = "environment", srcs = ["environment.py"], deps = [ + ":action_type", ":specs", "//android_env:env_interface", - "//android_env/components:action_type", "//android_env/components:android_device", "//android_env/components:telemetry", "//android_env/proto:adb_py_pb2", @@ -44,8 +49,8 @@ py_test( srcs = ["environment_test.py"], legacy_create_init = False, deps = [ + ":action_type", ":environment", - "//android_env/components:action_type", "//android_env/components:android_device", "//android_env/components:config_classes", "//android_env/components:device_connection", @@ -129,7 +134,7 @@ py_library( name = "specs", srcs = ["specs.py"], deps = [ - "//android_env/components:action_type", + ":action_type", "//android_env/proto:task_py_pb2", "@pip//dm_env", "@pip//numpy", diff --git a/android_env/components/action_type.py b/android_env/rl/action_type.py similarity index 100% rename from android_env/components/action_type.py rename to android_env/rl/action_type.py diff --git a/android_env/rl/environment.py b/android_env/rl/environment.py index e633ba0..18063d5 100644 --- a/android_env/rl/environment.py +++ b/android_env/rl/environment.py @@ -24,11 +24,11 @@ from absl import logging from android_env import env_interface -from android_env.components import action_type from android_env.components import android_device from android_env.components import telemetry from android_env.proto import adb_pb2 from android_env.proto import device_env_service_pb2 +from android_env.rl import action_type from android_env.rl.specs import base_action_spec from android_env.rl.specs import base_observation_spec import dm_env diff --git a/android_env/rl/environment_test.py b/android_env/rl/environment_test.py index 0203cec..29216aa 100644 --- a/android_env/rl/environment_test.py +++ b/android_env/rl/environment_test.py @@ -17,13 +17,13 @@ from unittest import mock from absl.testing import absltest -from android_env.components import action_type from android_env.components import android_device from android_env.components import config_classes from android_env.components import device_connection from android_env.components import telemetry from android_env.proto import adb_pb2 from android_env.proto import device_env_service_pb2 +from android_env.rl import action_type from android_env.rl import environment as android_device_env import numpy as np diff --git a/android_env/rl/log_stream.py b/android_env/rl/log_stream.py index 9643c89..47b1b0a 100644 --- a/android_env/rl/log_stream.py +++ b/android_env/rl/log_stream.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Abstract class for handling a stream of logs from a simulator.""" +"""Abstract class for handling a stream of logs from an Android device.""" import abc from collections.abc import Generator, Sequence @@ -22,7 +22,7 @@ class LogStream(metaclass=abc.ABCMeta): - """Manages the stream of logs output by a simulator.""" + """Manages the stream of logs output by an Android device.""" def __init__(self, verbose: bool = False): self._verbose = verbose diff --git a/android_env/rl/logcat_thread.py b/android_env/rl/logcat_thread.py index aad4692..cbc8080 100644 --- a/android_env/rl/logcat_thread.py +++ b/android_env/rl/logcat_thread.py @@ -42,7 +42,7 @@ def __init__(self, log_stream: log_stream_lib.LogStream): info on `logcat`. Args: - log_stream: Stream of logs from simulator. + log_stream: Stream of logs from the Android device. """ self._log_stream = log_stream diff --git a/android_env/rl/specs.py b/android_env/rl/specs.py index d6791fa..d68d846 100644 --- a/android_env/rl/specs.py +++ b/android_env/rl/specs.py @@ -19,8 +19,8 @@ from typing import Any, Final, Mapping -from android_env.components import action_type from android_env.proto import task_pb2 +from android_env.rl import action_type from dm_env import specs import numpy as np diff --git a/android_env/wrappers/BUILD.bazel b/android_env/wrappers/BUILD.bazel index 726a91e..bf0521a 100644 --- a/android_env/wrappers/BUILD.bazel +++ b/android_env/wrappers/BUILD.bazel @@ -31,7 +31,7 @@ py_library( deps = [ ":base_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//dm_env", "@pip//numpy", ], @@ -44,7 +44,7 @@ py_test( deps = [ ":discrete_action_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//absl_py", "@pip//numpy", ], @@ -56,7 +56,7 @@ py_library( deps = [ ":base_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//dm_env", "@pip//numpy", ], @@ -69,7 +69,7 @@ py_test( deps = [ ":rate_limit_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//absl_py", "@pip//dm_env", "@pip//numpy", @@ -178,7 +178,7 @@ py_library( deps = [ ":base_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "//android_env/rl:pixel_fns", "@pip//dm_env", "@pip//numpy", @@ -192,7 +192,7 @@ py_test( deps = [ ":last_action_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//absl_py", "@pip//dm_env", "@pip//numpy", @@ -205,7 +205,7 @@ py_library( deps = [ ":base_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//dm_env", "@pip//numpy", ], @@ -218,7 +218,7 @@ py_test( deps = [ ":tap_action_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//absl_py", "@pip//dm_env", "@pip//numpy", @@ -231,7 +231,7 @@ py_library( deps = [ ":base_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//dm_env", "@pip//numpy", ], @@ -244,7 +244,7 @@ py_test( deps = [ ":swipe_action_wrapper", "//android_env:env_interface", - "//android_env/components:action_type", + "//android_env/rl:action_type", "@pip//absl_py", "@pip//dm_env", "@pip//numpy", diff --git a/android_env/wrappers/__init__.py b/android_env/wrappers/__init__.py deleted file mode 100644 index 0256ac6..0000000 --- a/android_env/wrappers/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - diff --git a/android_env/wrappers/discrete_action_wrapper.py b/android_env/wrappers/discrete_action_wrapper.py index 1ccdff1..62ab36a 100644 --- a/android_env/wrappers/discrete_action_wrapper.py +++ b/android_env/wrappers/discrete_action_wrapper.py @@ -19,7 +19,7 @@ from typing import cast from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import base_wrapper import dm_env from dm_env import specs diff --git a/android_env/wrappers/discrete_action_wrapper_test.py b/android_env/wrappers/discrete_action_wrapper_test.py index ce72aa9..e5a5224 100644 --- a/android_env/wrappers/discrete_action_wrapper_test.py +++ b/android_env/wrappers/discrete_action_wrapper_test.py @@ -19,7 +19,7 @@ from absl.testing import absltest from android_env import env_interface -from android_env.components import action_type as action_type_lib +from android_env.rl import action_type as action_type_lib from android_env.wrappers import discrete_action_wrapper from dm_env import specs import numpy as np diff --git a/android_env/wrappers/last_action_wrapper.py b/android_env/wrappers/last_action_wrapper.py index 69e42e3..94ea0c9 100644 --- a/android_env/wrappers/last_action_wrapper.py +++ b/android_env/wrappers/last_action_wrapper.py @@ -17,7 +17,7 @@ from typing import cast from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.rl import pixel_fns from android_env.wrappers import base_wrapper import dm_env diff --git a/android_env/wrappers/last_action_wrapper_test.py b/android_env/wrappers/last_action_wrapper_test.py index 71911c9..4024b48 100644 --- a/android_env/wrappers/last_action_wrapper_test.py +++ b/android_env/wrappers/last_action_wrapper_test.py @@ -20,7 +20,7 @@ from absl.testing import absltest from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import last_action_wrapper import dm_env from dm_env import specs diff --git a/android_env/wrappers/rate_limit_wrapper.py b/android_env/wrappers/rate_limit_wrapper.py index ab3895a..a91d964 100644 --- a/android_env/wrappers/rate_limit_wrapper.py +++ b/android_env/wrappers/rate_limit_wrapper.py @@ -19,7 +19,7 @@ import time from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import base_wrapper import dm_env import numpy as np diff --git a/android_env/wrappers/rate_limit_wrapper_test.py b/android_env/wrappers/rate_limit_wrapper_test.py index 5e1b8ad..a2213cc 100644 --- a/android_env/wrappers/rate_limit_wrapper_test.py +++ b/android_env/wrappers/rate_limit_wrapper_test.py @@ -22,7 +22,7 @@ from absl.testing import absltest from absl.testing import parameterized from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import rate_limit_wrapper import dm_env from dm_env import specs diff --git a/android_env/wrappers/swipe_action_wrapper.py b/android_env/wrappers/swipe_action_wrapper.py index 2308b18..6f9f79e 100644 --- a/android_env/wrappers/swipe_action_wrapper.py +++ b/android_env/wrappers/swipe_action_wrapper.py @@ -19,7 +19,7 @@ from typing import Any, cast from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import base_wrapper import dm_env from dm_env import specs diff --git a/android_env/wrappers/swipe_action_wrapper_test.py b/android_env/wrappers/swipe_action_wrapper_test.py index 20caf4b..a2455c0 100644 --- a/android_env/wrappers/swipe_action_wrapper_test.py +++ b/android_env/wrappers/swipe_action_wrapper_test.py @@ -18,7 +18,7 @@ from absl.testing import absltest from absl.testing import parameterized from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import swipe_action_wrapper import dm_env from dm_env import specs diff --git a/android_env/wrappers/tap_action_wrapper.py b/android_env/wrappers/tap_action_wrapper.py index 541cfa8..6c57410 100644 --- a/android_env/wrappers/tap_action_wrapper.py +++ b/android_env/wrappers/tap_action_wrapper.py @@ -19,7 +19,7 @@ from typing import Any from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import base_wrapper import dm_env import numpy as np diff --git a/android_env/wrappers/tap_action_wrapper_test.py b/android_env/wrappers/tap_action_wrapper_test.py index 2e9edeb..013bfb9 100644 --- a/android_env/wrappers/tap_action_wrapper_test.py +++ b/android_env/wrappers/tap_action_wrapper_test.py @@ -19,7 +19,7 @@ from absl.testing import absltest from absl.testing import parameterized from android_env import env_interface -from android_env.components import action_type +from android_env.rl import action_type from android_env.wrappers import tap_action_wrapper import dm_env from dm_env import specs diff --git a/examples/__init__.py b/examples/__init__.py deleted file mode 100644 index 0256ac6..0000000 --- a/examples/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# coding=utf-8 -# Copyright 2026 DeepMind Technologies Limited. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - diff --git a/examples/run_acme_agent.py b/examples/run_acme_agent.py index 6454d4c..45b2edc 100644 --- a/examples/run_acme_agent.py +++ b/examples/run_acme_agent.py @@ -32,7 +32,7 @@ from android_env.wrappers import tap_action_wrapper import haiku as hk -# Simulator args +# Device / Emulator args flags.DEFINE_string('avd_name', None, 'Name of AVD to use.') flags.DEFINE_string('android_avd_home', '~/.android/avd', 'Path to AVD.') flags.DEFINE_string('android_sdk_root', '~/Android/Sdk', 'Path to SDK.') @@ -88,7 +88,7 @@ def env_factory(seed): del seed config = config_classes.AndroidEnvConfig( task=config_classes.FilesystemTaskConfig(path=FLAGS.task_path), - simulator=config_classes.AndroidDeviceConfig( + device=config_classes.AndroidDeviceConfig( emulator_launcher=config_classes.EmulatorLauncherConfig( emulator_path=FLAGS.emulator_path, android_sdk_root=FLAGS.android_sdk_root, diff --git a/examples/run_random_agent.py b/examples/run_random_agent.py index 909f422..64fc5af 100644 --- a/examples/run_random_agent.py +++ b/examples/run_random_agent.py @@ -25,7 +25,7 @@ FLAGS = flags.FLAGS -# Simulator args. +# Device / Emulator args. flags.DEFINE_string('avd_name', None, 'Name of AVD to use.') flags.DEFINE_string('android_avd_home', '~/.android/avd', 'Path to AVD.') flags.DEFINE_string('android_sdk_root', '~/Android/Sdk', 'Path to SDK.') @@ -47,7 +47,7 @@ def main(_): config = config_classes.AndroidEnvConfig( task=config_classes.FilesystemTaskConfig(path=FLAGS.task_path), - simulator=config_classes.AndroidDeviceConfig( + device=config_classes.AndroidDeviceConfig( emulator_launcher=config_classes.EmulatorLauncherConfig( emulator_path=FLAGS.emulator_path, android_sdk_root=FLAGS.android_sdk_root, diff --git a/pyproject.toml b/pyproject.toml index 8db73f3..b6508da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,15 +8,14 @@ build-backend = "setuptools.build_meta" [project] name = "android-env" version = "2.0.0" -description = "AndroidEnv environment and library for training agents." +description = "AndroidEnv: The Android Interaction & Learning Platform" authors = [{name = "DeepMind"}] license = {file = "LICENSE"} -readme = {text = "Read the README at https://github.com/google-deepmind/android_env for more information.", content-type = "text/plain"} +readme = "README.md" keywords = ["Android", "OS", "reinforcement-learning"] requires-python = ">=3.10" dependencies = [ "absl-py>=2.1.0", - "dm_env>=1.6", "numpy>=2.1.0", "portpicker>=1.6.0", "protobuf>=6,<8", @@ -27,18 +26,29 @@ dependencies = [ [project.optional-dependencies] testing = [ + "dm-env>=1.6", "gymnasium", "pytype", ] -acme = ["dm-acme"] -gym = ["gymnasium>=0.29.1"] +acme = [ + "dm-acme", + "dm-env>=1.6", +] +gym = [ + "dm-env>=1.6", + "gymnasium>=0.29.1", +] mcp = ["mcp>=1.26,<2"] playground = ["ml-collections"] +rl = ["dm-env>=1.6"] [project.scripts] android-env-mcp = "android_env.mcp.android_mcp_server:run" android-env-playground = "android_env.playground.playground:run" +[tool.setuptools.packages.find] +include = ["android_env*"] + [tool.setuptools.package-data] "android_env.apps.java.com.google.androidenv.core" = ["*.apk"] "android_env.components" = ["*.textproto"]