Skip to content

Commit 598c0c1

Browse files
metin-armmarcbonnici
authored andcommitted
tools/android: Add support for creating Android virtual devices
Introduce ``tools/android/install_base.sh`` [1] script to install Android command line tools including necessary platforms and system-images for Linux and create Android Virtual Devices (AVD) for Pixel 6 with Android v12 & v14 as well as an Android virtual *desktop* device (v13) for ChromeOS tests. [1] Forked from https://github.com/ARM-software/lisa/blob/main/install_base.sh Signed-off-by: Metin Kaya <metin.kaya@arm.com>
1 parent a1718c3 commit 598c0c1

File tree

9 files changed

+429
-0
lines changed

9 files changed

+429
-0
lines changed

doc/tools.rst

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Tools
2+
=====
3+
4+
Android
5+
-------
6+
7+
``tools/android/install_base.sh`` script installs Android command line tools
8+
for Linux and creates Android Virtual Devices (AVD).
9+
10+
The script creates ``android-sdk-linux`` directory under ``tools/android`` and
11+
sets it as ``ANDROID_HOME`` directory (see
12+
https://developer.android.com/tools/variables).
13+
14+
Your ``ANDROID_USER_HOME`` and ``ANDROID_EMULATOR_HOME`` environment variables
15+
point to ``tools/android/android-sdk-linux/.android``. Hence, removing
16+
``android-sdk-linux`` folder will clean all artefacts of ``install_base.sh``.
17+
18+
It fetches Android command line tools, then installs Android SDK
19+
Platform-Tools, SDK Platform 31 (for Android 12) & 34 (for Android 14), and
20+
Google APIs for platforms 31 & 34 for the associated ABI type.
21+
22+
Finally the script creates AVDs per Pixel 6 for Android 12 & 14.
23+
24+
Shell commands below illustrate how to list available AVDs and run them via
25+
Android emulator:
26+
27+
.. code:: shell
28+
29+
ANDROID_HOME="/devlib/tools/android/android-sdk-linux"
30+
export ANDROID_HOME
31+
EMULATOR="${ANDROID_HOME}/emulator/emulator"
32+
33+
export ANDROID_EMULATOR_HOME="${ANDROID_HOME}/.android"
34+
35+
# List available AVDs:
36+
${EMULATOR} -list-avds
37+
38+
# Run devlib-p6-14 AVD in emulator:
39+
${EMULATOR} -avd devlib-p6-14 -no-window -no-snapshot -memory 2048 &
40+
41+
# After ~30 seconds, the emulated device will be ready:
42+
adb -s emulator-5554 shell "lsmod"
43+

tools/android/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
android-sdk-linux/

tools/android/install_base.sh

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
#!/usr/bin/env bash
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Copyright (C) 2024, ARM Limited and contributors.
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
8+
# not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
# Forked from https://github.com/ARM-software/lisa/blob/main/install_base.sh
20+
#
21+
22+
# shellcheck disable=SC2317
23+
24+
# Read standard /etc/os-release file and extract the needed field lsb_release
25+
# binary is not installed on all distro, but that file is found pretty much
26+
# anywhere.
27+
read_os_release() {
28+
local field_name=${1}
29+
# shellcheck source=/etc/os-release
30+
(source /etc/os-release &> /dev/null && printf "%s" "${!field_name}")
31+
}
32+
33+
# Test the value of a field in /etc/os-release
34+
test_os_release() {
35+
local field_name=${1}
36+
local value=${2}
37+
38+
if [[ "$(read_os_release "${field_name}")" == "${value}" ]]; then
39+
return 0
40+
else
41+
return 1
42+
fi
43+
}
44+
45+
function set_host_arch
46+
{
47+
# Google ABI type for Arm platforms
48+
HOST_ARCH="arm64-v8a"
49+
50+
local machine
51+
machine=$(uname -m)
52+
if [[ "${machine}" == "x86"* ]]; then
53+
HOST_ARCH=${machine}
54+
fi
55+
}
56+
57+
ANDROID_HOME="$(dirname "${0}")/android-sdk-linux"
58+
export ANDROID_HOME
59+
export ANDROID_USER_HOME="${ANDROID_HOME}/.android"
60+
61+
mkdir -p "${ANDROID_HOME}/cmdline-tools"
62+
63+
CMDLINE_VERSION=${CMDLINE_VERSION:-"11076708"}
64+
65+
cleanup_android_home() {
66+
echo "Cleaning up Android SDK: ${ANDROID_HOME}"
67+
rm -rf "${ANDROID_HOME}"
68+
mkdir -p "${ANDROID_HOME}/cmdline-tools"
69+
}
70+
71+
install_android_sdk_manager() {
72+
echo "Installing Android SDK manager ..."
73+
74+
# URL taken from "Command line tools only": https://developer.android.com/studio
75+
local url="https://dl.google.com/android/repository/commandlinetools-linux-${CMDLINE_VERSION}_latest.zip"
76+
77+
echo "Downloading Android SDK manager from: $url"
78+
wget -qO- "${url}" | bsdtar -xf- -C "${ANDROID_HOME}/cmdline-tools"
79+
80+
echo "Moving commandlinetools to cmdline-tools/latest..."
81+
# First, clear cmdline-tools/latest if it exists.
82+
rm -rf "${ANDROID_HOME}/cmdline-tools/latest"
83+
mv "${ANDROID_HOME}/cmdline-tools/cmdline-tools" "${ANDROID_HOME}/cmdline-tools/latest"
84+
85+
chmod +x -R "${ANDROID_HOME}/cmdline-tools/latest/bin"
86+
87+
yes | (call_android_sdkmanager --licenses || true)
88+
89+
echo "Creating the link to skins directory..."
90+
readlink "${ANDROID_HOME}/skins" > /dev/null 2>&1 || ln -sf "../skins" "${ANDROID_HOME}/skins"
91+
}
92+
93+
# Android SDK is picky on Java version, so we need to set JAVA_HOME manually.
94+
# In most distributions, Java is installed under /usr/lib/jvm so use that.
95+
# according to the distribution
96+
ANDROID_SDK_JAVA_VERSION=17
97+
find_java_home() {
98+
_JAVA_BIN=$(find -L /usr/lib/jvm -path "*${ANDROID_SDK_JAVA_VERSION}*/bin/java" -not -path '*/jre/bin/*' -print -quit)
99+
_JAVA_HOME=$(dirname "${_JAVA_BIN}")/../
100+
101+
echo "Found JAVA_HOME=${_JAVA_HOME}"
102+
}
103+
104+
call_android_sdk() {
105+
local tool="${ANDROID_HOME}/cmdline-tools/latest/bin/${1}"
106+
shift
107+
JAVA_HOME=${_JAVA_HOME} "${tool}" "$@"
108+
}
109+
110+
call_android_sdkmanager() {
111+
call_android_sdk sdkmanager "$@"
112+
}
113+
114+
call_android_avdmanager() {
115+
call_android_sdk avdmanager "$@"
116+
}
117+
118+
# Needs install_android_sdk_manager first
119+
install_android_tools() {
120+
yes | call_android_sdkmanager --verbose --channel=0 --install "platform-tools"
121+
yes | call_android_sdkmanager --verbose --channel=0 --install "platforms;android-31"
122+
yes | call_android_sdkmanager --verbose --channel=0 --install "platforms;android-33"
123+
yes | call_android_sdkmanager --verbose --channel=0 --install "platforms;android-34"
124+
yes | call_android_sdkmanager --verbose --channel=0 --install "system-images;android-31;google_apis;${HOST_ARCH}"
125+
yes | call_android_sdkmanager --verbose --channel=0 --install "system-images;android-33;android-desktop;${HOST_ARCH}"
126+
yes | call_android_sdkmanager --verbose --channel=0 --install "system-images;android-34;google_apis;${HOST_ARCH}"
127+
}
128+
129+
create_android_vds() {
130+
local vd_name
131+
132+
vd_name="devlib-p6-12"
133+
echo "Creating virtual device \"${vd_name}\" (Pixel 6 - Android 12)..."
134+
echo no | call_android_avdmanager -s create avd -n "${vd_name}" -k "system-images;android-31;google_apis;${HOST_ARCH}" --skin pixel_6 -b "${HOST_ARCH}" -f
135+
136+
vd_name="devlib-p6-14"
137+
echo "Creating virtual device \"${vd_name}\" (Pixel 6 - Android 14)..."
138+
echo no | call_android_avdmanager -s create avd -n "${vd_name}" -k "system-images;android-34;google_apis;${HOST_ARCH}" --skin pixel_6 -b "${HOST_ARCH}" -f
139+
140+
vd_name="devlib-chromeos"
141+
echo "Creating virtual device \"${vd_name}\" (ChromeOS - Android 13, Pixel tablet)..."
142+
echo no | call_android_avdmanager -s create avd -n "${vd_name}" -k "system-images;android-33;android-desktop;${HOST_ARCH}" --skin pixel_tablet -b "${HOST_ARCH}" -f
143+
}
144+
145+
install_apt() {
146+
echo "Installing apt packages..."
147+
local apt_cmd=(DEBIAN_FRONTEND=noninteractive apt-get)
148+
sudo "${apt_cmd[@]}" update
149+
if [[ $unsupported_distro == 1 ]]; then
150+
for package in "${apt_packages[@]}"; do
151+
if ! sudo "${apt_cmd[@]}" install -y "$package"; then
152+
echo "Failed to install $package on that distribution" >&2
153+
fi
154+
done
155+
else
156+
sudo "${apt_cmd[@]}" install -y "${apt_packages[@]}" || exit $?
157+
fi
158+
}
159+
160+
install_pacman() {
161+
echo "Installing pacman packages..."
162+
sudo pacman -Sy --needed --noconfirm "${pacman_packages[@]}" || exit $?
163+
}
164+
165+
# APT-based distributions like Ubuntu or Debian
166+
apt_packages=(
167+
cpu-checker
168+
libarchive-tools
169+
wget
170+
unzip
171+
qemu-user-static
172+
)
173+
174+
# pacman-based distributions like Archlinux or its derivatives
175+
pacman_packages=(
176+
libarchive
177+
qemu-user-static
178+
)
179+
180+
# Detection based on the package-manager, so that it works on derivatives of
181+
# distributions we expect. Matching on distro name would prevent that.
182+
if which apt-get &>/dev/null; then
183+
install_functions+=(install_apt)
184+
package_manager='apt-get'
185+
expected_distro="Ubuntu"
186+
187+
elif which pacman &>/dev/null; then
188+
install_functions+=(install_pacman)
189+
package_manager="pacman"
190+
expected_distro="Arch Linux"
191+
else
192+
echo "The package manager of distribution $(read_os_release NAME) is not supported, will only install distro-agnostic code"
193+
fi
194+
195+
if [[ -n "${package_manager}" ]] && ! test_os_release NAME "${expected_distro}"; then
196+
unsupported_distro=1
197+
echo
198+
echo "INFO: the distribution seems based on ${package_manager} but is not ${expected_distro}, some package names might not be right"
199+
echo
200+
else
201+
unsupported_distro=0
202+
fi
203+
204+
usage() {
205+
echo "Usage: ${0} [--help] [--cleanup-android-sdk] [--install-android-tools]
206+
[--install-android-platform-tools] [--create-avds] [--install-all]"
207+
cat << EOF
208+
209+
Install distribution packages and other bits required by Android emulator.
210+
Archlinux and Ubuntu are supported, although derivative distributions will
211+
probably work as well.
212+
213+
--install-android-platform-tools is not needed when using
214+
--install-android-tools, but has the advantage of not needing a Java
215+
installation and is quicker to install.
216+
EOF
217+
}
218+
219+
# Defaults to --install-all if no option is given
220+
if [[ -z "$*" ]]; then
221+
args=("--install-all")
222+
else
223+
args=("$@")
224+
fi
225+
226+
set_host_arch
227+
228+
# Use conditional fall-through ;;& to all matching all branches with
229+
# --install-all
230+
for arg in "${args[@]}"; do
231+
# We need this flag since *) does not play well with fall-through ;;&
232+
handled=0
233+
case "$arg" in
234+
235+
"--cleanup-android-sdk")
236+
install_functions+=(cleanup_android_home)
237+
handled=1
238+
;;&
239+
240+
"--install-android-tools" | "--install-all")
241+
install_functions+=(
242+
find_java_home
243+
install_android_sdk_manager
244+
install_android_tools
245+
)
246+
apt_packages+=(openjdk-"${ANDROID_SDK_JAVA_VERSION}"-jre openjdk-"${ANDROID_SDK_JAVA_VERSION}"-jdk)
247+
pacman_packages+=(jre"${ANDROID_SDK_JAVA_VERSION}"-openjdk jdk"${ANDROID_SDK_JAVA_VERSION}"-openjdk)
248+
handled=1;
249+
;;&
250+
251+
"--create-avds" | "--install-all")
252+
install_functions+=(
253+
find_java_home
254+
install_android_sdk_manager
255+
install_android_tools
256+
create_android_vds
257+
)
258+
handled=1
259+
;;&
260+
261+
"--help")
262+
usage
263+
exit 0
264+
;;&
265+
266+
*)
267+
if [[ ${handled} != 1 ]]; then
268+
echo "Unrecognised argument: ${arg}"
269+
usage
270+
exit 2
271+
fi
272+
;;
273+
esac
274+
done
275+
276+
# In order in which they will be executed if specified in command line
277+
ordered_functions=(
278+
# Distro package managers before anything else, so all the basic
279+
# pre-requisites are there
280+
install_apt
281+
install_pacman
282+
283+
find_java_home
284+
# cleanup must be done BEFORE installing
285+
cleanup_android_home
286+
install_android_sdk_manager
287+
install_android_tools
288+
create_android_vds
289+
)
290+
291+
# Remove duplicates in the list
292+
# shellcheck disable=SC2207
293+
install_functions=($(echo "${install_functions[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
294+
295+
# Call all the hooks in the order of available_functions
296+
ret=0
297+
for f in "${ordered_functions[@]}"; do
298+
for func in "${install_functions[@]}"; do
299+
if [[ ${func} == "${f}" ]]; then
300+
# If one hook returns non-zero, we keep going but return an overall failure code.
301+
${func}; _ret=$?
302+
if [[ $_ret != 0 ]]; then
303+
ret=${_ret}
304+
echo "Stage ${func} failed with exit code ${ret}" >&2
305+
else
306+
echo "Stage ${func} succeeded" >&2
307+
fi
308+
fi
309+
done
310+
done
311+
312+
exit $ret
313+
314+
# vim: set tabstop=4 shiftwidth=4 textwidth=80 expandtab:
185 KB
Loading

tools/android/skins/pixel_6/layout

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
parts {
2+
device {
3+
display {
4+
width 1080
5+
height 2400
6+
x 0
7+
y 0
8+
}
9+
}
10+
portrait {
11+
background {
12+
image back.webp
13+
}
14+
foreground {
15+
mask mask.webp
16+
cutout hole
17+
}
18+
}
19+
}
20+
layouts {
21+
portrait {
22+
width 1209
23+
height 2553
24+
event EV_SW:0:1
25+
part1 {
26+
name portrait
27+
x 0
28+
y 0
29+
}
30+
part2 {
31+
name device
32+
x 60
33+
y 69
34+
}
35+
}
36+
}
6.41 KB
Loading
194 KB
Loading

0 commit comments

Comments
 (0)