OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Gathers information about APKs.""" | 5 """Gathers information about APKs.""" |
6 | 6 |
7 import collections | 7 import collections |
8 import logging | |
8 import os | 9 import os |
10 import pickle | |
9 import re | 11 import re |
10 | 12 |
11 import cmd_helper | 13 import cmd_helper |
12 | 14 |
15 # If you change the cached output of proguard, increment this number | |
16 PICKLE_FORMAT_VERSION = 1 | |
13 | 17 |
14 def GetPackageNameForApk(apk_path): | 18 def GetPackageNameForApk(apk_path): |
15 """Returns the package name of the apk file.""" | 19 """Returns the package name of the apk file.""" |
16 aapt_output = cmd_helper.GetCmdOutput( | 20 aapt_output = cmd_helper.GetCmdOutput( |
17 ['aapt', 'dump', 'badging', apk_path]).split('\n') | 21 ['aapt', 'dump', 'badging', apk_path]).split('\n') |
18 package_name_re = re.compile(r'package: .*name=\'(\S*)\'') | 22 package_name_re = re.compile(r'package: .*name=\'(\S*)\'') |
19 for line in aapt_output: | 23 for line in aapt_output: |
20 m = package_name_re.match(line) | 24 m = package_name_re.match(line) |
21 if m: | 25 if m: |
22 return m.group(1) | 26 return m.group(1) |
(...skipping 20 matching lines...) Expand all Loading... | |
43 raise Exception('%s not found, please build it' % apk_path) | 47 raise Exception('%s not found, please build it' % apk_path) |
44 self._apk_path = apk_path | 48 self._apk_path = apk_path |
45 if not os.path.exists(jar_path): | 49 if not os.path.exists(jar_path): |
46 raise Exception('%s not found, please build it' % jar_path) | 50 raise Exception('%s not found, please build it' % jar_path) |
47 self._jar_path = jar_path | 51 self._jar_path = jar_path |
48 self._annotation_map = collections.defaultdict(list) | 52 self._annotation_map = collections.defaultdict(list) |
49 self._test_methods = [] | 53 self._test_methods = [] |
50 self._Initialize() | 54 self._Initialize() |
51 | 55 |
52 def _Initialize(self): | 56 def _Initialize(self): |
57 pickle_name = self._jar_path + '-proguard.pickle' | |
58 if os.path.exists(pickle_name) and (os.path.getmtime(pickle_name) > | |
59 os.path.getmtime(self._jar_path)): | |
60 logging.info('Loading cached proguard output from %s', pickle_name) | |
61 try: | |
62 with open(pickle_name, 'r') as r: | |
63 d = pickle.loads(r.read()) | |
64 if d['VERSION'] == PICKLE_FORMAT_VERSION: | |
65 self._annotation_map = d['ANNOTATION_MAP'] | |
66 self._test_methods = d['TEST_METHODS'] | |
67 return | |
68 except: | |
69 logging.warning('PICKLE_FORMAT_VERSION has changed, ignoring cache') | |
frankf
2012/11/26 19:09:08
Optional: For sake of modularity, can you factor o
Yaron
2012/11/27 18:06:18
Done.
| |
70 | |
53 proguard_output = cmd_helper.GetCmdOutput([self._PROGUARD_PATH, | 71 proguard_output = cmd_helper.GetCmdOutput([self._PROGUARD_PATH, |
54 '-injars', self._jar_path, | 72 '-injars', self._jar_path, |
55 '-dontshrink', | 73 '-dontshrink', |
56 '-dontoptimize', | 74 '-dontoptimize', |
57 '-dontobfuscate', | 75 '-dontobfuscate', |
58 '-dontpreverify', | 76 '-dontpreverify', |
59 '-dump', | 77 '-dump', |
60 ]).split('\n') | 78 ]).split('\n') |
61 clazz = None | 79 clazz = None |
62 method = None | 80 method = None |
(...skipping 28 matching lines...) Expand all Loading... | |
91 if m: | 109 if m: |
92 has_value = True | 110 has_value = True |
93 else: | 111 else: |
94 m = self._PROGUARD_ANNOTATION_VALUE_RE.match(line) | 112 m = self._PROGUARD_ANNOTATION_VALUE_RE.match(line) |
95 if m: | 113 if m: |
96 value = m.group(1) | 114 value = m.group(1) |
97 self._annotation_map[qualified_method].append( | 115 self._annotation_map[qualified_method].append( |
98 annotation + ':' + value) | 116 annotation + ':' + value) |
99 has_value = False | 117 has_value = False |
100 | 118 |
119 logging.info('Storing proguard output to %s', pickle_name) | |
120 d = {'VERSION': PICKLE_FORMAT_VERSION, | |
121 'ANNOTATION_MAP': self._annotation_map, | |
122 'TEST_METHODS': self._test_methods} | |
123 with open(pickle_name, 'w') as f: | |
124 f.write(pickle.dumps(d)) | |
125 | |
101 def _GetAnnotationMap(self): | 126 def _GetAnnotationMap(self): |
102 return self._annotation_map | 127 return self._annotation_map |
103 | 128 |
104 def _IsTestMethod(self, test): | 129 def _IsTestMethod(self, test): |
105 class_name, method = test.split('#') | 130 class_name, method = test.split('#') |
106 return class_name.endswith('Test') and method.startswith('test') | 131 return class_name.endswith('Test') and method.startswith('test') |
107 | 132 |
108 def GetApkPath(self): | 133 def GetApkPath(self): |
109 return self._apk_path | 134 return self._apk_path |
110 | 135 |
(...skipping 29 matching lines...) Expand all Loading... | |
140 if self._IsTestMethod(test) and self._AnnotationsMatchFilters( | 165 if self._IsTestMethod(test) and self._AnnotationsMatchFilters( |
141 annotation_filter_list, annotations)] | 166 annotation_filter_list, annotations)] |
142 | 167 |
143 def GetTestMethods(self): | 168 def GetTestMethods(self): |
144 """Returns a list of all test methods in this apk as Class#testMethod.""" | 169 """Returns a list of all test methods in this apk as Class#testMethod.""" |
145 return self._test_methods | 170 return self._test_methods |
146 | 171 |
147 @staticmethod | 172 @staticmethod |
148 def IsPythonDrivenTest(test): | 173 def IsPythonDrivenTest(test): |
149 return 'pythonDrivenTests' in test | 174 return 'pythonDrivenTests' in test |
OLD | NEW |