From 0b10614f7b76818c773d1be69855e6436c1737bd Mon Sep 17 00:00:00 2001 From: Russell Martin Date: Wed, 1 Nov 2023 10:51:52 -0400 Subject: [PATCH] Support downloading Android emulator system image on Linux aarch64 --- changes/1519.misc.rst | 1 + src/briefcase/integrations/android_sdk.py | 28 +++++++++++++------ .../AndroidSDK/test__create_emulator.py | 6 ++-- .../AndroidSDK/test_create_emulator.py | 3 +- .../android_sdk/AndroidSDK/test_properties.py | 2 +- .../android_sdk/AndroidSDK/test_verify.py | 1 + .../AndroidSDK/test_verify_system_image.py | 11 ++++---- 7 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 changes/1519.misc.rst diff --git a/changes/1519.misc.rst b/changes/1519.misc.rst new file mode 100644 index 000000000..9323549ce --- /dev/null +++ b/changes/1519.misc.rst @@ -0,0 +1 @@ +It is now possible to create an Android emulator AVD on Linux for arm64. diff --git a/src/briefcase/integrations/android_sdk.py b/src/briefcase/integrations/android_sdk.py index 5c7d6075c..ddfbc772b 100644 --- a/src/briefcase/integrations/android_sdk.py +++ b/src/briefcase/integrations/android_sdk.py @@ -142,15 +142,25 @@ def env(self) -> dict[str, str]: @property def emulator_abi(self) -> str: """The ABI to use for the Android emulator.""" - if self.tools.host_arch == "arm64" and self.tools.host_os == "Darwin": - return "arm64-v8a" - if self.tools.host_arch in ("x86_64", "AMD64"): - return "x86_64" - - raise BriefcaseCommandError( - "The Android emulator does not currently support " - f"{self.tools.host_os} {self.tools.host_arch} hardware." - ) + try: + return { + "Linux": { + "x86_64": "x86_64", + "aarch64": "arm64-v8a", + }, + "Darwin": { + "x86_64": "x86_64", + "arm64": "arm64-v8a", + }, + "Windows": { + "AMD64": "x86_64", + }, + }[self.tools.host_os][self.tools.host_arch] + except KeyError: + raise BriefcaseCommandError( + "The Android emulator does not currently support " + f"{self.tools.host_os} {self.tools.host_arch} hardware." + ) @property def DEFAULT_DEVICE_TYPE(self) -> str: diff --git a/tests/integrations/android_sdk/AndroidSDK/test__create_emulator.py b/tests/integrations/android_sdk/AndroidSDK/test__create_emulator.py index a6e6b7408..9a304e67e 100644 --- a/tests/integrations/android_sdk/AndroidSDK/test__create_emulator.py +++ b/tests/integrations/android_sdk/AndroidSDK/test__create_emulator.py @@ -38,8 +38,9 @@ def android_sdk(android_sdk) -> AndroidSDK: [ ("Darwin", "x86_64", "x86_64"), ("Darwin", "arm64", "arm64-v8a"), - ("Windows", "x86_64", "x86_64"), + ("Windows", "AMD64", "x86_64"), ("Linux", "x86_64", "x86_64"), + ("Linux", "aarch64", "arm64-v8a"), ], ) def test_create_emulator( @@ -117,8 +118,9 @@ def test_create_emulator( [ ("Darwin", "x86_64", "x86_64"), ("Darwin", "arm64", "arm64-v8a"), - ("Windows", "x86_64", "x86_64"), + ("Windows", "AMD64", "x86_64"), ("Linux", "x86_64", "x86_64"), + ("Linux", "aarch64", "arm64-v8a"), ], ) def test_create_emulator_with_defaults( diff --git a/tests/integrations/android_sdk/AndroidSDK/test_create_emulator.py b/tests/integrations/android_sdk/AndroidSDK/test_create_emulator.py index 1227a6ef6..bddbcef0f 100644 --- a/tests/integrations/android_sdk/AndroidSDK/test_create_emulator.py +++ b/tests/integrations/android_sdk/AndroidSDK/test_create_emulator.py @@ -35,8 +35,9 @@ def android_sdk(android_sdk) -> AndroidSDK: [ ("Darwin", "x86_64", "x86_64"), ("Darwin", "arm64", "arm64-v8a"), - ("Windows", "x86_64", "x86_64"), + ("Windows", "AMD64", "x86_64"), ("Linux", "x86_64", "x86_64"), + ("Linux", "aarch64", "arm64-v8a"), ], ) def test_create_emulator( diff --git a/tests/integrations/android_sdk/AndroidSDK/test_properties.py b/tests/integrations/android_sdk/AndroidSDK/test_properties.py index c37e6e744..9960c91d4 100644 --- a/tests/integrations/android_sdk/AndroidSDK/test_properties.py +++ b/tests/integrations/android_sdk/AndroidSDK/test_properties.py @@ -107,9 +107,9 @@ def test_managed_install(mock_tools, android_sdk): [ ("Darwin", "x86_64", "x86_64"), ("Darwin", "arm64", "arm64-v8a"), - ("Windows", "x86_64", "x86_64"), ("Windows", "AMD64", "x86_64"), ("Linux", "x86_64", "x86_64"), + ("Linux", "aarch64", "arm64-v8a"), ], ) def test_emulator_abi(mock_tools, android_sdk, host_os, host_arch, emulator_abi): diff --git a/tests/integrations/android_sdk/AndroidSDK/test_verify.py b/tests/integrations/android_sdk/AndroidSDK/test_verify.py index 012f36c37..43aa14a43 100644 --- a/tests/integrations/android_sdk/AndroidSDK/test_verify.py +++ b/tests/integrations/android_sdk/AndroidSDK/test_verify.py @@ -104,6 +104,7 @@ def test_unsupported_arch(mock_tools): ("Darwin", "arm64"), ("Darwin", "x86_64"), ("Linux", "x86_64"), + ("Linux", "aarch64"), ("Windows", "AMD64"), ], ) diff --git a/tests/integrations/android_sdk/AndroidSDK/test_verify_system_image.py b/tests/integrations/android_sdk/AndroidSDK/test_verify_system_image.py index ecf121c10..6acc5e540 100644 --- a/tests/integrations/android_sdk/AndroidSDK/test_verify_system_image.py +++ b/tests/integrations/android_sdk/AndroidSDK/test_verify_system_image.py @@ -1,4 +1,5 @@ import os +import platform from subprocess import CalledProcessError import pytest @@ -10,7 +11,7 @@ "host_os, host_arch", [ ("Windows", "arm64"), - ("Linux", "arm64"), + ("Linux", "armv7l"), ], ) def test_unsupported_abi(mock_tools, android_sdk, host_os, host_arch): @@ -56,7 +57,7 @@ def test_incompatible_abi(mock_tools, android_sdk, capsys): """If the system image doesn't match the emulator ABI, warn the user, but continue.""" # Mock the host arch - mock_tools.host_arch = "x86_64" + mock_tools.host_arch = "AMD64" if platform.system() == "Windows" else "x86_64" # Verify a system image that doesn't match the host architecture android_sdk.verify_system_image("system-images;android-31;default;anything") @@ -79,7 +80,7 @@ def test_incompatible_abi(mock_tools, android_sdk, capsys): def test_existing_system_image(mock_tools, android_sdk): """If the system image already exists, don't attempt to download it again.""" # Mock the host arch - mock_tools.host_arch = "x86_64" + mock_tools.host_arch = "AMD64" if platform.system() == "Windows" else "x86_64" # Mock the existence of a system image ( @@ -96,7 +97,7 @@ def test_existing_system_image(mock_tools, android_sdk): def test_new_system_image(mock_tools, android_sdk): """If the system image doesn't exist locally, it will be installed.""" # Mock the host arch - mock_tools.host_arch = "x86_64" + mock_tools.host_arch = "AMD64" if platform.system() == "Windows" else "x86_64" # Verify the system image, triggering a download android_sdk.verify_system_image("system-images;android-31;default;x86_64") @@ -116,7 +117,7 @@ def test_new_system_image(mock_tools, android_sdk): def test_problem_downloading_system_image(mock_tools, android_sdk): """If there is a failure downloading the system image, an error is raised.""" # Mock the host arch - mock_tools.host_arch = "x86_64" + mock_tools.host_arch = "AMD64" if platform.system() == "Windows" else "x86_64" # Mock a failure condition on subprocess.run mock_tools.subprocess.run.side_effect = CalledProcessError(