Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: devil/devil/android/apk_helper.py

Issue 3000783002: Revert of ApkHelper: Add GetViewActivityName(). Make GetActivityName() more strict (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | devil/devil/android/apk_helper_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2013 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 """Module containing utilities for apk packages.""" 5 """Module containing utilities for apk packages."""
6 6
7 import itertools 7 import itertools
8 import re 8 import re
9 9
10 from devil import base_error 10 from devil import base_error
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 if manifest_key in node: 70 if manifest_key in node:
71 raise base_error.BaseError( 71 raise base_error.BaseError(
72 "A single attribute should have one key and one value") 72 "A single attribute should have one key and one value")
73 else: 73 else:
74 node[manifest_key] = m.group(2) or m.group(3) 74 node[manifest_key] = m.group(2) or m.group(3)
75 continue 75 continue
76 76
77 return parsed_manifest 77 return parsed_manifest
78 78
79 79
80 def _ParseNumericKey(obj, key, default=0):
81 val = obj.get(key)
82 if val is None:
83 return default
84 return int(val, 0)
85
86
87 class _ExportedActivity(object):
88 def __init__(self, name):
89 self.name = name
90 self.actions = set()
91 self.categories = set()
92 self.schemes = set()
93
94
95 def _IterateExportedActivities(manifest_info):
96 app_node = manifest_info['manifest'][0]['application'][0]
97 activities = app_node.get('activity', []) + app_node.get('activity-alias', [])
98 for activity_node in activities:
99 if not _ParseNumericKey(activity_node, 'android:exported'):
100 continue
101 activity = _ExportedActivity(activity_node.get('android:name'))
102 # Merge all intent-filters into a single set because there is not
103 # currently a need to keep them separate.
104 for intent_filter in activity_node.get('intent-filter', []):
105 for action in intent_filter.get('action', []):
106 activity.actions.add(action.get('android:name'))
107 for category in intent_filter.get('category', []):
108 activity.categories.add(category.get('android:name'))
109 for data in intent_filter.get('data', []):
110 activity.schemes.add(data.get('android:scheme'))
111 yield activity
112
113
114 class ApkHelper(object): 80 class ApkHelper(object):
115 81
116 def __init__(self, path): 82 def __init__(self, path):
117 self._apk_path = path 83 self._apk_path = path
118 self._manifest = None 84 self._manifest = None
119 85
120 @property 86 @property
121 def path(self): 87 def path(self):
122 return self._apk_path 88 return self._apk_path
123 89
124 def GetActivityName(self): 90 def GetActivityName(self):
125 """Returns the name of the first launcher Activity in the apk.""" 91 """Returns the name of the Activity in the apk."""
126 manifest_info = self._GetManifest() 92 manifest_info = self._GetManifest()
127 for activity in _IterateExportedActivities(manifest_info): 93 try:
128 if ('android.intent.action.MAIN' in activity.actions and 94 activity = (
129 'android.intent.category.LAUNCHER' in activity.categories): 95 manifest_info['manifest'][0]['application'][0]['activity'][0]
130 return self._ResolveName(activity.name) 96 ['android:name'])
131 return None 97 except KeyError:
132 98 return None
133 def GetViewActivityName(self): 99 if '.' not in activity:
134 """Returns name of the first action=View Activity that can handle http.""" 100 activity = '%s.%s' % (self.GetPackageName(), activity)
135 manifest_info = self._GetManifest() 101 elif activity.startswith('.'):
136 for activity in _IterateExportedActivities(manifest_info): 102 activity = '%s%s' % (self.GetPackageName(), activity)
137 if ('android.intent.action.VIEW' in activity.actions and 103 return activity
138 'http' in activity.schemes):
139 return self._ResolveName(activity.name)
140 return None
141 104
142 def GetInstrumentationName( 105 def GetInstrumentationName(
143 self, default='android.test.InstrumentationTestRunner'): 106 self, default='android.test.InstrumentationTestRunner'):
144 """Returns the name of the Instrumentation in the apk.""" 107 """Returns the name of the Instrumentation in the apk."""
145 all_instrumentations = self.GetAllInstrumentations(default=default) 108 all_instrumentations = self.GetAllInstrumentations(default=default)
146 if len(all_instrumentations) != 1: 109 if len(all_instrumentations) != 1:
147 raise base_error.BaseError( 110 raise base_error.BaseError(
148 'There is more than one instrumentation. Expected one.') 111 'There is more than one instrumentation. Expected one.')
149 else: 112 else:
150 return self._ResolveName(all_instrumentations[0]['android:name']) 113 return all_instrumentations[0]['android:name']
151 114
152 def GetAllInstrumentations( 115 def GetAllInstrumentations(
153 self, default='android.test.InstrumentationTestRunner'): 116 self, default='android.test.InstrumentationTestRunner'):
154 """Returns a list of all Instrumentations in the apk.""" 117 """Returns a list of all Instrumentations in the apk."""
155 try: 118 try:
156 return self._GetManifest()['manifest'][0]['instrumentation'] 119 return self._GetManifest()['manifest'][0]['instrumentation']
157 except KeyError: 120 except KeyError:
158 return [{'android:name': default}] 121 return [{'android:name': default}]
159 122
160 def GetPackageName(self): 123 def GetPackageName(self):
(...skipping 21 matching lines...) Expand all
182 return None 145 return None
183 146
184 def HasIsolatedProcesses(self): 147 def HasIsolatedProcesses(self):
185 """Returns whether any services exist that use isolatedProcess=true.""" 148 """Returns whether any services exist that use isolatedProcess=true."""
186 manifest_info = self._GetManifest() 149 manifest_info = self._GetManifest()
187 try: 150 try:
188 applications = manifest_info['manifest'][0].get('application', []) 151 applications = manifest_info['manifest'][0].get('application', [])
189 services = itertools.chain( 152 services = itertools.chain(
190 *(application.get('service', []) for application in applications)) 153 *(application.get('service', []) for application in applications))
191 return any( 154 return any(
192 _ParseNumericKey(s, 'android:isolatedProcess') for s in services) 155 int(s.get('android:isolatedProcess', '0'), 0)
156 for s in services)
193 except KeyError: 157 except KeyError:
194 return False 158 return False
195 159
196 def _GetManifest(self): 160 def _GetManifest(self):
197 if not self._manifest: 161 if not self._manifest:
198 self._manifest = _ParseManifestFromApk(self._apk_path) 162 self._manifest = _ParseManifestFromApk(self._apk_path)
199 return self._manifest 163 return self._manifest
200 164
201 def _ResolveName(self, name):
202 name = name.lstrip('.')
203 if '.' not in name:
204 return '%s.%s' % (self.GetPackageName(), name)
205 return name
OLDNEW
« no previous file with comments | « no previous file | devil/devil/android/apk_helper_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698