Do not add `--user` in snippet commands for SDK < 24. (#653)
diff --git a/mobly/controllers/android_device_lib/snippet_client.py b/mobly/controllers/android_device_lib/snippet_client.py
index 218ef46..735a921 100644
--- a/mobly/controllers/android_device_lib/snippet_client.py
+++ b/mobly/controllers/android_device_lib/snippet_client.py
@@ -40,10 +40,10 @@
_PROTOCOL_MINOR_VERSION = 0
_LAUNCH_CMD = (
- '{shell_cmd} am instrument --user {user} -w -e action start {snippet_package}/'
- + _INSTRUMENTATION_RUNNER_PACKAGE)
+ '{shell_cmd} am instrument {user} -w -e action start {snippet_package}/' +
+ _INSTRUMENTATION_RUNNER_PACKAGE)
-_STOP_CMD = ('am instrument -w -e action stop %s/' +
+_STOP_CMD = ('am instrument {user} -w -e action stop {snippet_package}/' +
_INSTRUMENTATION_RUNNER_PACKAGE)
# Test that uses UiAutomation requires the shell session to be maintained while
@@ -109,6 +109,23 @@
"""
return self._conn is not None
+ def _get_user_command_string(self):
+ """Gets the appropriate command argument for specifying user IDs.
+
+ By default, `SnippetClient` operates within the current user.
+
+ We don't add the `--user {ID}` arg when Android's SDK is below 24,
+ where multi-user support is not well implemented.
+
+ Returns:
+ String, the command param section to be formatted into the adb
+ commands.
+ """
+ sdk_int = int(self._ad.build_info['build_version_sdk'])
+ if sdk_int < 24:
+ return ''
+ return '--user %s' % self._adb.current_user_id
+
def start_app_and_connect(self):
"""Starts snippet apk on the device and connects to it.
@@ -157,7 +174,7 @@
self.package, _PROTOCOL_MAJOR_VERSION,
_PROTOCOL_MINOR_VERSION)
cmd = _LAUNCH_CMD.format(shell_cmd=persists_shell_cmd,
- user=self._adb.current_user_id,
+ user=self._get_user_command_string(),
snippet_package=self.package)
start_time = time.time()
self._proc = self._do_start_app(cmd)
@@ -234,7 +251,10 @@
if self._proc:
utils.stop_standing_subprocess(self._proc)
self._proc = None
- out = self._adb.shell(_STOP_CMD % self.package).decode('utf-8')
+ out = self._adb.shell(
+ _STOP_CMD.format(
+ snippet_package=self.package,
+ user=self._get_user_command_string())).decode('utf-8')
if 'OK (0 tests)' not in out:
raise errors.DeviceError(
self._ad,
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 fa5b9fb..cb62345 100755
--- a/tests/mobly/controllers/android_device_lib/snippet_client_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
@@ -293,6 +293,48 @@
'SnippetClient.connect')
@mock.patch('mobly.controllers.android_device_lib.snippet_client.'
'utils.get_available_host_port')
+ def test_snippet_start_on_sdk_21(self, mock_get_port, mock_connect,
+ mock_read_protocol_line,
+ mock_check_app_installed,
+ mock_do_start_app):
+ """Check that `--user` is not added to start command on SDK < 24."""
+
+ def _mocked_shell(arg):
+ if 'setsid' in arg:
+ raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')
+ else:
+ return b'nohup'
+
+ mock_get_port.return_value = 123
+ mock_read_protocol_line.side_effect = [
+ 'SNIPPET START, PROTOCOL 1 234',
+ 'SNIPPET SERVING, PORT 1234',
+ 'SNIPPET START, PROTOCOL 1 234',
+ 'SNIPPET SERVING, PORT 1234',
+ 'SNIPPET START, PROTOCOL 1 234',
+ 'SNIPPET SERVING, PORT 1234',
+ ]
+
+ # Test 'setsid' exists
+ client = self._make_client()
+ client._ad.build_info['build_version_sdk'] = 21
+ 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,
+ snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
+ mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])
+
+ @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
+ 'SnippetClient._do_start_app')
+ @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
+ 'SnippetClient._check_app_installed')
+ @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
+ 'SnippetClient._read_protocol_line')
+ @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
+ 'SnippetClient.connect')
+ @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
+ 'utils.get_available_host_port')
def test_snippet_start_app_and_connect_persistent_session(
self, mock_get_port, mock_connect, mock_read_protocol_line,
mock_check_app_installed, mock_do_start_app):