aboutsummaryrefslogtreecommitdiff
path: root/emrun
diff options
context:
space:
mode:
Diffstat (limited to 'emrun')
-rwxr-xr-x[-rw-r--r--]emrun437
1 files changed, 301 insertions, 136 deletions
diff --git a/emrun b/emrun
index 9c096db3..d5975b8a 100644..100755
--- a/emrun
+++ b/emrun
@@ -8,6 +8,7 @@ import os, platform, optparse, logging, re, pprint, atexit, urlparse, subprocess
from operator import itemgetter
from urllib import unquote
from Queue import PriorityQueue
+from threading import Thread, RLock
# Populated from cmdline params
emrun_options = None
@@ -41,6 +42,9 @@ processname_killed_atexit = ""
# If user does not specify a --port parameter, this port is used to launch the server.
default_webserver_port = 6931
+# Location of Android Debug Bridge executable
+ADB = ''
+
# Host OS detection to autolocate browsers and other OS-specific support needs.
WINDOWS = False
LINUX = False
@@ -73,7 +77,7 @@ last_message_time = time.clock()
page_start_time = time.clock()
# Stores the time of most recent http page serve.
-page_last_served_time = time.clock()
+page_last_served_time = None
# Returns given log message formatted to be outputted on a HTML page.
def format_html(msg):
@@ -82,21 +86,14 @@ def format_html(msg):
msg = cgi.escape(msg)
msg = msg.replace('\r\n', '<br />').replace('\n', '<br />')
return msg
-
+
+# HTTP requests are handled from separate threads - synchronize them to avoid race conditions
+http_mutex = RLock()
+
# Prints a log message to 'info' stdout channel. Always printed.
def logi(msg):
global last_message_time
- if emrun_options.log_html:
- sys.stdout.write(format_html(msg))
- else:
- print >> sys.stdout, msg
- sys.stdout.flush()
- last_message_time = time.clock()
-
-# Prints a verbose log message to stdout channel. Only shown if run with --verbose.
-def logv(msg):
- global emrun_options, last_message_time
- if emrun_options.verbose:
+ with http_mutex:
if emrun_options.log_html:
sys.stdout.write(format_html(msg))
else:
@@ -104,15 +101,28 @@ def logv(msg):
sys.stdout.flush()
last_message_time = time.clock()
+# Prints a verbose log message to stdout channel. Only shown if run with --verbose.
+def logv(msg):
+ global emrun_options, last_message_time
+ with http_mutex:
+ if emrun_options.verbose:
+ if emrun_options.log_html:
+ sys.stdout.write(format_html(msg))
+ else:
+ print >> sys.stdout, msg
+ sys.stdout.flush()
+ last_message_time = time.clock()
+
# Prints an error message to stderr channel.
def loge(msg):
global last_message_time
- if emrun_options.log_html:
- sys.stderr.write(format_html(msg))
- else:
- print >> sys.stderr, msg
- sys.stderr.flush()
- last_message_time = time.clock()
+ with http_mutex:
+ if emrun_options.log_html:
+ sys.stderr.write(format_html(msg))
+ else:
+ print >> sys.stderr, msg
+ sys.stderr.flush()
+ last_message_time = time.clock()
def format_eol(msg):
if WINDOWS:
@@ -122,8 +132,6 @@ def format_eol(msg):
# Prints a message to the browser stdout output stream.
def browser_logi(msg):
global browser_stdout_handle
- if browser_stdout_handle != sys.stdout and not msg.endswith('\n'):
- msg += '\n'
msg = format_eol(msg)
print >> browser_stdout_handle, msg
browser_stdout_handle.flush()
@@ -132,8 +140,6 @@ def browser_logi(msg):
# Prints a message to the browser stderr output stream.
def browser_loge(msg):
global browser_stderr_handle
- if browser_stderr_handle != sys.stderr and not msg.endswith('\n'):
- msg += '\n'
msg = format_eol(msg)
print >> browser_stderr_handle, msg
browser_stderr_handle.flush()
@@ -153,7 +159,7 @@ def is_browser_process_alive():
# Kills browser_process and processname_killed_atexit.
def kill_browser_process():
- global browser_process, processname_killed_atexit
+ global browser_process, processname_killed_atexit, emrun_options, ADB
if browser_process:
try:
logv('Terminating browser process..')
@@ -161,21 +167,25 @@ def kill_browser_process():
except:
pass
browser_process = None
-
if len(processname_killed_atexit) > 0:
- logv("Terminating all processes that have string '" + processname_killed_atexit + "' in their name.")
- if WINDOWS:
- process_image = processname_killed_atexit if '.exe' in processname_killed_atexit else (processname_killed_atexit + '.exe')
- process = subprocess.Popen(['taskkill', '/F', '/IM', process_image, '/T'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- process.communicate()
+ if emrun_options.android:
+ logv("Terminating Android app '" + processname_killed_atexit + "'.")
+ subprocess.call([ADB, 'shell', 'am', 'force-stop', processname_killed_atexit])
else:
- try:
- subprocess.call(['pkill', processname_killed_atexit])
- except OSError, e:
+ logv("Terminating all processes that have string '" + processname_killed_atexit + "' in their name.")
+ if WINDOWS:
+ process_image = processname_killed_atexit if '.exe' in processname_killed_atexit else (processname_killed_atexit + '.exe')
+ process = subprocess.Popen(['taskkill', '/F', '/IM', process_image, '/T'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ process.communicate()
+ else:
try:
- subprocess.call(['killall', processname_killed_atexit])
+ subprocess.call(['pkill', processname_killed_atexit])
except OSError, e:
- loge('Both commands pkill and killall failed to clean up the spawned browser process. Perhaps neither of these utilities is available on your system?')
+ try:
+ subprocess.call(['killall', processname_killed_atexit])
+ except OSError, e:
+ loge('Both commands pkill and killall failed to clean up the spawned browser process. Perhaps neither of these utilities is available on your system?')
+ # Clear the process name to represent that the browser is now dead.
processname_killed_atexit = ''
# Our custom HTTP web server that will server the target page to run via .html.
@@ -190,56 +200,60 @@ class HTTPWebServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
def handle_incoming_message(self, seq_num, log, data):
global have_received_messages
- have_received_messages = True
-
- if self.expected_http_seq_num == -1:
- self.expected_http_seq_num = seq_num+1
- log(data)
- elif seq_num == -1: # Message arrived without a sequence number? Just log immediately
- log(data)
- elif seq_num == self.expected_http_seq_num:
- log(data)
- self.expected_http_seq_num += 1
- self.print_messages_due()
- elif seq_num < self.expected_http_seq_num:
- log(data)
- else:
- log(data)
- self.http_message_queue += [(seq_num, data, log)]
- self.http_message_queue.sort(key=itemgetter(0))
- if len(self.http_message_queue) > 16:
- self.print_next_message()
+ with http_mutex:
+ have_received_messages = True
+
+ if self.expected_http_seq_num == -1:
+ self.expected_http_seq_num = seq_num+1
+ log(data)
+ elif seq_num == -1: # Message arrived without a sequence number? Just log immediately
+ log(data)
+ elif seq_num == self.expected_http_seq_num:
+ log(data)
+ self.expected_http_seq_num += 1
+ self.print_messages_due()
+ elif seq_num < self.expected_http_seq_num:
+ log(data)
+ else:
+ self.http_message_queue += [(seq_num, data, log)]
+ self.http_message_queue.sort(key=itemgetter(0))
+ if len(self.http_message_queue) > 16:
+ self.print_next_message()
# If it's been too long since we we got a message, prints out the oldest queued message, ignoring the proper order.
# This ensures that if any messages are actually lost, that the message queue will be orderly flushed.
def print_timed_out_messages(self):
global last_message_time
- now = time.clock()
- max_message_queue_time = 5
- if len(self.http_message_queue) > 0 and now - last_message_time > max_message_queue_time:
- self.print_next_message()
+ with http_mutex:
+ now = time.clock()
+ max_message_queue_time = 5
+ if len(self.http_message_queue) > 0 and now - last_message_time > max_message_queue_time:
+ self.print_next_message()
# Skips to printing the next message in queue now, independent of whether there was missed messages in the sequence numbering.
def print_next_message(self):
- if len(self.http_message_queue) > 0:
- self.expected_http_seq_num = self.http_message_queue[0][0]
- self.print_messages_due()
+ with http_mutex:
+ if len(self.http_message_queue) > 0:
+ self.expected_http_seq_num = self.http_message_queue[0][0]
+ self.print_messages_due()
# Completely flushes all out-of-order messages in the queue.
def print_all_messages(self):
- while len(self.http_message_queue) > 0:
- self.print_next_message()
+ with http_mutex:
+ while len(self.http_message_queue) > 0:
+ self.print_next_message()
# Prints any messages that are now due after we logged some other previous messages.
def print_messages_due(self):
- while len(self.http_message_queue) > 0:
- msg = self.http_message_queue[0]
- if msg[0] == self.expected_http_seq_num:
- msg[2](msg[1])
- self.expected_http_seq_num += 1
- self.http_message_queue.pop(0)
- else:
- return
+ with http_mutex:
+ while len(self.http_message_queue) > 0:
+ msg = self.http_message_queue[0]
+ if msg[0] == self.expected_http_seq_num:
+ msg[2](msg[1])
+ self.expected_http_seq_num += 1
+ self.http_message_queue.pop(0)
+ else:
+ return
def serve_forever(self, timeout=0.5):
global emrun_options, last_message_time, page_exit_code, have_received_messages, emrun_not_enabled_nag_printed
@@ -278,10 +292,11 @@ class HTTPWebServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
page_exit_code = emrun_options.timeout_returncode
# If we detect that the page is not running with emrun enabled, print a warning message.
- time_since_page_serve = now - page_last_served_time
- if not emrun_not_enabled_nag_printed and not have_received_messages and time_since_page_serve > 5:
- logi('The html page you are running is not emrun-capable. Stdout, stderr and exit(returncode) capture will not work. Recompile the application with the --emrun linker flag to enable this, or pass --no_emrun_detect to emrun to hide this check.')
- emrun_not_enabled_nag_printed = True
+ if not emrun_not_enabled_nag_printed and page_last_served_time is not None:
+ time_since_page_serve = now - page_last_served_time
+ if not have_received_messages and time_since_page_serve > 10:
+ logi('The html page you are running is not emrun-capable. Stdout, stderr and exit(returncode) capture will not work. Recompile the application with the --emrun linker flag to enable this, or pass --no_emrun_detect to emrun to hide this check.')
+ emrun_not_enabled_nag_printed = True
# Clean up at quit, print any leftover messages in queue.
self.print_all_messages()
@@ -411,6 +426,19 @@ def get_cpu_infoline():
return platform.machine() + ', ' + cpu_name
+def get_android_cpu_infoline():
+ lines = subprocess.check_output([ADB, 'shell', 'cat', '/proc/cpuinfo']).split('\n')
+ processor = ''
+ hardware = ''
+ for line in lines:
+ if line.startswith('Processor'):
+ processor = line[line.find(':')+1:].strip()
+ elif line.startswith('Hardware'):
+ hardware = line[line.find(':')+1:].strip()
+
+ freq = int(subprocess.check_output([ADB, 'shell', 'cat', '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq']).strip())/1000
+ return 'CPU: ' + processor + ', ' + hardware + ' @ ' + str(freq) + ' MHz'
+
def win_print_gpu_info():
gpus = []
gpu_memory = []
@@ -575,19 +603,24 @@ def get_os_version():
return 'Unknown OS'
def get_system_memory():
+ global emrun_options
+
try:
- if WINDOWS:
- return win32api.GlobalMemoryStatusEx()['TotalPhys']
- elif OSX:
- return int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']).strip())
- elif LINUX:
- mem = open('/proc/meminfo', 'r')
- lines = mem.readlines()
- mem.close()
+ if LINUX or emrun_options.android:
+ if emrun_options.android:
+ lines = subprocess.check_output([ADB, 'shell', 'cat', '/proc/meminfo']).split('\n')
+ else:
+ mem = open('/proc/meminfo', 'r')
+ lines = mem.readlines()
+ mem.close()
for i in lines:
sline = i.split()
if str(sline[0]) == 'MemTotal:':
return int(sline[1]) * 1024
+ elif WINDOWS:
+ return win32api.GlobalMemoryStatusEx()['TotalPhys']
+ elif OSX:
+ return int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']).strip())
except:
return -1
@@ -698,6 +731,75 @@ def find_browser(name):
return None # Could not find the browser
+def get_android_model():
+ global ADB
+ manufacturer = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.manufacturer']).strip()
+ brand = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.brand']).strip()
+ model = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.model']).strip()
+ board = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.board']).strip()
+ device = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.device']).strip()
+ name = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.product.name']).strip()
+ return manufacturer + ' ' + brand + ' ' + model + ' ' + board + ' ' + device + ' ' + name
+
+def get_android_os_version():
+ global ADB
+ ver = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.build.version.release']).strip()
+ apiLevel = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.build.version.sdk']).strip()
+ if not apiLevel:
+ apiLevel = subprocess.check_output([ADB, 'shell', 'getprop', 'ro.build.version.sdk_int']).strip()
+
+ os = ''
+ if ver:
+ os += 'Android ' + ver + ' '
+ if apiLevel:
+ os += 'SDK API Level ' + apiLevel + ' '
+ os += subprocess.check_output([ADB, 'shell', 'getprop', 'ro.build.description']).strip()
+ return os
+
+def list_android_browsers():
+ global ADB
+ apps = subprocess.check_output([ADB, 'shell', 'pm', 'list', 'packages', '-f']).replace('\r\n', '\n')
+ browsers = []
+ for line in apps.split('\n'):
+ line = line.strip()
+ if line.endswith('=org.mozilla.firefox'):
+ browsers += ['firefox']
+ if line.endswith('=org.mozilla.firefox_beta'):
+ browsers += ['firefox_beta']
+ if line.endswith('=org.mozilla.fennec_aurora'):
+ browsers += ['firefox_aurora']
+ if line.endswith('=org.mozilla.fennec'):
+ browsers += ['firefox_nightly']
+ if line.endswith('=com.android.chrome'):
+ browsers += ['chrome']
+ if line.endswith('=com.chrome.beta'):
+ browsers += ['chrome_beta']
+ if line.endswith('=com.opera.browser'):
+ browsers += ['opera']
+ if line.endswith('=com.opera.mini.android'):
+ browsers += ['opera_mini']
+ if line.endswith('=mobi.mgeek.TunnyBrowser'):
+ browsers += ['dolphin']
+
+ browsers.sort()
+ logi('emrun has automatically found the following browsers on the connected Android device:')
+ for browser in browsers:
+ logi(' - ' + browser)
+
+def list_pc_browsers():
+ browsers = ['firefox', 'firefox_beta', 'firefox_aurora', 'firefox_nightly', 'chrome', 'chrome_canary', 'iexplore', 'safari', 'opera']
+ logi('emrun has automatically found the following browsers in the default install locations on the system:')
+ logi('')
+ for browser in browsers:
+ browser_exe = find_browser(browser)
+ if type(browser_exe) == list:
+ browser_exe = browser_exe[0]
+ if browser_exe:
+ logi(' - ' + browser + ': ' + browser_display_name(browser_exe) + ' ' + get_executable_version(browser_exe))
+ logi('')
+ logi('You can pass the --browser <id> option to launch with the given browser above.')
+ logi('Even if your browser was not detected, you can use --browser /path/to/browser/executable to launch with that browser.')
+
def browser_display_name(browser):
b = browser.lower()
if 'iexplore' in b:
@@ -718,7 +820,7 @@ def browser_display_name(browser):
return browser
def main():
- global browser_process, processname_killed_atexit, emrun_options, emrun_not_enabled_nag_printed
+ global browser_process, processname_killed_atexit, emrun_options, emrun_not_enabled_nag_printed, ADB
usage_str = "usage: %prog [options] [optional_portnum]"
parser = optparse.OptionParser(usage=usage_str)
@@ -773,6 +875,9 @@ def main():
parser.add_option('--browser', dest='browser', default='',
help='Specifies the browser executable to run the web page in.')
+ parser.add_option('--android', dest='android', action='store_true', default=False,
+ help='Launches the page in a browser of an Android device connected to an USB on the local system. (via adb)')
+
parser.add_option('--system_info', dest='system_info', action='store_true',
help='Prints information about the current system at startup.')
@@ -785,7 +890,13 @@ def main():
(options, args) = parser.parse_args(sys.argv)
emrun_options = options
- if not options.browser:
+ if options.android:
+ ADB = which('adb')
+ if not ADB:
+ loge("Could not find the adb tool. Install Android SDK and add the directory of adb to PATH.")
+ return 1
+
+ if not options.browser and not options.android:
if WINDOWS:
options.browser = 'start'
elif LINUX:
@@ -795,19 +906,11 @@ def main():
elif OSX:
options.browser = 'safari'
- browsers = ['firefox', 'firefox_beta', 'firefox_aurora', 'firefox_nightly', 'chrome', 'chrome_canary', 'iexplore', 'safari', 'opera']
if options.list_browsers:
- logi('emrun has automatically found the following browsers in the default install locations on the system:')
- logi('')
- for browser in browsers:
- browser_exe = find_browser(browser)
- if type(browser_exe) == list:
- browser_exe = browser_exe[0]
- if browser_exe:
- logi(' - ' + browser + ': ' + browser_display_name(browser_exe) + ' ' + get_executable_version(browser_exe))
- logi('')
- logi('You can pass the --browser <id> option to launch with the given browser above.')
- logi('Even if your browser was not detected, you can use --browser /path/to/browser/executable to launch with that browser.')
+ if options.android:
+ list_android_browsers()
+ else:
+ list_pc_browsers()
return
if len(args) < 2 and (options.system_info or options.browser_info):
@@ -827,58 +930,109 @@ def main():
url = os.path.relpath(os.path.abspath(file_to_serve), serve_dir)
if len(cmdlineparams) > 0:
url += '?' + '&'.join(cmdlineparams)
- url = 'http://localhost:'+str(options.port)+'/'+url
+ server_root = 'localhost'
+ if options.android:
+ server_root = socket.gethostbyname(socket.gethostname())
+ url = 'http://' + server_root + ':' + str(options.port)+'/'+url
os.chdir(serve_dir)
logv('Web server root directory: ' + os.path.abspath('.'))
- browser = find_browser(str(options.browser))
- browser_exe = browser[0]
- browser_args = []
-
- if 'safari' in browser_exe.lower():
- # Safari has a bug that a command line 'Safari http://page.com' does not launch that page,
- # but instead launches 'file:///http://page.com'. To remedy this, must use the open -a command
- # to run Safari, but unfortunately this will end up spawning Safari process detached from emrun.
- if OSX:
- browser = ['open', '-a', 'Safari'] + (browser[1:] if len(browser) > 1 else [])
-
- processname_killed_atexit = 'Safari'
- elif 'chrome' in browser_exe.lower():
- processname_killed_atexit = 'chrome'
- browser_args = ['--incognito', '--enable-nacl', '--enable-pnacl', '--disable-restore-session-state', '--enable-webgl', '--no-default-browser-check', '--no-first-run', '--allow-file-access-from-files']
-# if options.no_server:
-# browser_args += ['--disable-web-security']
- elif 'firefox' in browser_exe.lower():
- processname_killed_atexit = 'firefox'
- elif 'iexplore' in browser_exe.lower():
- processname_killed_atexit = 'iexplore'
- browser_args = ['-private']
- elif 'opera' in browser_exe.lower():
- processname_killed_atexit = 'opera'
-
- # In Windows cmdline, & character delimits multiple commmands, so must use ^ to escape them.
- if browser_exe == 'cmd':
- url = url.replace('&', '^&')
- browser += browser_args + [url]
+ if options.android:
+ if not options.no_browser:
+ if not options.browser:
+ loge("Running on Android requires that you explicitly specify the browser to run with --browser <id>. Run emrun --android --list_browsers to obtain a list of installed browsers you can use.")
+ return 1
+ elif options.browser == 'firefox':
+ browser_app = 'org.mozilla.firefox/.App'
+ elif options.browser == 'firefox_beta':
+ browser_app = 'org.mozilla.firefox_beta/.App'
+ elif options.browser == 'firefox_aurora' or options.browser == 'fennec_aurora':
+ browser_app = 'org.mozilla.fennec_aurora/.App'
+ elif options.browser == 'firefox_nightly' or options.browser == 'fennec':
+ browser_app = 'org.mozilla.fennec/.App'
+ elif options.browser == 'chrome':
+ browser_app = 'com.android.chrome/.Main'
+ elif options.browser == 'chrome_beta' or options.browser == 'chrome_canary': # There is no Chrome Canary for Android, but Play store has 'Chrome Beta' instead.
+ browser_app = 'com.chrome.beta/com.android.chrome.Main'
+ elif options.browser == 'opera':
+ browser_app = 'com.opera.browser/com.opera.Opera'
+ elif options.browser == 'opera_mini': # Launching the URL works, but page seems to never load (Fails with 'Network problem' even when other browsers work)
+ browser_app = 'com.opera.mini.android/.Browser'
+ elif options.browser =='dolphin': # Current stable Dolphin as of 12/2013 does not have WebGL support.
+ browser_app = 'mobi.mgeek.TunnyBrowser/.BrowserActivity'
+ else:
+ loge("Don't know how to launch browser " + options.browser + ' on Android!')
+ return 1
+ # To add support for a new Android browser in the list above:
+ # 1. Install the browser to Android phone, connect it via adb to PC.
+ # 2. Type 'adb shell pm list packages -f' to locate the package name of that application.
+ # 3. Type 'adb pull <packagename>.apk' to copy the apk of that application to PC.
+ # 4. Type 'aapt d xmltree <packagename>.apk AndroidManifest.xml > manifest.txt' to extract the manifest from the package.
+ # 5. Locate the name of the main activity for the browser in manifest.txt and add an entry to above list in form 'appname/mainactivityname'
+
+ if WINDOWS:
+ url = url.replace('&', '\\&')
+ browser = [ADB, 'shell', 'am', 'start', '-a', 'android.intent.action.VIEW', '-n', browser_app, '-d', url]
+ processname_killed_atexit = browser_app[:browser_app.find('/')]
+ else: #Launching a web page on local system.
+ browser = find_browser(str(options.browser))
+ browser_exe = browser[0]
+ browser_args = []
+
+ if 'safari' in browser_exe.lower():
+ # Safari has a bug that a command line 'Safari http://page.com' does not launch that page,
+ # but instead launches 'file:///http://page.com'. To remedy this, must use the open -a command
+ # to run Safari, but unfortunately this will end up spawning Safari process detached from emrun.
+ if OSX:
+ browser = ['open', '-a', 'Safari'] + (browser[1:] if len(browser) > 1 else [])
+
+ processname_killed_atexit = 'Safari'
+ elif 'chrome' in browser_exe.lower():
+ processname_killed_atexit = 'chrome'
+ browser_args = ['--incognito', '--enable-nacl', '--enable-pnacl', '--disable-restore-session-state', '--enable-webgl', '--no-default-browser-check', '--no-first-run', '--allow-file-access-from-files']
+ # if options.no_server:
+ # browser_args += ['--disable-web-security']
+ elif 'firefox' in browser_exe.lower():
+ processname_killed_atexit = 'firefox'
+ elif 'iexplore' in browser_exe.lower():
+ processname_killed_atexit = 'iexplore'
+ browser_args = ['-private']
+ elif 'opera' in browser_exe.lower():
+ processname_killed_atexit = 'opera'
+
+ # In Windows cmdline, & character delimits multiple commmands, so must use ^ to escape them.
+ if browser_exe == 'cmd':
+ url = url.replace('&', '^&')
+ browser += browser_args + [url]
if options.kill_on_start:
+ pname = processname_killed_atexit
kill_browser_process()
+ processname_killed_atexit = pname
if options.system_info:
logi('Time of run: ' + time.strftime("%x %X"))
- logi('Computer name: ' + socket.gethostname()) # http://stackoverflow.com/questions/799767/getting-name-of-windows-computer-running-python-script
- logi('OS: ' + get_os_version() + ' with ' + str(get_system_memory()/1024/1024) + ' MB of System RAM')
- logi('CPU: ' + get_cpu_infoline())
- print_gpu_infolines()
+ if options.android:
+ logi('Model: ' + get_android_model())
+ logi('OS: ' + get_android_os_version() + ' with ' + str(get_system_memory()/1024/1024) + ' MB of System RAM')
+ logi('CPU: ' + get_android_cpu_infoline())
+ else:
+ logi('Computer name: ' + socket.gethostname()) # http://stackoverflow.com/questions/799767/getting-name-of-windows-computer-running-python-script
+ logi('OS: ' + get_os_version() + ' with ' + str(get_system_memory()/1024/1024) + ' MB of System RAM')
+ logi('CPU: ' + get_cpu_infoline())
+ print_gpu_infolines()
if options.browser_info:
- logi('Browser: ' + browser_display_name(browser[0]) + ' ' + get_executable_version(browser_exe))
+ if options.android:
+ logi('Browser: Android ' + browser_app)
+ else:
+ logi('Browser: ' + browser_display_name(browser[0]) + ' ' + get_executable_version(browser_exe))
# Suppress run warning if requested.
if options.no_emrun_detect:
emrun_not_enabled_nag_printed = True
- global browser_stdout_handle, browser_stderr_handle
+ global browser_stdout_handle, browser_stderr_handle
if options.log_stdout:
browser_stdout_handle = open(options.log_stdout, 'ab')
if options.log_stderr:
@@ -887,6 +1041,10 @@ def main():
else:
browser_stderr_handle = open(options.log_stderr, 'ab')
+ if not options.no_server:
+ logv('Starting web server in port ' + str(options.port))
+ httpd = HTTPWebServer(('', options.port), HTTPHandler)
+
if not options.no_browser:
logv("Executing %s" % ' '.join(browser))
if browser[0] == 'cmd':
@@ -894,10 +1052,15 @@ def main():
browser_process = subprocess.Popen(browser)
if options.kill_on_exit:
atexit.register(kill_browser_process)
+ # For Android automation, we execute adb, so this process does not represent a browser and no point killing it.
+ if options.android:
+ browser_process = None
+ if browser_process and browser_process.poll() == None:
+ options.serve_after_close = True
+ logv('Warning: emrun got detached from the target browser process. Cannot detect when user closes the browser. Behaving as if --serve_after_close was passed in.')
+
if not options.no_server:
- logv('Starting web server in port ' + str(options.port))
- httpd = HTTPWebServer(('', options.port), HTTPHandler)
try:
httpd.serve_forever()
except KeyboardInterrupt:
@@ -915,4 +1078,6 @@ def main():
return page_exit_code
if __name__ == '__main__':
- sys.exit(main())
+ returncode = main()
+ logv('emrun quitting with process exit code ' + str(returncode))
+ sys.exit(returncode)