Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
start_time = time.time()
expiration_time = start_time + _APP_START_WAIT_TIME
started = False
while time.time() < expiration_time:
self.log.debug('Attempting to start %s.', self.app_name)
try:
self.connect()
started = True
break
except:
self.log.debug('%s is not yet running, retrying',
self.app_name,
exc_info=True)
time.sleep(1)
if not started:
raise jsonrpc_client_base.AppRestoreConnectionError(
self._ad, '%s failed to connect for %s at host port %s, '
'device port %s' % (self.app_name, self._adb.serial,
self.host_port, self.device_port))
def _start_event_client(self):
"""Overrides superclass."""
event_client = SnippetClient(package=self.package, ad=self._ad)
event_client.host_port = self.host_port
event_client.device_port = self.device_port
event_client.connect(self.uid,
jsonrpc_client_base.JsonRpcCommand.CONTINUE)
return event_client
def _start_event_client(self):
# Start an EventDispatcher for the current sl4a session
event_client = Sl4aClient(self._ad)
event_client.host_port = self.host_port
event_client.device_port = self.device_port
event_client.connect(uid=self.uid,
cmd=jsonrpc_client_base.JsonRpcCommand.CONTINUE)
ed = event_dispatcher.EventDispatcher(event_client)
ed.start()
return ed
_INSTRUMENTATION_RUNNER_PACKAGE)
# Test that uses UiAutomation requires the shell session to be maintained while
# test is in progress. However, this requirement does not hold for the test that
# deals with device USB disconnection (Once device disconnects, the shell
# session that started the instrument ends, and UiAutomation fails with error:
# "UiAutomation not connected"). To keep the shell session and redirect
# stdin/stdout/stderr, use "setsid" or "nohup" while launching the
# instrumentation test. Because these commands may not be available in every
# android system, try to use them only if exists.
_SETSID_COMMAND = 'setsid'
_NOHUP_COMMAND = 'nohup'
class AppStartPreCheckError(jsonrpc_client_base.Error):
"""Raised when pre checks for the snippet failed."""
class ProtocolVersionError(jsonrpc_client_base.AppStartError):
"""Raised when the protocol reported by the snippet is unknown."""
class SnippetClient(jsonrpc_client_base.JsonRpcClientBase):
"""A client for interacting with snippet APKs using Mobly Snippet Lib.
See superclass documentation for a list of public attributes.
For a description of the launch protocols, see the documentation in
mobly-snippet-lib, SnippetRunner.java.
"""
device port. If not provided, find a new available port as host
port.
Raises:
AppRestoreConnectionError: When the app was not able to be started.
"""
self.host_port = port or utils.get_available_host_port()
self._adb.forward(
['tcp:%d' % self.host_port,
'tcp:%d' % self.device_port])
try:
self.connect()
except:
# Log the original error and raise AppRestoreConnectionError.
self.log.exception('Failed to re-connect to app.')
raise jsonrpc_client_base.AppRestoreConnectionError(
self._ad,
('Failed to restore app connection for %s at host port %s, '
'device port %s') %
(self.package, self.host_port, self.device_port))
# Because the previous connection was lost, update self._proc
self._proc = None
self._restore_event_client()
# instrumentation test. Because these commands may not be available in every
# android system, try to use them only if exists.
_SETSID_COMMAND = 'setsid'
_NOHUP_COMMAND = 'nohup'
class AppStartPreCheckError(jsonrpc_client_base.Error):
"""Raised when pre checks for the snippet failed."""
class ProtocolVersionError(jsonrpc_client_base.AppStartError):
"""Raised when the protocol reported by the snippet is unknown."""
class SnippetClient(jsonrpc_client_base.JsonRpcClientBase):
"""A client for interacting with snippet APKs using Mobly Snippet Lib.
See superclass documentation for a list of public attributes.
For a description of the launch protocols, see the documentation in
mobly-snippet-lib, SnippetRunner.java.
"""
def __init__(self, package, ad):
"""Initializes a SnippetClient.
Args:
package: (str) The package name of the apk where the snippets are
defined.
ad: (AndroidDevice) the device object associated with this client.
"""
_DEVICE_SIDE_PORT = 8080
_LAUNCH_CMD = (
'am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER '
'--ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT %s '
'com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher')
# Maximum time to wait for the app to start on the device (10 minutes).
# TODO: This timeout is set high in order to allow for retries in
# start_app_and_connect. Decrease it when the call to connect() has the option
# for a quicker timeout than the default _cmd() timeout.
# TODO: Evaluate whether the high timeout still makes sense for sl4a. It was
# designed for user snippets which could be very slow to start depending on the
# size of the snippet and main apps. sl4a can probably use a much smaller value.
_APP_START_WAIT_TIME = 2 * 60
class Sl4aClient(jsonrpc_client_base.JsonRpcClientBase):
"""A client for interacting with SL4A using Mobly Snippet Lib.
Extra public attributes:
ed: Event dispatcher instance for this sl4a client.
"""
def __init__(self, ad):
"""Initializes an Sl4aClient.
Args:
ad: AndroidDevice object.
"""
super(Sl4aClient, self).__init__(app_name=_APP_NAME, ad=ad)
self._ad = ad
self.ed = None
self._adb = ad.adb
"""Reads the next line of instrumentation output relevant to snippets.
This method will skip over lines that don't start with 'SNIPPET' or
'INSTRUMENTATION_RESULT'.
Returns:
(str) Next line of snippet-related instrumentation output, stripped.
Raises:
jsonrpc_client_base.AppStartError: If EOF is reached without any
protocol lines being read.
"""
while True:
line = self._proc.stdout.readline().decode('utf-8')
if not line:
raise jsonrpc_client_base.AppStartError(
self._ad, 'Unexpected EOF waiting for app to start')
# readline() uses an empty string to mark EOF, and a single newline
# to mark regular empty lines in the output. Don't move the strip()
# call above the truthiness check, or this method will start
# considering any blank output line to be EOF.
line = line.strip()
if (line.startswith('INSTRUMENTATION_RESULT:')
or line.startswith('SNIPPET ')):
self.log.debug(
'Accepted line from instrumentation output: "%s"', line)
return line
self.log.debug('Discarded line from instrumentation output: "%s"',
line)