Skip to content

Commit

Permalink
Migrate DeviceUtils.StartActivity to adb_wrapper
Browse files Browse the repository at this point in the history
The implementation runs an 'am' shell command with the
relevant options and the args of the given intent.
Output is parsed to check for any errors.

BUG=267773

Review URL: https://codereview.chromium.org/802323002

Cr-Commit-Position: refs/heads/master@{#308600}
  • Loading branch information
perezju authored and Commit bot committed Dec 16, 2014
1 parent b6c0ec4 commit 4c75d6a
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 86 deletions.
35 changes: 15 additions & 20 deletions build/android/pylib/device/device_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,12 @@ def KillAll(self, process_name, signum=9, as_root=False, blocking=False,
return len(pids)

@decorators.WithTimeoutAndRetriesFromInstance()
def StartActivity(self, intent, blocking=False, trace_file_name=None,
def StartActivity(self, intent_obj, blocking=False, trace_file_name=None,
force_stop=False, timeout=None, retries=None):
"""Start package's activity on the device.
Args:
intent: An Intent to send.
intent_obj: An Intent object to send.
blocking: A boolean indicating whether we should wait for the activity to
finish launching.
trace_file_name: If present, a string that both indicates that we want to
Expand All @@ -531,16 +531,17 @@ def StartActivity(self, intent, blocking=False, trace_file_name=None,
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
single_category = (intent.category[0] if isinstance(intent.category, list)
else intent.category)
output = self.old_interface.StartActivity(
intent.package, intent.activity, wait_for_completion=blocking,
action=intent.action, category=single_category, data=intent.data,
extras=intent.extras, trace_file_name=trace_file_name,
force_stop=force_stop, flags=intent.flags)
for l in output:
if l.startswith('Error:'):
raise device_errors.CommandFailedError(l, str(self))
cmd = ['am', 'start']
if blocking:
cmd.append('-W')
if trace_file_name:
cmd.extend(['--start-profiler', trace_file_name])
if force_stop:
cmd.append('-S')
cmd.extend(intent_obj.am_args)
for line in self.RunShellCommand(cmd, check_return=True):
if line.startswith('Error:'):
raise device_errors.CommandFailedError(line, str(self))

@decorators.WithTimeoutAndRetriesFromInstance()
def StartInstrumentation(self, component, finish=True, raw=False,
Expand All @@ -559,7 +560,7 @@ def StartInstrumentation(self, component, finish=True, raw=False,
return self.RunShellCommand(cmd, check_return=True)

@decorators.WithTimeoutAndRetriesFromInstance()
def BroadcastIntent(self, intent, timeout=None, retries=None):
def BroadcastIntent(self, intent_obj, timeout=None, retries=None):
"""Send a broadcast intent.
Args:
Expand All @@ -571,13 +572,7 @@ def BroadcastIntent(self, intent, timeout=None, retries=None):
CommandTimeoutError on timeout.
DeviceUnreachableError on missing device.
"""
cmd = ['am', 'broadcast', '-a', intent.action]
if intent.extras:
for key, value in intent.extras.iteritems():
if key:
cmd.extend(['-e', key])
if value:
cmd.append(str(value))
cmd = ['am', 'broadcast'] + intent_obj.am_args
self.RunShellCommand(cmd, check_return=True)

@decorators.WithTimeoutAndRetriesFromInstance()
Expand Down
131 changes: 65 additions & 66 deletions build/android/pylib/device/device_utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,35 +658,35 @@ def testKillAll_sigterm(self):
self.device.KillAll('some.process', signum=signal.SIGTERM))


class DeviceUtilsStartActivityTest(DeviceUtilsOldImplTest):
class DeviceUtilsStartActivityTest(DeviceUtilsNewImplTest):

def testStartActivity_actionOnly(self):
test_intent = intent.Intent(action='android.intent.action.VIEW')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

def testStartActivity_success(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

def testStartActivity_failure(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Error: Failed to start test activity'):
with self.assertRaises(device_errors.CommandFailedError):
self.device.StartActivity(test_intent)
Expand All @@ -695,11 +695,11 @@ def testStartActivity_blocking(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-W "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-W '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent, blocking=True)

Expand All @@ -708,27 +708,26 @@ def testStartActivity_withCategory(self):
package='this.is.a.test.package',
activity='.Main',
category='android.intent.category.HOME')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-c android.intent.category.HOME "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-c android.intent.category.HOME '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

def testStartActivity_withMultipleCategories(self):
# The new implementation will start the activity with all provided
# categories. The old one only uses the first category.
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main',
category=['android.intent.category.HOME',
'android.intent.category.BROWSABLE'])
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-c android.intent.category.HOME "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-c android.intent.category.HOME '
'-c android.intent.category.BROWSABLE '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

Expand All @@ -737,11 +736,11 @@ def testStartActivity_withData(self):
package='this.is.a.test.package',
activity='.Main',
data='http://www.google.com/')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"-d \"http://www.google.com/\"'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-d http://www.google.com/ '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

Expand All @@ -750,11 +749,11 @@ def testStartActivity_withStringExtra(self):
package='this.is.a.test.package',
activity='.Main',
extras={'foo': 'test'})
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"--es foo test'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--es foo test'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

Expand All @@ -763,11 +762,11 @@ def testStartActivity_withBoolExtra(self):
package='this.is.a.test.package',
activity='.Main',
extras={'foo': True})
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"--ez foo True'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--ez foo True'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

Expand All @@ -776,23 +775,23 @@ def testStartActivity_withIntExtra(self):
package='this.is.a.test.package',
activity='.Main',
extras={'foo': 123})
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"--ei foo 123'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'--ei foo 123'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

def testStartActivity_withTraceFile(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"--start-profiler test_trace_file.out'",
with self.assertCall(
self.call.adb.Shell('am start '
'--start-profiler test_trace_file.out '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent,
trace_file_name='test_trace_file.out')
Expand All @@ -801,11 +800,11 @@ def testStartActivity_withForceStop(self):
test_intent = intent.Intent(action='android.intent.action.VIEW',
package='this.is.a.test.package',
activity='.Main')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-S "
"-n this.is.a.test.package/.Main'",
with self.assertCall(
self.call.adb.Shell('am start '
'-S '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent, force_stop=True)

Expand All @@ -814,11 +813,11 @@ def testStartActivity_withFlags(self):
package='this.is.a.test.package',
activity='.Main',
flags='0x10000000')
with self.assertCalls(
"adb -s 0123456789abcdef shell 'am start "
"-a android.intent.action.VIEW "
"-n this.is.a.test.package/.Main "
"-f 0x10000000'",
with self.assertCall(
self.call.adb.Shell('am start '
'-a android.intent.action.VIEW '
'-n this.is.a.test.package/.Main '
'-f 0x10000000'),
'Starting: Intent { act=android.intent.action.VIEW }'):
self.device.StartActivity(test_intent)

Expand Down Expand Up @@ -879,7 +878,7 @@ def testBroadcastIntent_withExtra(self):
extras={'foo': 'bar value'})
with self.assertCall(
self.call.adb.Shell(
"am broadcast -a test.package.with.an.INTENT -e foo 'bar value'"),
"am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"),
'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
self.device.BroadcastIntent(test_intent)

Expand All @@ -888,7 +887,7 @@ def testBroadcastIntent_withExtra_noValue(self):
extras={'foo': None})
with self.assertCall(
self.call.adb.Shell(
'am broadcast -a test.package.with.an.INTENT -e foo'),
'am broadcast -a test.package.with.an.INTENT --esn foo'),
'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
self.device.BroadcastIntent(test_intent)

Expand Down
34 changes: 34 additions & 0 deletions build/android/pylib/device/intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,37 @@ def flags(self):
def package(self):
return self._package

@property
def am_args(self):
"""Returns the intent as a list of arguments for the activity manager.
For details refer to the specification at:
- http://developer.android.com/tools/help/adb.html#IntentSpec
"""
args = []
if self.action:
args.extend(['-a', self.action])
if self.data:
args.extend(['-d', self.data])
if self.category:
args.extend(arg for cat in self.category for arg in ('-c', cat))
if self.component:
args.extend(['-n', self.component])
if self.flags:
args.extend(['-f', self.flags])
if self.extras:
for key, value in self.extras.iteritems():
if value is None:
args.extend(['--esn', key])
elif isinstance(value, str):
args.extend(['--es', key, value])
elif isinstance(value, bool):
args.extend(['--ez', key, str(value)])
elif isinstance(value, int):
args.extend(['--ei', key, str(value)])
elif isinstance(value, float):
args.extend(['--ef', key, str(value)])
else:
raise NotImplementedError(
'Intent does not know how to pass %s extras' % type(value))
return args

0 comments on commit 4c75d6a

Please sign in to comment.