7Find an Android device with a given ABI.
9The name of the Android device is printed to stdout.
11Optionally configure and launch an emulator if there's no existing device for a
12given ABI. Will download and install Android SDK components as needed.
27 result = optparse.OptionParser()
33 help=
"Desired ABI. armeabi-v7a or x86.")
38 'Bootstrap - create an emulator, installing SDK packages if needed.',
44 help=
'Turn on debugging diagnostics.',
50 help=
'Verbose output.',
60 VERBOSE = options.verbose
61 if options.abi
is None:
62 sys.stderr.write(
'--abi not specified.\n')
69 Parse the output of an 'android list sdk' command.
71 Return list of (id-num, id-key, type, description).
73 header_regex = re.compile(
74 r'Packages available for installation or update: \d+\n')
75 packages = re.split(header_regex, text)
76 if len(packages) != 2:
77 raise utils.Error(
"Could not get a list of packages to install")
78 entry_regex = re.compile(
79 r'^id\: (\d+) or "([^"]*)"\n\s*Type\: ([^\n]*)\n\s*Desc\: (.*)')
81 for entry
in packages[1].split(
'----------\n'):
82 match = entry_regex.match(entry)
85 entries.append((
int(match.group(1)), match.group(2), match.group(3),
98 packages: list of (id-num, id-key, type, description).
99 key: (id-key, type, description-prefix).
101 (key_id, key_type, key_description_prefix) = key
102 for package
in packages:
103 (package_num, package_id, package_type, package_description) = package
104 if (package_id == key_id
and package_type == key_type
and
105 package_description.startswith(key_description_prefix)):
112 Makes sure the package with a given key
is installed.
114 key
is (id-key, type, description-prefix)
116 Returns
True if the package was
not already installed.
120 raise utils.Error(
"Could not find a package for key %s" % key)
123 sys.stderr.write(
'Checking Android SDK package %s...\n' % str(entry))
125 [
"android",
"update",
"sdk",
"-a",
"-u",
"--filter",
127 return '\nInstalling Archives:\n' in out
134 (
'android-15',
'Platform',
'Android SDK Platform 4.0.3'),
136 (
'sysimg-15',
'SystemImage',
'Android SDK Platform 4.0.3')
140 (
'android-15',
'Platform',
'Android SDK Platform 4.0.3'),
142 (
'sysimg-15',
'SystemImage',
'Android SDK Platform 4.0.4')
146 if abi
not in packagesForAbi:
148 return packagesForAbi[abi]
153 if package[1] ==
'Platform':
158 """Return true if at least one package was not already installed."""
160 installedSomething =
False
162 for package
in abiPackageList:
164 return installedSomething
169 Parse the output of an 'android list avd' command.
170 Return List of {Name: Path: Target: ABI: Skin: Sdcard:}
172 text = text.split('Available Android Virtual Devices:\n')[-1]
174 'The following Android Virtual Devices could not be loaded:\n')[0]
176 line_re = re.compile(
r'^\s*([^\:]+)\:\s*(.*)$')
177 for chunk
in text.split(
'\n---------\n'):
179 for line
in chunk.split(
'\n'):
183 match = line_re.match(line)
185 sys.stderr.write(
'Match fail %s\n' % str(line))
188 entry[match.group(1)] = match.group(2)
195 """Returns a list of available Android Virtual Devices."""
202 if avd[
'Name'] == key:
209 "android",
"create",
"avd",
"--name", avdName,
"--target",
213 if out.find(
'Created AVD ') < 0:
215 sys.stderr.write(
'Could not create AVD:\n%s\n' % out)
221 return FindAvd(avdList, avdName)
is not None
228 sys.stderr.write(
'Checking SDK packages...\n')
238 Start an emulator for a given abi
and svdName.
240 Echo the emulator
's stderr and stdout output to our stderr.
242 Call pollFn repeatedly until it returns False. Leave the emulator running
245 Implementation note: Normally we would call the
'emulator' binary, which
246 is a wrapper that launches the appropriate abi-specific emulator. But there
247 is a bug that causes the emulator to exit immediately
with a result code of
248 -11
if run
from a ssh shell
or a No Machine shell. (And only
if called
from
249 three levels of nested python scripts.) Calling the ABI-specific versions
250 of the emulator directly works around this bug.
252 emulatorName = {'x86':
'emulator-x86',
'armeabi-v7a':
'emulator-arm'}[abi]
253 command = [emulatorName,
'-avd', avdName,
'-no-boot-anim',
'-no-window']
257 killOnEarlyReturn=
False,
258 outStream=sys.stderr,
259 errStream=sys.stderr)
263 """Return Dictionary [name] -> status"""
264 text = text.split(
'List of devices attached')[-1]
265 lines = [line.strip()
for line
in text.split(
'\n')]
266 lines = [line
for line
in lines
if len(line) > 0]
269 lineItems = line.split(
'\t')
270 devices[lineItems[0]] = lineItems[1]
280 for device
in devices.keys():
281 status = devices[device]
282 if status !=
'offline':
283 online[device] = status
298 for property
in [
'ro.product.cpu.abi',
'ro.product.cpu.abi2']:
313 script_dir = os.path.dirname(sys.argv[0])
314 dart_root = os.path.realpath(os.path.join(script_dir,
'..',
'..'))
315 third_party_root = os.path.join(dart_root,
'third_party')
316 android_tools = os.path.join(third_party_root,
'android_tools')
317 android_sdk_root = os.path.join(android_tools,
'sdk')
318 android_sdk_tools = os.path.join(android_sdk_root,
'tools')
319 android_sdk_platform_tools = os.path.join(android_sdk_root,
321 os.environ[
'PATH'] =
':'.
join(
322 [os.environ[
'PATH'], android_sdk_tools, android_sdk_platform_tools])
325 'ANDROID_NDK_ROOT',
'ANDROID_SDK_ROOT',
'ANDROID_TOOLCHAIN',
'AR',
326 'BUILDTYPE',
'CC',
'CXX',
'GYP_DEFINES',
'LD_LIBRARY_PATH',
'LINK',
327 'MAKEFLAGS',
'MAKELEVEL',
'MAKEOVERRIDES',
'MFLAGS',
'NM'
336 'Looking for an Android device running abi %s...\n' % abi)
342 sys.stderr.write(
"No emulator found, try to create one.\n")
343 avdName =
'dart-build-%s' % abi
352 sys.stderr.write(
'.')
355 return pollResult[0] !=
None
358 device = pollResult[0]
365 (options, args) = parser.parse_args()
376 device =
FindAndroid(options.abi, options.bootstrap)
378 sys.stdout.write(
"%s\n" % device)
382 sys.stderr.write(
'Could not find device\n')
385 sys.stderr.write(
"error: %s\n" % e)
387 traceback.print_exc(file=sys.stderr)
391if __name__ ==
'__main__':
def EnsureAndroidSdkPackagesInstalled(abi)
def ParseAndroidDevices(text)
def ParseAndroidListAvdResult(text)
def CreateAvd(avdName, abi)
def GetOnlineAndroidDevices()
def FindAndroidRunning(abi)
def FilterOfflineDevices(devices)
def SdkPackagesForAbi(abi)
def ParseAndroidListSdkResult(text)
def FindAndroid(abi, bootstrap)
def AndroidSdkFindPackage(packages, key)
def GetAndroidDeviceProperty(device, property)
def StartEmulator(abi, avdName, pollFn)
def GetAndroidDeviceAbis(device)
def EnsureSdkPackageInstalled(packages, key)
def EnsureAvdExists(avdName, abi)
def ProcessOptions(options)
def RunCommand(command, input=None, pollFn=None, outStream=None, errStream=None, killOnEarlyReturn=True, verbose=False, debug=False, printErrorInfo=False)
static SkString join(const CommandLineFlags::StringArray &)