Always operate on the current user in `snippet_client`. (#647)
diff --git a/mobly/controllers/android_device_lib/snippet_client.py b/mobly/controllers/android_device_lib/snippet_client.py
index cc6e74a..218ef46 100644
--- a/mobly/controllers/android_device_lib/snippet_client.py
+++ b/mobly/controllers/android_device_lib/snippet_client.py
@@ -39,8 +39,9 @@
# existing clients.
_PROTOCOL_MINOR_VERSION = 0
-_LAUNCH_CMD = ('%s am instrument -w -e action start %s/' +
- _INSTRUMENTATION_RUNNER_PACKAGE)
+_LAUNCH_CMD = (
+ '{shell_cmd} am instrument --user {user} -w -e action start {snippet_package}/'
+ + _INSTRUMENTATION_RUNNER_PACKAGE)
_STOP_CMD = ('am instrument -w -e action stop %s/' +
_INSTRUMENTATION_RUNNER_PACKAGE)
@@ -155,7 +156,9 @@
self.log.info('Launching snippet apk %s with protocol %d.%d',
self.package, _PROTOCOL_MAJOR_VERSION,
_PROTOCOL_MINOR_VERSION)
- cmd = _LAUNCH_CMD % (persists_shell_cmd, self.package)
+ cmd = _LAUNCH_CMD.format(shell_cmd=persists_shell_cmd,
+ user=self._adb.current_user_id,
+ snippet_package=self.package)
start_time = time.time()
self._proc = self._do_start_app(cmd)
@@ -259,11 +262,13 @@
self._event_client.connect()
def _check_app_installed(self):
- # Check that the Mobly Snippet app is installed.
- out = self._adb.shell('pm list package')
+ # Check that the Mobly Snippet app is installed for the current user.
+ user_id = self._adb.current_user_id
+ out = self._adb.shell('pm list package --user %s' % user_id)
if not utils.grep('^package:%s$' % self.package, out):
- raise AppStartPreCheckError(self._ad,
- '%s is not installed.' % self.package)
+ raise AppStartPreCheckError(
+ self._ad,
+ '%s is not installed for user %s.' % (self.package, user_id))
# Check that the app is instrumented.
out = self._adb.shell('pm list instrumentation')
matched_out = utils.grep(
@@ -279,11 +284,12 @@
# Check that the instrumentation target is installed if it's not the
# same as the snippet package.
if target_name != self.package:
- out = self._adb.shell('pm list package')
+ out = self._adb.shell('pm list package --user %s' % user_id)
if not utils.grep('^package:%s$' % target_name, out):
raise AppStartPreCheckError(
- self._ad, 'Instrumentation target %s is not installed.' %
- target_name)
+ self._ad,
+ 'Instrumentation target %s is not installed for user %s.' %
+ (target_name, user_id))
def _do_start_app(self, launch_cmd):
adb_cmd = [adb.ADB]
diff --git a/tests/mobly/controllers/android_device_lib/snippet_client_test.py b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
index d60ee46..fa5b9fb 100755
--- a/tests/mobly/controllers/android_device_lib/snippet_client_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
@@ -28,6 +28,7 @@
MOCK_PACKAGE_NAME = 'some.package.name'
MOCK_MISSING_PACKAGE_NAME = 'not.installed'
JSONRPC_BASE_CLASS = 'mobly.controllers.android_device_lib.jsonrpc_client_base.JsonRpcClientBase'
+MOCK_USER_ID = 0
def get_print_function_name():
@@ -70,8 +71,9 @@
def test_check_app_installed_fail_target_not_installed(self):
sc = self._make_client(
mock_android_device.MockAdbProxy(instrumented_packages=[(
- MOCK_PACKAGE_NAME, snippet_client.
- _INSTRUMENTATION_RUNNER_PACKAGE, MOCK_MISSING_PACKAGE_NAME)]))
+ MOCK_PACKAGE_NAME,
+ snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+ MOCK_MISSING_PACKAGE_NAME)]))
expected_msg = ('.* Instrumentation target %s is not installed.' %
MOCK_MISSING_PACKAGE_NAME)
with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
@@ -314,8 +316,8 @@
client = self._make_client()
client._adb.shell = mock.Mock(return_value=b'setsid')
client.start_app_and_connect()
- cmd_setsid = '%s am instrument -w -e action start %s/%s' % (
- snippet_client._SETSID_COMMAND, MOCK_PACKAGE_NAME,
+ cmd_setsid = '%s am instrument --user %s -w -e action start %s/%s' % (
+ snippet_client._SETSID_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])
@@ -323,8 +325,8 @@
client = self._make_client()
client._adb.shell = _mocked_shell
client.start_app_and_connect()
- cmd_nohup = '%s am instrument -w -e action start %s/%s' % (
- snippet_client._NOHUP_COMMAND, MOCK_PACKAGE_NAME,
+ cmd_nohup = '%s am instrument --user %s -w -e action start %s/%s' % (
+ snippet_client._NOHUP_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
mock_do_start_app.assert_has_calls(
[mock.call(cmd_setsid),
@@ -335,8 +337,9 @@
side_effect=adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code'))
client = self._make_client()
client.start_app_and_connect()
- cmd_not_persist = ' am instrument -w -e action start %s/%s' % (
- MOCK_PACKAGE_NAME, snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+ cmd_not_persist = ' am instrument --user %s -w -e action start %s/%s' % (
+ MOCK_USER_ID, MOCK_PACKAGE_NAME,
+ snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
mock_do_start_app.assert_has_calls([
mock.call(cmd_setsid),
mock.call(cmd_nohup),
@@ -447,11 +450,13 @@
def _make_client(self, adb_proxy=None):
adb_proxy = adb_proxy or mock_android_device.MockAdbProxy(
- instrumented_packages=[(MOCK_PACKAGE_NAME, snippet_client.
- _INSTRUMENTATION_RUNNER_PACKAGE,
- MOCK_PACKAGE_NAME)])
+ instrumented_packages=[(
+ MOCK_PACKAGE_NAME,
+ snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
+ MOCK_PACKAGE_NAME)])
ad = mock.Mock()
ad.adb = adb_proxy
+ ad.adb.current_user_id = MOCK_USER_ID
ad.build_info = {
'build_version_codename':
ad.adb.getprop('ro.build.version.codename'),