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

Unified Diff: devil/devil/android/apk_helper.py

Issue 2994053002: ApkHelper: Add GetViewActivityName(). Make GetActivityName() more strict (Closed)
Patch Set: nits 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | devil/devil/android/apk_helper_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: devil/devil/android/apk_helper.py
diff --git a/devil/devil/android/apk_helper.py b/devil/devil/android/apk_helper.py
index 1a9b8c55107e1dd0912f5a84a5cbb70567338013..54eb92152f03a674f2143c18c5c11e1c2a10429c 100644
--- a/devil/devil/android/apk_helper.py
+++ b/devil/devil/android/apk_helper.py
@@ -77,6 +77,40 @@ def _ParseManifestFromApk(apk_path):
return parsed_manifest
+def _ParseNumericKey(obj, key, default=0):
+ val = obj.get(key)
+ if val is None:
+ return default
+ return int(val, 0)
+
+
+class _ExportedActivity(object):
+ def __init__(self, name):
+ self.name = name
+ self.actions = set()
+ self.categories = set()
+ self.schemes = set()
+
+
+def _IterateExportedActivities(manifest_info):
+ app_node = manifest_info['manifest'][0]['application'][0]
+ activities = app_node.get('activity', []) + app_node.get('activity-alias', [])
+ for activity_node in activities:
+ if not _ParseNumericKey(activity_node, 'android:exported'):
+ continue
+ activity = _ExportedActivity(activity_node.get('android:name'))
+ # Merge all intent-filters into a single set because there is not
+ # currently a need to keep them separate.
+ for intent_filter in activity_node.get('intent-filter', []):
+ for action in intent_filter.get('action', []):
+ activity.actions.add(action.get('android:name'))
+ for category in intent_filter.get('category', []):
+ activity.categories.add(category.get('android:name'))
+ for data in intent_filter.get('data', []):
+ activity.schemes.add(data.get('android:scheme'))
+ yield activity
+
+
class ApkHelper(object):
def __init__(self, path):
@@ -88,19 +122,22 @@ class ApkHelper(object):
return self._apk_path
def GetActivityName(self):
- """Returns the name of the Activity in the apk."""
+ """Returns the name of the first launcher Activity in the apk."""
manifest_info = self._GetManifest()
- try:
- activity = (
- manifest_info['manifest'][0]['application'][0]['activity'][0]
- ['android:name'])
- except KeyError:
- return None
- if '.' not in activity:
- activity = '%s.%s' % (self.GetPackageName(), activity)
- elif activity.startswith('.'):
- activity = '%s%s' % (self.GetPackageName(), activity)
- return activity
+ for activity in _IterateExportedActivities(manifest_info):
+ if ('android.intent.action.MAIN' in activity.actions and
+ 'android.intent.category.LAUNCHER' in activity.categories):
+ return self._ResolveName(activity.name)
+ return None
+
+ def GetViewActivityName(self):
+ """Returns name of the first action=View Activity that can handle http."""
+ manifest_info = self._GetManifest()
+ for activity in _IterateExportedActivities(manifest_info):
+ if ('android.intent.action.VIEW' in activity.actions and
+ 'http' in activity.schemes):
+ return self._ResolveName(activity.name)
+ return None
def GetInstrumentationName(
self, default='android.test.InstrumentationTestRunner'):
@@ -110,7 +147,7 @@ class ApkHelper(object):
raise base_error.BaseError(
'There is more than one instrumentation. Expected one.')
else:
- return all_instrumentations[0]['android:name']
+ return self._ResolveName(all_instrumentations[0]['android:name'])
def GetAllInstrumentations(
self, default='android.test.InstrumentationTestRunner'):
@@ -152,8 +189,7 @@ class ApkHelper(object):
services = itertools.chain(
*(application.get('service', []) for application in applications))
return any(
- int(s.get('android:isolatedProcess', '0'), 0)
- for s in services)
+ _ParseNumericKey(s, 'android:isolatedProcess') for s in services)
except KeyError:
return False
@@ -162,3 +198,8 @@ class ApkHelper(object):
self._manifest = _ParseManifestFromApk(self._apk_path)
return self._manifest
+ def _ResolveName(self, name):
+ name = name.lstrip('.')
+ if '.' not in name:
+ return '%s.%s' % (self.GetPackageName(), name)
+ return name
« 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