Add Android emulator support
Add prebuilts and scripts for the Android emulator
and all the required SDK harness.
Also introduces a run_android_emulator script that
sets up the necessary .avd files and starts the
emulator using the configuration files checked in
into //build/android_emulators.
In the next CLs this will be wired up to tests.
Change-Id: I56b7cecaaea48ab5f28682c2f341f443c04b134b
diff --git a/build/android_emulators/arm.ini b/build/android_emulators/arm.ini
new file mode 100644
index 0000000..ee724ae
--- /dev/null
+++ b/build/android_emulators/arm.ini
@@ -0,0 +1,21 @@
+avd.ini.encoding=UTF-8
+abi.type=armeabi-v7a
+disk.dataPartition.size=64M
+hw.accelerometer=no
+hw.audioInput=no
+hw.battery=no
+hw.camera.back=none
+hw.camera.front=none
+hw.cpu.arch=arm
+hw.dPad=no
+hw.gps=no
+hw.keyboard=yes
+hw.lcd.density=480
+hw.mainKeys=no
+hw.ramSize=512
+hw.sdCard=no
+hw.sensors.orientation=yes
+hw.sensors.proximity=yes
+hw.trackBall=no
+image.sysdir.1=system-images/android-24/default/armeabi-v7a/
+vm.heapSize=64
diff --git a/build/android_emulators/arm64.ini b/build/android_emulators/arm64.ini
new file mode 100644
index 0000000..c1d56f8
--- /dev/null
+++ b/build/android_emulators/arm64.ini
@@ -0,0 +1,21 @@
+avd.ini.encoding=UTF-8
+abi.type=arm64-v8a
+disk.dataPartition.size=64M
+hw.accelerometer=no
+hw.audioInput=no
+hw.battery=no
+hw.camera.back=none
+hw.camera.front=none
+hw.cpu.arch=arm64
+hw.dPad=no
+hw.gps=no
+hw.keyboard=yes
+hw.lcd.density=480
+hw.mainKeys=no
+hw.ramSize=512
+hw.sdCard=no
+hw.sensors.orientation=yes
+hw.sensors.proximity=yes
+hw.trackBall=no
+image.sysdir.1=system-images/android-24/default/arm64-v8a/
+vm.heapSize=64
diff --git a/build/install-build-deps b/build/install-build-deps
index 5958ea7..69c7d53 100755
--- a/build/install-build-deps
+++ b/build/install-build-deps
@@ -23,7 +23,10 @@
import urllib
import zipfile
-PREBUILTS = (
+from collections import namedtuple
+
+# Dependencies required to build code on the host or when targeting desktop OS.
+BUILD_DEPS_HOST = [
# GN
('buildtools/mac/gn',
'https://storage.googleapis.com/chromium-gn/c2c934d4dda1f470a6511b1015dda9a9fb1ce50b',
@@ -48,6 +51,39 @@
'linux2'
),
+ # Keep in sync with Android's //external/googletest/README.version.
+ ('buildtools/googletest.zip',
+ 'https://github.com/google/googletest/archive/ff07a5de0e81580547f1685e101194ed1a4fcd56.zip',
+ 'c7edec7d7e6db1fc37a20710de9c4d89e3a3893b',
+ 'all'
+ ),
+
+ # Keep in sync with Android's //external/protobuf/README.version.
+ ('buildtools/protobuf.zip',
+ 'https://github.com/google/protobuf/releases/download/v3.0.0-beta-3/protobuf-cpp-3.0.0-beta-3.zip',
+ '3caec60aa9d8eefc8c3c3201b6b8ca19935edb89',
+ 'all'
+ ),
+
+ # libc++ and libc++abi, for clang msan that require rebuilding the C++ lib
+ # from sources. Keep the SHA1s in sync with Chrome's src/buildtools/DEPS.
+ ('buildtools/libcxx',
+ 'https://chromium.googlesource.com/chromium/llvm-project/libcxx.git',
+ '3a07dd740be63878167a0ea19fe81869954badd7',
+ 'all'
+ ),
+ ('buildtools/libcxxabi',
+ 'https://chromium.googlesource.com/chromium/llvm-project/libcxxabi.git',
+ '4072e8fd76febee37f60aeda76d6d9f5e3791daa',
+ 'all'
+ ),
+]
+
+# Dependencies required to build Android code.
+# URLs and SHA1s taken from:
+# - https://dl.google.com/android/repository/repository-11.xml
+# - https://dl.google.com/android/repository/sys-img/android/sys-img.xml
+BUILD_DEPS_ANDROID = [
# Android NDK
('buildtools/ndk.zip',
'https://dl.google.com/android/repository/android-ndk-r15c-darwin-x86_64.zip',
@@ -59,36 +95,46 @@
'0bf02d4e8b85fd770fd7b9b2cdec57f9441f27a2',
'linux2'
),
+]
- # Keep in sync with Android's //external/googletest/README.version .
- ('buildtools/googletest.zip',
- 'https://github.com/google/googletest/archive/ff07a5de0e81580547f1685e101194ed1a4fcd56.zip',
- 'c7edec7d7e6db1fc37a20710de9c4d89e3a3893b',
- 'all'
+# Dependencies required to run Android tests.
+TEST_DEPS_ANDROID = [
+ # tools.zip contains the emulator binaries.
+ ('buildtools/android_sdk/tools.zip',
+ 'https://dl.google.com/android/repository/tools_r25.2.5-macosx.zip',
+ 'd2168d963ac5b616e3d3ddaf21511d084baf3659',
+ 'darwin'
+ ),
+ ('buildtools/android_sdk/tools.zip',
+ 'https://dl.google.com/android/repository/tools_r25.2.5-linux.zip',
+ '72df3aa1988c0a9003ccdfd7a13a7b8bd0f47fc1',
+ 'linux2'
),
- # Keep in sync with Android's //external/protobuf/README.version .
- ('buildtools/protobuf.zip',
- 'https://github.com/google/protobuf/releases/download/v3.0.0-beta-3/protobuf-cpp-3.0.0-beta-3.zip',
- '3caec60aa9d8eefc8c3c3201b6b8ca19935edb89',
- 'all'
+ # platform-tools.zip contains adb binaries.
+ ('buildtools/android_sdk/platform-tools.zip',
+ 'https://dl.google.com/android/repository/platform-tools_r26.0.0-darwin.zip',
+ 'e75b6137dc444f777eb02f44a6d9819b3aabff82',
+ 'darwin'
+ ),
+ ('buildtools/android_sdk/platform-tools.zip',
+ 'https://dl.google.com/android/repository/platform-tools_r26.0.0-linux.zip',
+ '00de8a6631405b617c10f68cd11ff2e1cd528e23',
+ 'linux2'
),
- # libc++ and libc++abi, for clang msan that require rebuilding the C++ lib
- # from sources. Keep the SHA1s in sync with Chrome's src/buildtools/DEPS .
- ('buildtools/libcxx',
- 'https://chromium.googlesource.com/chromium/llvm-project/libcxx.git',
- '3a07dd740be63878167a0ea19fe81869954badd7',
+ # Android emulator images.
+ ('buildtools/android_sdk/system-images/android-24/default/armeabi-v7a.zip',
+ 'https://dl.google.com/android/repository/sys-img/android/armeabi-v7a-24_r07.zip',
+ '3454546b4eed2d6c3dd06d47757d6da9f4176033',
'all'
),
- ('buildtools/libcxxabi',
- 'https://chromium.googlesource.com/chromium/llvm-project/libcxxabi.git',
- '4072e8fd76febee37f60aeda76d6d9f5e3791daa',
+ ('buildtools/android_sdk/system-images/android-24/default/arm64-v8a.zip',
+ 'https://dl.google.com/android/repository/sys-img/android/arm64-v8a-24_r07.zip',
+ 'e8ab2e49e4efe4b064232b33b5eeaded61437d7f',
'all'
),
-
-
-)
+]
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -143,15 +189,14 @@
def Main():
parser = argparse.ArgumentParser()
- parser.add_argument('--skip', action='append', default=[])
+ parser.add_argument('--no-android', action='store_true')
args = parser.parse_args()
- skip_set = set(args.skip)
- for rel_path, url, expected_sha1, platform in PREBUILTS:
+ deps = BUILD_DEPS_HOST
+ if not args.no_android:
+ deps += BUILD_DEPS_ANDROID + TEST_DEPS_ANDROID
+ for rel_path, url, expected_sha1, platform in deps:
if platform != 'all' and platform != sys.platform:
continue
- if os.path.basename(rel_path) in skip_set:
- logging.info('Skipping %s because of --skip cmdline arg', rel_path)
- continue
local_path = os.path.join(ROOT_DIR, rel_path)
if url.endswith('.git'):
CheckoutGitRepo(local_path, url, expected_sha1)
diff --git a/build/run_android_emulator b/build/run_android_emulator
new file mode 100755
index 0000000..32f024f
--- /dev/null
+++ b/build/run_android_emulator
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# Copyright (C) 2017 The Android Open Source Project
+#
+# 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.
+
+import argparse
+import os
+import shutil
+import sys
+
+
+def Main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--verbose', '-v', action='store_true')
+ parser.add_argument('--pid', help='(optional) save pid into given file')
+ parser.add_argument('image', help='arm|arm64 (see //build/android_emulators)')
+ args = parser.parse_args()
+
+ root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ ini = os.path.join(root_dir, 'build', 'android_emulators', args.image + '.ini')
+ assert os.path.exists(ini), 'File not found: ' + ini
+
+ avd_dir = os.path.join(root_dir, 'buildtools', 'emulator_images')
+ if not os.path.exists(avd_dir):
+ os.makedirs(avd_dir)
+
+ emu_img_dir = os.path.join(avd_dir, args.image + '.avd')
+ if not os.path.exists(emu_img_dir):
+ os.makedirs(emu_img_dir)
+ shutil.copyfile(ini, os.path.join(emu_img_dir, 'config.ini'))
+
+ with open(os.path.join(avd_dir, args.image + '.ini'), 'w') as f:
+ f.write('path=' + emu_img_dir)
+
+ sdk_dir = os.path.join(root_dir, 'buildtools', 'android_sdk')
+ env = {
+ # Travis CI doesn't set this and causes the emulator to fallback in
+ # 32-bit mode with a "Cannot decide host bitness because $SHELL" error.
+ 'SHELL': '/bin/bash',
+ 'ANDROID_EMULATOR_DEBUG': '1' if args.verbose else '0',
+ 'ANDROID_SDK_ROOT': sdk_dir,
+ 'ANDROID_AVD_HOME': avd_dir,
+ 'DYLD_LIBRARY_PATH': os.path.join(sdk_dir, 'tools', 'lib64', 'qt', 'lib'),
+ }
+ emulator_bin = os.path.join(sdk_dir, 'tools', 'emulator')
+ emulator_args = ['-no-window', '-no-snapshot', '-gpu', 'off', '-wipe-data',
+ '-avd', args.image]
+ print '\n'.join('='.join(x) for x in env.items())
+ print ' '.join([emulator_bin] + emulator_args)
+ if args.pid:
+ with open(args.pid, 'w') as f:
+ f.write(str(os.getpid()))
+ os.execve(emulator_bin, [emulator_bin] + emulator_args, env)
+
+
+if __name__ == '__main__':
+ sys.exit(Main())
diff --git a/buildtools/.gitignore b/buildtools/.gitignore
index 79d7ef2..594bce1 100644
--- a/buildtools/.gitignore
+++ b/buildtools/.gitignore
@@ -1,7 +1,9 @@
+android_sdk/
+emulator_images/
googletest/
+libcxx/
+libcxxabi/
linux/
mac/
ndk/
protobuf/
-libcxx/
-libcxxabi/