diff options
Diffstat (limited to 'build/android')
-rwxr-xr-x | build/android/gyp/util/build_utils_test.py | 44 | ||||
-rw-r--r-- | build/android/gyp/util/jar_info_utils.py | 52 | ||||
-rwxr-xr-x | build/android/gyp/util/md5_check_test.py | 144 | ||||
-rw-r--r-- | build/android/gyp/util/proguard_util.py | 212 | ||||
-rw-r--r-- | build/android/gyp/util/resource_utils.py | 511 | ||||
-rwxr-xr-x | build/android/pylib/constants/host_paths_unittest.py | 50 | ||||
-rw-r--r-- | build/android/pylib/content_settings.py | 80 | ||||
-rw-r--r-- | build/android/pylib/device_settings.py | 199 | ||||
-rw-r--r-- | build/android/pylib/pexpect.py | 21 | ||||
-rwxr-xr-x | build/android/pylib/restart_adbd.sh | 20 | ||||
-rw-r--r-- | build/android/pylib/valgrind_tools.py | 130 |
11 files changed, 0 insertions, 1463 deletions
diff --git a/build/android/gyp/util/build_utils_test.py b/build/android/gyp/util/build_utils_test.py deleted file mode 100755 index bcc892f39b..0000000000 --- a/build/android/gyp/util/build_utils_test.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import collections -import unittest - -import build_utils # pylint: disable=W0403 - -_DEPS = collections.OrderedDict() -_DEPS['a'] = [] -_DEPS['b'] = [] -_DEPS['c'] = ['a'] -_DEPS['d'] = ['a'] -_DEPS['e'] = ['f'] -_DEPS['f'] = ['a', 'd'] -_DEPS['g'] = [] -_DEPS['h'] = ['d', 'b', 'f'] -_DEPS['i'] = ['f'] - - -class BuildUtilsTest(unittest.TestCase): - def testGetSortedTransitiveDependencies_all(self): - TOP = _DEPS.keys() - EXPECTED = ['a', 'b', 'c', 'd', 'f', 'e', 'g', 'h', 'i'] - actual = build_utils.GetSortedTransitiveDependencies(TOP, _DEPS.get) - self.assertEqual(EXPECTED, actual) - - def testGetSortedTransitiveDependencies_leaves(self): - TOP = ['c', 'e', 'g', 'h', 'i'] - EXPECTED = ['a', 'c', 'd', 'f', 'e', 'g', 'b', 'h', 'i'] - actual = build_utils.GetSortedTransitiveDependencies(TOP, _DEPS.get) - self.assertEqual(EXPECTED, actual) - - def testGetSortedTransitiveDependencies_leavesReverse(self): - TOP = ['i', 'h', 'g', 'e', 'c'] - EXPECTED = ['a', 'd', 'f', 'i', 'b', 'h', 'g', 'e', 'c'] - actual = build_utils.GetSortedTransitiveDependencies(TOP, _DEPS.get) - self.assertEqual(EXPECTED, actual) - - -if __name__ == '__main__': - unittest.main() diff --git a/build/android/gyp/util/jar_info_utils.py b/build/android/gyp/util/jar_info_utils.py deleted file mode 100644 index 987ee9dcf1..0000000000 --- a/build/android/gyp/util/jar_info_utils.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import os - -# Utilities to read and write .jar.info files. -# -# A .jar.info file contains a simple mapping from fully-qualified Java class -# names to the source file that actually defines it. -# -# For APKs, the .jar.info maps the class names to the .jar file that which -# contains its .class definition instead. - - -def ParseJarInfoFile(info_path): - """Parse a given .jar.info file as a dictionary. - - Args: - info_path: input .jar.info file path. - Returns: - A new dictionary mapping fully-qualified Java class names to file paths. - """ - info_data = dict() - if os.path.exists(info_path): - with open(info_path, 'r') as info_file: - for line in info_file: - line = line.strip() - if line: - fully_qualified_name, path = line.split(',', 1) - info_data[fully_qualified_name] = path - return info_data - - -def WriteJarInfoFile(info_path, info_data, source_file_map=None): - """Generate a .jar.info file from a given dictionary. - - Args: - info_path: output file path. - info_data: a mapping of fully qualified Java class names to filepaths. - source_file_map: an optional mapping from java source file paths to the - corresponding source .srcjar. This is because info_data may contain the - path of Java source files that where extracted from an .srcjar into a - temporary location. - """ - with open(info_path, 'w') as info_file: - for fully_qualified_name, path in info_data.iteritems(): - if source_file_map and path in source_file_map: - path = source_file_map[path] - assert not path.startswith('/tmp'), ( - 'Java file path should not be in temp dir: {}'.format(path)) - info_file.write('{},{}\n'.format(fully_qualified_name, path)) diff --git a/build/android/gyp/util/md5_check_test.py b/build/android/gyp/util/md5_check_test.py deleted file mode 100755 index 312d4a98cb..0000000000 --- a/build/android/gyp/util/md5_check_test.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import fnmatch -import tempfile -import unittest -import zipfile - -import md5_check # pylint: disable=W0403 - - -def _WriteZipFile(path, entries): - with zipfile.ZipFile(path, 'w') as zip_file: - for subpath, data in entries: - zip_file.writestr(subpath, data) - - -class TestMd5Check(unittest.TestCase): - def setUp(self): - self.called = False - self.changes = None - - def testCallAndRecordIfStale(self): - input_strings = ['string1', 'string2'] - input_file1 = tempfile.NamedTemporaryFile(suffix='.txt') - input_file2 = tempfile.NamedTemporaryFile(suffix='.zip') - file1_contents = 'input file 1' - input_file1.write(file1_contents) - input_file1.flush() - # Test out empty zip file to start. - _WriteZipFile(input_file2.name, []) - input_files = [input_file1.name, input_file2.name] - - record_path = tempfile.NamedTemporaryFile(suffix='.stamp') - - def CheckCallAndRecord(should_call, message, force=False, - outputs_specified=False, outputs_missing=False, - expected_changes=None, added_or_modified_only=None): - output_paths = None - if outputs_specified: - output_file1 = tempfile.NamedTemporaryFile() - if outputs_missing: - output_file1.close() # Gets deleted on close(). - output_paths = [output_file1.name] - - self.called = False - self.changes = None - if expected_changes or added_or_modified_only is not None: - def MarkCalled(changes): - self.called = True - self.changes = changes - else: - def MarkCalled(): - self.called = True - - md5_check.CallAndRecordIfStale( - MarkCalled, - record_path=record_path.name, - input_paths=input_files, - input_strings=input_strings, - output_paths=output_paths, - force=force, - pass_changes=(expected_changes or added_or_modified_only) is not None) - self.assertEqual(should_call, self.called, message) - if expected_changes: - description = self.changes.DescribeDifference() - self.assertTrue(fnmatch.fnmatch(description, expected_changes), - 'Expected %s to match %s' % ( - repr(description), repr(expected_changes))) - if should_call and added_or_modified_only is not None: - self.assertEqual(added_or_modified_only, - self.changes.AddedOrModifiedOnly()) - - CheckCallAndRecord(True, 'should call when record doesn\'t exist', - expected_changes='Previous stamp file not found.', - added_or_modified_only=False) - CheckCallAndRecord(False, 'should not call when nothing changed') - CheckCallAndRecord(False, 'should not call when nothing changed #2', - outputs_specified=True, outputs_missing=False) - CheckCallAndRecord(True, 'should call when output missing', - outputs_specified=True, outputs_missing=True, - expected_changes='Outputs do not exist:*', - added_or_modified_only=False) - CheckCallAndRecord(True, force=True, message='should call when forced', - expected_changes='force=True', - added_or_modified_only=False) - - input_file1.write('some more input') - input_file1.flush() - CheckCallAndRecord(True, 'changed input file should trigger call', - expected_changes='*Modified: %s' % input_file1.name, - added_or_modified_only=True) - - input_files = input_files[::-1] - CheckCallAndRecord(False, 'reordering of inputs shouldn\'t trigger call') - - input_files = input_files[:1] - CheckCallAndRecord(True, 'removing file should trigger call', - expected_changes='*Removed: %s' % input_file1.name, - added_or_modified_only=False) - - input_files.append(input_file1.name) - CheckCallAndRecord(True, 'added input file should trigger call', - expected_changes='*Added: %s' % input_file1.name, - added_or_modified_only=True) - - input_strings[0] = input_strings[0] + ' a bit longer' - CheckCallAndRecord(True, 'changed input string should trigger call', - expected_changes='*Input strings changed*', - added_or_modified_only=False) - - input_strings = input_strings[::-1] - CheckCallAndRecord(True, 'reordering of string inputs should trigger call', - expected_changes='*Input strings changed*') - - input_strings = input_strings[:1] - CheckCallAndRecord(True, 'removing a string should trigger call') - - input_strings.append('a brand new string') - CheckCallAndRecord(True, 'added input string should trigger call') - - _WriteZipFile(input_file2.name, [('path/1.txt', '1')]) - CheckCallAndRecord(True, 'added subpath should trigger call', - expected_changes='*Modified: %s*Subpath added: %s' % ( - input_file2.name, 'path/1.txt'), - added_or_modified_only=True) - _WriteZipFile(input_file2.name, [('path/1.txt', '2')]) - CheckCallAndRecord(True, 'changed subpath should trigger call', - expected_changes='*Modified: %s*Subpath modified: %s' % ( - input_file2.name, 'path/1.txt'), - added_or_modified_only=True) - CheckCallAndRecord(False, 'should not call when nothing changed') - - _WriteZipFile(input_file2.name, []) - CheckCallAndRecord(True, 'removed subpath should trigger call', - expected_changes='*Modified: %s*Subpath removed: %s' % ( - input_file2.name, 'path/1.txt'), - added_or_modified_only=False) - - -if __name__ == '__main__': - unittest.main() diff --git a/build/android/gyp/util/proguard_util.py b/build/android/gyp/util/proguard_util.py deleted file mode 100644 index fd657e2aa7..0000000000 --- a/build/android/gyp/util/proguard_util.py +++ /dev/null @@ -1,212 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import os -import re -from util import build_utils - - -class ProguardOutputFilter(object): - """ProGuard outputs boring stuff to stdout (proguard version, jar path, etc) - as well as interesting stuff (notes, warnings, etc). If stdout is entirely - boring, this class suppresses the output. - """ - - IGNORE_RE = re.compile( - r'Pro.*version|Note:|Reading|Preparing|Printing|ProgramClass:|Searching|' - r'jar \[|\d+ class path entries checked') - - def __init__(self): - self._last_line_ignored = False - self._ignore_next_line = False - - def __call__(self, output): - ret = [] - for line in output.splitlines(True): - if self._ignore_next_line: - self._ignore_next_line = False - continue - - if '***BINARY RUN STATS***' in line: - self._last_line_ignored = True - self._ignore_next_line = True - elif not line.startswith(' '): - self._last_line_ignored = bool(self.IGNORE_RE.match(line)) - elif 'You should check if you need to specify' in line: - self._last_line_ignored = True - - if not self._last_line_ignored: - ret.append(line) - return ''.join(ret) - - -class ProguardCmdBuilder(object): - def __init__(self, proguard_jar): - assert os.path.exists(proguard_jar) - self._proguard_jar_path = proguard_jar - self._mapping = None - self._libraries = None - self._injars = None - self._configs = None - self._config_exclusions = None - self._outjar = None - self._verbose = False - self._disabled_optimizations = [] - - def outjar(self, path): - assert self._outjar is None - self._outjar = path - - def mapping(self, path): - assert self._mapping is None - assert os.path.exists(path), path - self._mapping = path - - def libraryjars(self, paths): - assert self._libraries is None - for p in paths: - assert os.path.exists(p), p - self._libraries = paths - - def injars(self, paths): - assert self._injars is None - for p in paths: - assert os.path.exists(p), p - self._injars = paths - - def configs(self, paths): - assert self._configs is None - self._configs = paths - for p in self._configs: - assert os.path.exists(p), p - - def config_exclusions(self, paths): - assert self._config_exclusions is None - self._config_exclusions = paths - - def verbose(self, verbose): - self._verbose = verbose - - def disable_optimizations(self, optimizations): - self._disabled_optimizations += optimizations - - def build(self): - assert self._injars is not None - assert self._outjar is not None - assert self._configs is not None - cmd = [ - 'java', '-jar', self._proguard_jar_path, - '-forceprocessing', - ] - - if self._mapping: - cmd += ['-applymapping', self._mapping] - - if self._libraries: - cmd += ['-libraryjars', ':'.join(self._libraries)] - - for optimization in self._disabled_optimizations: - cmd += [ '-optimizations', '!' + optimization ] - - # Filter to just .class files to avoid warnings about multiple inputs having - # the same files in META_INF/. - cmd += [ - '-injars', - ':'.join('{}(**.class)'.format(x) for x in self._injars) - ] - - for config_file in self.GetConfigs(): - cmd += ['-include', config_file] - - # The output jar must be specified after inputs. - cmd += [ - '-outjars', self._outjar, - '-printseeds', self._outjar + '.seeds', - '-printusage', self._outjar + '.usage', - '-printmapping', self._outjar + '.mapping', - ] - - if self._verbose: - cmd.append('-verbose') - - return cmd - - def GetDepfileDeps(self): - # The list of inputs that the GN target does not directly know about. - inputs = self._configs + self._injars - if self._libraries: - inputs += self._libraries - return inputs - - def GetConfigs(self): - ret = list(self._configs) - for path in self._config_exclusions: - ret.remove(path) - return ret - - def GetInputs(self): - inputs = self.GetDepfileDeps() - inputs += [self._proguard_jar_path] - if self._mapping: - inputs.append(self._mapping) - return inputs - - def GetOutputs(self): - return [ - self._outjar, - self._outjar + '.flags', - self._outjar + '.mapping', - self._outjar + '.seeds', - self._outjar + '.usage', - ] - - def _WriteFlagsFile(self, cmd, out): - # Quite useful for auditing proguard flags. - for config in sorted(self._configs): - out.write('#' * 80 + '\n') - out.write(config + '\n') - out.write('#' * 80 + '\n') - with open(config) as config_file: - contents = config_file.read().rstrip() - # Remove numbers from generated rule comments to make file more - # diff'able. - contents = re.sub(r' #generated:\d+', '', contents) - out.write(contents) - out.write('\n\n') - out.write('#' * 80 + '\n') - out.write('Command-line\n') - out.write('#' * 80 + '\n') - out.write(' '.join(cmd) + '\n') - - def CheckOutput(self): - cmd = self.build() - - # There are a couple scenarios (.mapping files and switching from no - # proguard -> proguard) where GN's copy() target is used on output - # paths. These create hardlinks, so we explicitly unlink here to avoid - # updating files with multiple links. - for path in self.GetOutputs(): - if os.path.exists(path): - os.unlink(path) - - with open(self._outjar + '.flags', 'w') as out: - self._WriteFlagsFile(cmd, out) - - # Warning: and Error: are sent to stderr, but messages and Note: are sent - # to stdout. - stdout_filter = None - stderr_filter = None - if not self._verbose: - stdout_filter = ProguardOutputFilter() - stderr_filter = ProguardOutputFilter() - build_utils.CheckOutput(cmd, print_stdout=True, - print_stderr=True, - stdout_filter=stdout_filter, - stderr_filter=stderr_filter) - - # Proguard will skip writing -printseeds / -printusage / -printmapping if - # the files would be empty, but ninja needs all outputs to exist. - open(self._outjar + '.seeds', 'a').close() - open(self._outjar + '.usage', 'a').close() - open(self._outjar + '.mapping', 'a').close() diff --git a/build/android/gyp/util/resource_utils.py b/build/android/gyp/util/resource_utils.py deleted file mode 100644 index 875fd12631..0000000000 --- a/build/android/gyp/util/resource_utils.py +++ /dev/null @@ -1,511 +0,0 @@ -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import argparse -import collections -import contextlib -import os -import re -import shutil -import sys -import tempfile -from xml.etree import ElementTree - -import util.build_utils as build_utils - -_SOURCE_ROOT = os.path.abspath( - os.path.join(os.path.dirname(__file__), '..', '..', '..', '..')) -# Import jinja2 from third_party/jinja2 -sys.path.insert(1, os.path.join(_SOURCE_ROOT, 'third_party')) -from jinja2 import Template # pylint: disable=F0401 - - -EMPTY_ANDROID_MANIFEST_PATH = os.path.join( - _SOURCE_ROOT, 'build', 'android', 'AndroidManifest.xml') - - -# A variation of this lists also exists in: -# //base/android/java/src/org/chromium/base/LocaleUtils.java -# //ui/android/java/src/org/chromium/base/LocalizationUtils.java -CHROME_TO_ANDROID_LOCALE_MAP = { - 'en-GB': 'en-rGB', - 'en-US': 'en-rUS', - 'es-419': 'es-rUS', - 'fil': 'tl', - 'he': 'iw', - 'id': 'in', - 'pt-PT': 'pt-rPT', - 'pt-BR': 'pt-rBR', - 'yi': 'ji', - 'zh-CN': 'zh-rCN', - 'zh-TW': 'zh-rTW', -} - -# Represents a line from a R.txt file. -_TextSymbolEntry = collections.namedtuple('RTextEntry', - ('java_type', 'resource_type', 'name', 'value')) - - -def CreateResourceInfoFile(files_to_zip, zip_path): - """Given a mapping of archive paths to their source, write an info file. - - The info file contains lines of '{archive_path},{source_path}' for ease of - parsing. Assumes that there is no comma in the file names. - - Args: - files_to_zip: Dict mapping path in the zip archive to original source. - zip_path: Path where the zip file ends up, this is where the info file goes. - """ - info_file_path = zip_path + '.info' - with open(info_file_path, 'w') as info_file: - for archive_path, source_path in files_to_zip.iteritems(): - info_file.write('{},{}\n'.format(archive_path, source_path)) - - -def _ParseTextSymbolsFile(path, fix_package_ids=False): - """Given an R.txt file, returns a list of _TextSymbolEntry. - - Args: - path: Input file path. - fix_package_ids: if True, all packaged IDs read from the file - will be fixed to 0x7f. - Returns: - A list of _TextSymbolEntry instances. - Raises: - Exception: An unexpected line was detected in the input. - """ - ret = [] - with open(path) as f: - for line in f: - m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line) - if not m: - raise Exception('Unexpected line in R.txt: %s' % line) - java_type, resource_type, name, value = m.groups() - if fix_package_ids: - value = _FixPackageIds(value) - ret.append(_TextSymbolEntry(java_type, resource_type, name, value)) - return ret - - -def _FixPackageIds(resource_value): - # Resource IDs for resources belonging to regular APKs have their first byte - # as 0x7f (package id). However with webview, since it is not a regular apk - # but used as a shared library, aapt is passed the --shared-resources flag - # which changes some of the package ids to 0x02 and 0x00. This function just - # normalises all package ids to 0x7f, which the generated code in R.java - # changes to the correct package id at runtime. - # resource_value is a string with either, a single value '0x12345678', or an - # array of values like '{ 0xfedcba98, 0x01234567, 0x56789abc }' - return re.sub(r'0x(?!01)\d\d', r'0x7f', resource_value) - - -def _GetRTxtResourceNames(r_txt_path): - """Parse an R.txt file and extract the set of resource names from it.""" - result = set() - for entry in _ParseTextSymbolsFile(r_txt_path): - result.add(entry.name) - return result - - -class RJavaBuildOptions: - """A class used to model the various ways to build an R.java file. - - This is used to control which resource ID variables will be final or - non-final, and whether an onResourcesLoaded() method will be generated - to adjust the non-final ones, when the corresponding library is loaded - at runtime. - - Note that by default, all resources are final, and there is no - method generated, which corresponds to calling ExportNoResources(). - """ - def __init__(self): - self.has_constant_ids = True - self.resources_whitelist = None - self.has_on_resources_loaded = False - self.export_const_styleable = False - - def ExportNoResources(self): - """Make all resource IDs final, and don't generate a method.""" - self.has_constant_ids = True - self.resources_whitelist = None - self.has_on_resources_loaded = False - self.export_const_styleable = False - - def ExportAllResources(self): - """Make all resource IDs non-final in the R.java file.""" - self.has_constant_ids = False - self.resources_whitelist = None - - def ExportSomeResources(self, r_txt_file_path): - """Only select specific resource IDs to be non-final. - - Args: - r_txt_file_path: The path to an R.txt file. All resources named - int it will be non-final in the generated R.java file, all others - will be final. - """ - self.has_constant_ids = True - self.resources_whitelist = _GetRTxtResourceNames(r_txt_file_path) - - def ExportAllStyleables(self): - """Make all styleable constants non-final, even non-resources ones. - - Resources that are styleable but not of int[] type are not actually - resource IDs but constants. By default they are always final. Call this - method to make them non-final anyway in the final R.java file. - """ - self.export_const_styleable = True - - def GenerateOnResourcesLoaded(self): - """Generate an onResourcesLoaded() method. - - This Java method will be called at runtime by the framework when - the corresponding library (which includes the R.java source file) - will be loaded at runtime. This corresponds to the --shared-resources - or --app-as-shared-lib flags of 'aapt package'. - """ - self.has_on_resources_loaded = True - - def _IsResourceFinal(self, entry): - """Determines whether a resource should be final or not. - - Args: - entry: A _TextSymbolEntry instance. - Returns: - True iff the corresponding entry should be final. - """ - if entry.resource_type == 'styleable' and entry.java_type != 'int[]': - # A styleable constant may be exported as non-final after all. - return not self.export_const_styleable - elif not self.has_constant_ids: - # Every resource is non-final - return False - elif not self.resources_whitelist: - # No whitelist means all IDs are non-final. - return True - else: - # Otherwise, only those in the - return entry.name not in self.resources_whitelist - - -def CreateRJavaFiles(srcjar_dir, package, main_r_txt_file, - extra_res_packages, extra_r_txt_files, - rjava_build_options): - """Create all R.java files for a set of packages and R.txt files. - - Args: - srcjar_dir: The top-level output directory for the generated files. - package: Top-level package name. - main_r_txt_file: The main R.txt file containing the valid values - of _all_ resource IDs. - extra_res_packages: A list of extra package names. - extra_r_txt_files: A list of extra R.txt files. One per item in - |extra_res_packages|. Note that all resource IDs in them will be ignored, - |and replaced by the values extracted from |main_r_txt_file|. - rjava_build_options: An RJavaBuildOptions instance that controls how - exactly the R.java file is generated. - Raises: - Exception if a package name appears several times in |extra_res_packages| - """ - assert len(extra_res_packages) == len(extra_r_txt_files), \ - 'Need one R.txt file per package' - - packages = list(extra_res_packages) - r_txt_files = list(extra_r_txt_files) - - if package and package not in packages: - # Sometimes, an apk target and a resources target share the same - # AndroidManifest.xml and thus |package| will already be in |packages|. - packages.append(package) - r_txt_files.append(main_r_txt_file) - - # Map of (resource_type, name) -> Entry. - # Contains the correct values for resources. - all_resources = {} - for entry in _ParseTextSymbolsFile(main_r_txt_file, fix_package_ids=True): - all_resources[(entry.resource_type, entry.name)] = entry - - # Map of package_name->resource_type->entry - resources_by_package = ( - collections.defaultdict(lambda: collections.defaultdict(list))) - # Build the R.java files using each package's R.txt file, but replacing - # each entry's placeholder value with correct values from all_resources. - for package, r_txt_file in zip(packages, r_txt_files): - if package in resources_by_package: - raise Exception(('Package name "%s" appeared twice. All ' - 'android_resources() targets must use unique package ' - 'names, or no package name at all.') % package) - resources_by_type = resources_by_package[package] - # The sub-R.txt files have the wrong values at this point. Read them to - # figure out which entries belong to them, but use the values from the - # main R.txt file. - for entry in _ParseTextSymbolsFile(r_txt_file): - entry = all_resources.get((entry.resource_type, entry.name)) - # For most cases missing entry here is an error. It means that some - # library claims to have or depend on a resource that isn't included into - # the APK. There is one notable exception: Google Play Services (GMS). - # GMS is shipped as a bunch of AARs. One of them - basement - contains - # R.txt with ids of all resources, but most of the resources are in the - # other AARs. However, all other AARs reference their resources via - # basement's R.java so the latter must contain all ids that are in its - # R.txt. Most targets depend on only a subset of GMS AARs so some - # resources are missing, which is okay because the code that references - # them is missing too. We can't get an id for a resource that isn't here - # so the only solution is to skip the resource entry entirely. - # - # We can verify that all entries referenced in the code were generated - # correctly by running Proguard on the APK: it will report missing - # fields. - if entry: - resources_by_type[entry.resource_type].append(entry) - - for package, resources_by_type in resources_by_package.iteritems(): - _CreateRJavaSourceFile(srcjar_dir, package, resources_by_type, - rjava_build_options) - - -def _CreateRJavaSourceFile(srcjar_dir, package, resources_by_type, - rjava_build_options): - """Generates an R.java source file.""" - package_r_java_dir = os.path.join(srcjar_dir, *package.split('.')) - build_utils.MakeDirectory(package_r_java_dir) - package_r_java_path = os.path.join(package_r_java_dir, 'R.java') - java_file_contents = _RenderRJavaSource(package, resources_by_type, - rjava_build_options) - with open(package_r_java_path, 'w') as f: - f.write(java_file_contents) - - -# Resource IDs inside resource arrays are sorted. Application resource IDs start -# with 0x7f but system resource IDs start with 0x01 thus system resource ids are -# always at the start of the array. This function finds the index of the first -# non system resource id to be used for package ID rewriting (we should not -# rewrite system resource ids). -def _GetNonSystemIndex(entry): - """Get the index of the first application resource ID within a resource - array.""" - res_ids = re.findall(r'0x[0-9a-f]{8}', entry.value) - for i, res_id in enumerate(res_ids): - if res_id.startswith('0x7f'): - return i - return len(res_ids) - - -def _RenderRJavaSource(package, resources_by_type, rjava_build_options): - """Render an R.java source file. See _CreateRJaveSourceFile for args info.""" - final_resources_by_type = collections.defaultdict(list) - non_final_resources_by_type = collections.defaultdict(list) - for res_type, resources in resources_by_type.iteritems(): - for entry in resources: - # Entries in stylable that are not int[] are not actually resource ids - # but constants. - if rjava_build_options._IsResourceFinal(entry): - final_resources_by_type[res_type].append(entry) - else: - non_final_resources_by_type[res_type].append(entry) - - # Keep these assignments all on one line to make diffing against regular - # aapt-generated files easier. - create_id = ('{{ e.resource_type }}.{{ e.name }} ^= packageIdTransform;') - create_id_arr = ('{{ e.resource_type }}.{{ e.name }}[i] ^=' - ' packageIdTransform;') - for_loop_condition = ('int i = {{ startIndex(e) }}; i < ' - '{{ e.resource_type }}.{{ e.name }}.length; ++i') - - # Here we diverge from what aapt does. Because we have so many - # resources, the onResourcesLoaded method was exceeding the 64KB limit that - # Java imposes. For this reason we split onResourcesLoaded into different - # methods for each resource type. - template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */ - -package {{ package }}; - -public final class R { - private static boolean sResourcesDidLoad; - {% for resource_type in resource_types %} - public static final class {{ resource_type }} { - {% for e in final_resources[resource_type] %} - public static final {{ e.java_type }} {{ e.name }} = {{ e.value }}; - {% endfor %} - {% for e in non_final_resources[resource_type] %} - public static {{ e.java_type }} {{ e.name }} = {{ e.value }}; - {% endfor %} - } - {% endfor %} - {% if has_on_resources_loaded %} - public static void onResourcesLoaded(int packageId) { - assert !sResourcesDidLoad; - sResourcesDidLoad = true; - int packageIdTransform = (packageId ^ 0x7f) << 24; - {% for resource_type in resource_types %} - onResourcesLoaded{{ resource_type|title }}(packageIdTransform); - {% for e in non_final_resources[resource_type] %} - {% if e.java_type == 'int[]' %} - for(""" + for_loop_condition + """) { - """ + create_id_arr + """ - } - {% endif %} - {% endfor %} - {% endfor %} - } - {% for res_type in resource_types %} - private static void onResourcesLoaded{{ res_type|title }} ( - int packageIdTransform) { - {% for e in non_final_resources[res_type] %} - {% if res_type != 'styleable' and e.java_type != 'int[]' %} - """ + create_id + """ - {% endif %} - {% endfor %} - } - {% endfor %} - {% endif %} -} -""", trim_blocks=True, lstrip_blocks=True) - - return template.render( - package=package, - resource_types=sorted(resources_by_type), - has_on_resources_loaded=rjava_build_options.has_on_resources_loaded, - final_resources=final_resources_by_type, - non_final_resources=non_final_resources_by_type, - startIndex=_GetNonSystemIndex) - - -def ExtractPackageFromManifest(manifest_path): - """Extract package name from Android manifest file.""" - doc = ElementTree.parse(manifest_path) - return doc.getroot().get('package') - - -def ExtractDeps(dep_zips, deps_dir): - """Extract a list of resource dependency zip files. - - Args: - dep_zips: A list of zip file paths, each one will be extracted to - a subdirectory of |deps_dir|, named after the zip file (e.g. - '/some/path/foo.zip' -> '{deps_dir}/foo/'). - deps_dir: Top-level extraction directory. - Returns: - The list of all sub-directory paths, relative to |deps_dir|. - Raises: - Exception: If a sub-directory already exists with the same name before - extraction. - """ - dep_subdirs = [] - for z in dep_zips: - subdir = os.path.join(deps_dir, os.path.basename(z)) - if os.path.exists(subdir): - raise Exception('Resource zip name conflict: ' + os.path.basename(z)) - build_utils.ExtractAll(z, path=subdir) - dep_subdirs.append(subdir) - return dep_subdirs - - -class _ResourceBuildContext(object): - """A temporary directory for packaging and compiling Android resources.""" - def __init__(self): - """Initialized the context.""" - # The top-level temporary directory. - self.temp_dir = tempfile.mkdtemp() - # A location to store resources extracted form dependency zip files. - self.deps_dir = os.path.join(self.temp_dir, 'deps') - os.mkdir(self.deps_dir) - # A location to place aapt-generated files. - self.gen_dir = os.path.join(self.temp_dir, 'gen') - os.mkdir(self.gen_dir) - # Location of the generated R.txt file. - self.r_txt_path = os.path.join(self.gen_dir, 'R.txt') - # A location to place generated R.java files. - self.srcjar_dir = os.path.join(self.temp_dir, 'java') - os.mkdir(self.srcjar_dir) - - def Close(self): - """Close the context and destroy all temporary files.""" - shutil.rmtree(self.temp_dir) - - -@contextlib.contextmanager -def BuildContext(): - """Generator for a _ResourceBuildContext instance.""" - try: - context = _ResourceBuildContext() - yield context - finally: - context.Close() - - -def ResourceArgsParser(): - """Create an argparse.ArgumentParser instance with common argument groups. - - Returns: - A tuple of (parser, in_group, out_group) corresponding to the parser - instance, and the input and output argument groups for it, respectively. - """ - parser = argparse.ArgumentParser(description=__doc__) - - input_opts = parser.add_argument_group('Input options') - output_opts = parser.add_argument_group('Output options') - - build_utils.AddDepfileOption(output_opts) - - input_opts.add_argument('--android-sdk-jars', required=True, - help='Path to the android.jar file.') - - input_opts.add_argument('--aapt-path', required=True, - help='Path to the Android aapt tool') - - input_opts.add_argument('--aapt2-path', - help='Path to the Android aapt2 tool. If in different' - ' directory from --aapt-path.') - - input_opts.add_argument('--dependencies-res-zips', required=True, - help='Resources zip archives from dependents. Required to ' - 'resolve @type/foo references into dependent ' - 'libraries.') - - input_opts.add_argument( - '--r-text-in', - help='Path to pre-existing R.txt. Its resource IDs override those found ' - 'in the aapt-generated R.txt when generating R.java.') - - input_opts.add_argument( - '--extra-res-packages', - help='Additional package names to generate R.java files for.') - - input_opts.add_argument( - '--extra-r-text-files', - help='For each additional package, the R.txt file should contain a ' - 'list of resources to be included in the R.java file in the format ' - 'generated by aapt.') - - return (parser, input_opts, output_opts) - - -def HandleCommonOptions(options): - """Handle common command-line options after parsing. - - Args: - options: the result of parse_args() on the parser returned by - ResourceArgsParser(). This function updates a few common fields. - """ - options.android_sdk_jars = build_utils.ParseGnList(options.android_sdk_jars) - - options.dependencies_res_zips = ( - build_utils.ParseGnList(options.dependencies_res_zips)) - - # Don't use [] as default value since some script explicitly pass "". - if options.extra_res_packages: - options.extra_res_packages = ( - build_utils.ParseGnList(options.extra_res_packages)) - else: - options.extra_res_packages = [] - - if options.extra_r_text_files: - options.extra_r_text_files = ( - build_utils.ParseGnList(options.extra_r_text_files)) - else: - options.extra_r_text_files = [] - - if not options.aapt2_path: - options.aapt2_path = options.aapt_path + '2' diff --git a/build/android/pylib/constants/host_paths_unittest.py b/build/android/pylib/constants/host_paths_unittest.py deleted file mode 100755 index 658ed08bd9..0000000000 --- a/build/android/pylib/constants/host_paths_unittest.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python -# Copyright 2018 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import logging -import os -import unittest - -import pylib.constants as constants -import pylib.constants.host_paths as host_paths - - -# This map corresponds to the binprefix of NDK prebuilt toolchains for various -# target CPU architectures. Note that 'x86_64' and 'x64' are the same. -_EXPECTED_NDK_TOOL_SUBDIR_MAP = { - 'arm': 'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/' + - 'arm-linux-androideabi-', - 'arm64': - 'toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/' + - 'aarch64-linux-android-', - 'x86': 'toolchains/x86-4.9/prebuilt/linux-x86_64/bin/i686-linux-android-', - 'x86_64': - 'toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-', - 'x64': - 'toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-', - 'mips': - 'toolchains/mipsel-linux-android-4.9/prebuilt/linux-x86_64/bin/' + - 'mipsel-linux-android-' -} - - -class HostPathsTest(unittest.TestCase): - def setUp(self): - logging.getLogger().setLevel(logging.ERROR) - - def test_GetAaptPath(self): - _EXPECTED_AAPT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'aapt') - self.assertEqual(host_paths.GetAaptPath(), _EXPECTED_AAPT_PATH) - self.assertEqual(host_paths.GetAaptPath(), _EXPECTED_AAPT_PATH) - - def test_ToolPath(self): - for cpu_arch, binprefix in _EXPECTED_NDK_TOOL_SUBDIR_MAP.iteritems(): - expected_binprefix = os.path.join(constants.ANDROID_NDK_ROOT, binprefix) - expected_path = expected_binprefix + 'foo' - self.assertEqual(host_paths.ToolPath('foo', cpu_arch), expected_path) - - -if __name__ == '__main__': - unittest.main() diff --git a/build/android/pylib/content_settings.py b/build/android/pylib/content_settings.py deleted file mode 100644 index 3bf11bc490..0000000000 --- a/build/android/pylib/content_settings.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - - -class ContentSettings(dict): - - """A dict interface to interact with device content settings. - - System properties are key/value pairs as exposed by adb shell content. - """ - - def __init__(self, table, device): - super(ContentSettings, self).__init__() - self._table = table - self._device = device - - @staticmethod - def _GetTypeBinding(value): - if isinstance(value, bool): - return 'b' - if isinstance(value, float): - return 'f' - if isinstance(value, int): - return 'i' - if isinstance(value, long): - return 'l' - if isinstance(value, str): - return 's' - raise ValueError('Unsupported type %s' % type(value)) - - def iteritems(self): - # Example row: - # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05' - for row in self._device.RunShellCommand( - 'content query --uri content://%s' % self._table, as_root=True): - fields = row.split(', ') - key = None - value = None - for field in fields: - k, _, v = field.partition('=') - if k == 'name': - key = v - elif k == 'value': - value = v - if not key: - continue - if not value: - value = '' - yield key, value - - def __getitem__(self, key): - return self._device.RunShellCommand( - 'content query --uri content://%s --where "name=\'%s\'" ' - '--projection value' % (self._table, key), as_root=True).strip() - - def __setitem__(self, key, value): - if key in self: - self._device.RunShellCommand( - 'content update --uri content://%s ' - '--bind value:%s:%s --where "name=\'%s\'"' % ( - self._table, - self._GetTypeBinding(value), value, key), - as_root=True) - else: - self._device.RunShellCommand( - 'content insert --uri content://%s ' - '--bind name:%s:%s --bind value:%s:%s' % ( - self._table, - self._GetTypeBinding(key), key, - self._GetTypeBinding(value), value), - as_root=True) - - def __delitem__(self, key): - self._device.RunShellCommand( - 'content delete --uri content://%s ' - '--bind name:%s:%s' % ( - self._table, - self._GetTypeBinding(key), key), - as_root=True) diff --git a/build/android/pylib/device_settings.py b/build/android/pylib/device_settings.py deleted file mode 100644 index ab4ad1b900..0000000000 --- a/build/android/pylib/device_settings.py +++ /dev/null @@ -1,199 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import logging - -from pylib import content_settings - -_LOCK_SCREEN_SETTINGS_PATH = '/data/system/locksettings.db' -_ALTERNATE_LOCK_SCREEN_SETTINGS_PATH = ( - '/data/data/com.android.providers.settings/databases/settings.db') -PASSWORD_QUALITY_UNSPECIFIED = '0' -_COMPATIBLE_BUILD_TYPES = ['userdebug', 'eng'] - - -def ConfigureContentSettings(device, desired_settings): - """Configures device content setings from a list. - - Many settings are documented at: - http://developer.android.com/reference/android/provider/Settings.Global.html - http://developer.android.com/reference/android/provider/Settings.Secure.html - http://developer.android.com/reference/android/provider/Settings.System.html - - Many others are undocumented. - - Args: - device: A DeviceUtils instance for the device to configure. - desired_settings: A list of (table, [(key: value), ...]) for all - settings to configure. - """ - for table, key_value in desired_settings: - settings = content_settings.ContentSettings(table, device) - for key, value in key_value: - settings[key] = value - logging.info('\n%s %s', table, (80 - len(table)) * '-') - for key, value in sorted(settings.iteritems()): - logging.info('\t%s: %s', key, value) - - -def SetLockScreenSettings(device): - """Sets lock screen settings on the device. - - On certain device/Android configurations we need to disable the lock screen in - a different database. Additionally, the password type must be set to - DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED. - Lock screen settings are stored in sqlite on the device in: - /data/system/locksettings.db - - IMPORTANT: The first column is used as a primary key so that all rows with the - same value for that column are removed from the table prior to inserting the - new values. - - Args: - device: A DeviceUtils instance for the device to configure. - - Raises: - Exception if the setting was not properly set. - """ - if device.build_type not in _COMPATIBLE_BUILD_TYPES: - logging.warning('Unable to disable lockscreen on %s builds.', - device.build_type) - return - - def get_lock_settings(table): - return [(table, 'lockscreen.disabled', '1'), - (table, 'lockscreen.password_type', PASSWORD_QUALITY_UNSPECIFIED), - (table, 'lockscreen.password_type_alternate', - PASSWORD_QUALITY_UNSPECIFIED)] - - if device.FileExists(_LOCK_SCREEN_SETTINGS_PATH): - db = _LOCK_SCREEN_SETTINGS_PATH - locksettings = get_lock_settings('locksettings') - columns = ['name', 'user', 'value'] - generate_values = lambda k, v: [k, '0', v] - elif device.FileExists(_ALTERNATE_LOCK_SCREEN_SETTINGS_PATH): - db = _ALTERNATE_LOCK_SCREEN_SETTINGS_PATH - locksettings = get_lock_settings('secure') + get_lock_settings('system') - columns = ['name', 'value'] - generate_values = lambda k, v: [k, v] - else: - logging.warning('Unable to find database file to set lock screen settings.') - return - - for table, key, value in locksettings: - # Set the lockscreen setting for default user '0' - values = generate_values(key, value) - - cmd = """begin transaction; -delete from '%(table)s' where %(primary_key)s='%(primary_value)s'; -insert into '%(table)s' (%(columns)s) values (%(values)s); -commit transaction;""" % { - 'table': table, - 'primary_key': columns[0], - 'primary_value': values[0], - 'columns': ', '.join(columns), - 'values': ', '.join(["'%s'" % value for value in values]) - } - output_msg = device.RunShellCommand('sqlite3 %s "%s"' % (db, cmd), - as_root=True) - if output_msg: - logging.info(' '.join(output_msg)) - - -ENABLE_LOCATION_SETTINGS = [ - # Note that setting these in this order is required in order for all of - # them to take and stick through a reboot. - ('com.google.settings/partner', [ - ('use_location_for_services', 1), - ]), - ('settings/secure', [ - # Ensure Geolocation is enabled and allowed for tests. - ('location_providers_allowed', 'gps,network'), - ]), - ('com.google.settings/partner', [ - ('network_location_opt_in', 1), - ]) -] - -DISABLE_LOCATION_SETTINGS = [ - ('com.google.settings/partner', [ - ('use_location_for_services', 0), - ]), - ('settings/secure', [ - # Ensure Geolocation is disabled. - ('location_providers_allowed', ''), - ]), -] - -ENABLE_MOCK_LOCATION_SETTINGS = [ - ('settings/secure', [ - ('mock_location', 1), - ]), -] - -DISABLE_MOCK_LOCATION_SETTINGS = [ - ('settings/secure', [ - ('mock_location', 0), - ]), -] - -DETERMINISTIC_DEVICE_SETTINGS = [ - ('settings/global', [ - ('assisted_gps_enabled', 0), - - # Disable "auto time" and "auto time zone" to avoid network-provided time - # to overwrite the device's datetime and timezone synchronized from host - # when running tests later. See b/6569849. - ('auto_time', 0), - ('auto_time_zone', 0), - - ('development_settings_enabled', 1), - - # Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents - # on application crashes and ANRs. If this is disabled, the crash/ANR dialog - # will never display the "Report" button. - # Type: int ( 0 = disallow, 1 = allow ) - ('send_action_app_error', 0), - - ('stay_on_while_plugged_in', 3), - - ('verifier_verify_adb_installs', 0), - ]), - ('settings/secure', [ - ('allowed_geolocation_origins', - 'http://www.google.co.uk http://www.google.com'), - - # Ensure that we never get random dialogs like "Unfortunately the process - # android.process.acore has stopped", which steal the focus, and make our - # automation fail (because the dialog steals the focus then mistakenly - # receives the injected user input events). - ('anr_show_background', 0), - - ('lockscreen.disabled', 1), - - ('screensaver_enabled', 0), - - ('skip_first_use_hints', 1), - ]), - ('settings/system', [ - # Don't want devices to accidentally rotate the screen as that could - # affect performance measurements. - ('accelerometer_rotation', 0), - - ('lockscreen.disabled', 1), - - # Turn down brightness and disable auto-adjust so that devices run cooler. - ('screen_brightness', 5), - ('screen_brightness_mode', 0), - - ('user_rotation', 0), - ]), -] - -NETWORK_DISABLED_SETTINGS = [ - ('settings/global', [ - ('airplane_mode_on', 1), - ('wifi_on', 0), - ]), -] diff --git a/build/android/pylib/pexpect.py b/build/android/pylib/pexpect.py deleted file mode 100644 index cf59fb0f6d..0000000000 --- a/build/android/pylib/pexpect.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -from __future__ import absolute_import - -import os -import sys - -_CHROME_SRC = os.path.join( - os.path.abspath(os.path.dirname(__file__)), '..', '..', '..') - -_PEXPECT_PATH = os.path.join(_CHROME_SRC, 'third_party', 'pexpect') -if _PEXPECT_PATH not in sys.path: - sys.path.append(_PEXPECT_PATH) - -# pexpect is not available on all platforms. We allow this file to be imported -# on platforms without pexpect and only fail when pexpect is actually used. -try: - from pexpect import * # pylint: disable=W0401,W0614 -except ImportError: - pass diff --git a/build/android/pylib/restart_adbd.sh b/build/android/pylib/restart_adbd.sh deleted file mode 100755 index 393b2ebac0..0000000000 --- a/build/android/pylib/restart_adbd.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/system/bin/sh - -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Android shell script to restart adbd on the device. This has to be run -# atomically as a shell script because stopping adbd prevents further commands -# from running (even if called in the same adb shell). - -trap '' HUP -trap '' TERM -trap '' PIPE - -function restart() { - stop adbd - start adbd -} - -restart & diff --git a/build/android/pylib/valgrind_tools.py b/build/android/pylib/valgrind_tools.py deleted file mode 100644 index 3dc2488b26..0000000000 --- a/build/android/pylib/valgrind_tools.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# pylint: disable=R0201 - -import glob -import logging -import os.path -import subprocess -import sys - -from devil.android import device_errors -from devil.android.valgrind_tools import base_tool -from pylib.constants import DIR_SOURCE_ROOT - - -def SetChromeTimeoutScale(device, scale): - """Sets the timeout scale in /data/local/tmp/chrome_timeout_scale to scale.""" - path = '/data/local/tmp/chrome_timeout_scale' - if not scale or scale == 1.0: - # Delete if scale is None/0.0/1.0 since the default timeout scale is 1.0 - device.RemovePath(path, force=True, as_root=True) - else: - device.WriteFile(path, '%f' % scale, as_root=True) - - - -class AddressSanitizerTool(base_tool.BaseTool): - """AddressSanitizer tool.""" - - WRAPPER_NAME = '/system/bin/asanwrapper' - # Disable memcmp overlap check.There are blobs (gl drivers) - # on some android devices that use memcmp on overlapping regions, - # nothing we can do about that. - EXTRA_OPTIONS = 'strict_memcmp=0,use_sigaltstack=1' - - def __init__(self, device): - super(AddressSanitizerTool, self).__init__() - self._device = device - - @classmethod - def CopyFiles(cls, device): - """Copies ASan tools to the device.""" - libs = glob.glob(os.path.join(DIR_SOURCE_ROOT, - 'third_party/llvm-build/Release+Asserts/', - 'lib/clang/*/lib/linux/', - 'libclang_rt.asan-arm-android.so')) - assert len(libs) == 1 - subprocess.call( - [os.path.join( - DIR_SOURCE_ROOT, - 'tools/android/asan/third_party/asan_device_setup.sh'), - '--device', str(device), - '--lib', libs[0], - '--extra-options', AddressSanitizerTool.EXTRA_OPTIONS]) - device.WaitUntilFullyBooted() - - def GetTestWrapper(self): - return AddressSanitizerTool.WRAPPER_NAME - - def GetUtilWrapper(self): - """Returns the wrapper for utilities, such as forwarder. - - AddressSanitizer wrapper must be added to all instrumented binaries, - including forwarder and the like. This can be removed if such binaries - were built without instrumentation. """ - return self.GetTestWrapper() - - def SetupEnvironment(self): - try: - self._device.EnableRoot() - except device_errors.CommandFailedError as e: - # Try to set the timeout scale anyway. - # TODO(jbudorick) Handle this exception appropriately after interface - # conversions are finished. - logging.error(str(e)) - SetChromeTimeoutScale(self._device, self.GetTimeoutScale()) - - def CleanUpEnvironment(self): - SetChromeTimeoutScale(self._device, None) - - def GetTimeoutScale(self): - # Very slow startup. - return 20.0 - - -TOOL_REGISTRY = { - 'asan': AddressSanitizerTool, -} - - -def CreateTool(tool_name, device): - """Creates a tool with the specified tool name. - - Args: - tool_name: Name of the tool to create. - device: A DeviceUtils instance. - Returns: - A tool for the specified tool_name. - """ - if not tool_name: - return base_tool.BaseTool() - - ctor = TOOL_REGISTRY.get(tool_name) - if ctor: - return ctor(device) - else: - print 'Unknown tool %s, available tools: %s' % ( - tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) - sys.exit(1) - -def PushFilesForTool(tool_name, device): - """Pushes the files required for |tool_name| to |device|. - - Args: - tool_name: Name of the tool to create. - device: A DeviceUtils instance. - """ - if not tool_name: - return - - clazz = TOOL_REGISTRY.get(tool_name) - if clazz: - clazz.CopyFiles(device) - else: - print 'Unknown tool %s, available tools: %s' % ( - tool_name, ', '.join(sorted(TOOL_REGISTRY.keys()))) - sys.exit(1) - |