merge in oc-release history after reset to master
diff --git a/build/scripts/slave/recipes/adt/adb.py b/build/scripts/slave/recipes/adt/adb.py
index 807cb87..17c2831 100644
--- a/build/scripts/slave/recipes/adt/adb.py
+++ b/build/scripts/slave/recipes/adt/adb.py
@@ -60,6 +60,8 @@
                        '--dst', '%s%s/' % (logs_dir, buildername),
                        '--build-dir', build_dir,
                        '--skiplog']
+    if api.platform.is_win:
+      upload_log_args.append('--iswindows')
     api.python("Zip and Upload Logs", log_util_path, upload_log_args)
 
 def GenTests(api):
diff --git a/emu_test/test_avd/launch_avd.py b/emu_test/test_avd/launch_avd.py
new file mode 100644
index 0000000..75aa79c
--- /dev/null
+++ b/emu_test/test_avd/launch_avd.py
@@ -0,0 +1,160 @@
+"""AVD Launch test.
+
+Verify the emulator launched in AVD can be detected.
+
+usage: launch_avd.py [-h] [-t TIMEOUT_IN_SECONDS] --avd AVD
+                     [--exec EMULATOR_EXEC]
+"""
+
+import argparse
+import logging
+import multiprocessing.pool
+import subprocess
+from subprocess import PIPE, STDOUT
+import sys
+import time
+import threading
+import unittest
+
+import util
+
+log = logging.getLogger('launch_avd')
+
+def arg_parser():
+    """Return argument parser for launch_avd test"""
+    parser = argparse.ArgumentParser(description='Argument parser for emu test')
+
+    parser.add_argument('-t', '--timeout', type=int, dest='timeout_in_seconds', action='store',
+                        default=600,
+                        help='an integer for timeout in seconds, default is 600')
+    parser.add_argument('--avd', type=str, dest='avd', action='store',
+                        required=True,
+                        help='run test for given AVD')
+    parser.add_argument('--exec', type=str, dest='emulator_exec', action='store',
+                        default='emulator',
+                        help='path of emulator executable, default is system emulator')
+    parser.add_argument('unittest_args', nargs='*')
+    return parser
+
+class TimeoutError(Exception):
+    """Exception raised for timeout
+
+    Attributes:
+        cmd -- cmd which timed out
+        timeout  -- value of timeout
+    """
+
+    def __init__(self, cmd, timeout):
+        self.cmd = cmd
+        self.timeout = timeout
+
+def run_with_timeout(cmd, timeout):
+    """Run command with specified timeout.
+
+    Args:
+      cmd     - Required  : command to run
+      timeout - Required  : timeout (in seconds)
+
+    Returns:
+      Tuple of form (returncode, output, err), where:
+      * returncode is the exit code of the command
+      * output is the stdout output of the command, collected into a string
+      * err is the stderr output of the command, collected into a string
+    """
+    vars = {'output': "",
+            'err': "",
+            'process': None}
+
+    def run_cmd():
+        vars['process'] = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
+        (vars['output'], vars['err']) = vars['process'].communicate()
+
+    thread = threading.Thread(target=run_cmd)
+    thread.start()
+
+    thread.join(timeout)
+    if thread.is_alive():
+        log.debug('cmd %s timeout, force terminate' % ' '.join(cmd))
+        try:
+            vars['process'].terminate()
+        except Exception as e:
+            log.error('exception terminating adb getprop process: %r' % e)
+    thread.join(timeout)
+    return vars['process'].returncode, vars['output'], vars['err']
+
+
+def launch_emu(avd, emu_args):
+    """Launch given avd and return immediately"""
+    log.debug('call Launching AVD, ...: %s' % str(avd))
+    exec_path = emu_args.emulator_exec
+    launch_cmd = [exec_path, "-avd", str(avd), "-verbose", "-show-kernel"]
+
+    if "emu-master-dev" in exec_path:
+        launch_cmd += ["-skip-adb-auth"]
+
+    log.info('Launching AVD, cmd: %s' % ' '.join(launch_cmd))
+    start_proc = subprocess.Popen(launch_cmd, stdout=PIPE, stderr=STDOUT)
+    log.info('done Launching AVD, cmd: %s' % ' '.join(launch_cmd))
+
+    if start_proc.poll():
+        raise LaunchError(str(avd))
+    log.debug('return Launching AVD, ...: %s' % str(avd))
+    return start_proc
+
+
+def launch_emu_and_wait(avd, emu_args):
+    """Launch given avd and wait for boot completion, return boot time"""
+    run_with_timeout(["adb", "kill-server"], 20)
+    run_with_timeout(["adb", "start-server"], 20)
+    pool = multiprocessing.pool.ThreadPool(processes = 1)
+    launcher_emu = pool.apply_async(launch_emu, [avd, emu_args])
+    start_time = time.time()
+    completed = "0"
+    real_time_out = emu_args.timeout_in_seconds;
+    if 'swiftshader' in str(avd):
+        real_time_out = real_time_out + emu_args.timeout_in_seconds
+    if 'arm' in str(avd):
+        real_time_out = real_time_out + emu_args.timeout_in_seconds;
+    if 'mips' in str(avd):
+        real_time_out = real_time_out + emu_args.timeout_in_seconds;
+    while time.time()-start_time < real_time_out:
+        cmd = ["adb", "shell", "getprop", "sys.boot_completed"]
+        try:
+            (exit_code, output, err) = run_with_timeout(cmd, 10)
+        except Exception as e:
+            log.error('exception run_with_timeout adb getprop: %r' % e)
+            continue
+        if exit_code is 0:
+            completed = output.strip()
+        if completed is "1":
+            log.info('AVD %s is fully booted' % avd)
+            break
+        time.sleep(1)
+    if completed is not "1":
+        log.debug('command output - %s %s' % (output,err))
+        log.error('AVD %s didn\'t boot up within %s seconds' % (avd,real_time_out))
+        raise TimeoutError(avd, real_time_out)
+    boot_time = time.time() - start_time
+    log.debug('AVD %s, boot time is %s' % (avd, boot_time))
+    emu_proc = launcher_emu.get(10)
+    if util.get_connected_devices():
+        success = True
+    else:
+        success = False
+    emu_proc.terminate()
+    return success
+
+
+class LaunchAVDTest(unittest.TestCase):
+    def test_launch_avd(self):
+        args = arg_parser().parse_args()
+        avd = args.avd
+        return launch_emu_and_wait(avd, args)
+
+if __name__ == '__main__':
+    console_handler = logging.StreamHandler(sys.stdout)
+    console_handler.setLevel(logging.DEBUG)
+    log.addHandler(console_handler)
+    log.setLevel(logging.DEBUG)
+    suite = unittest.TestLoader().loadTestsFromTestCase(LaunchAVDTest)
+    unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/emu_test/utils/zip_upload_logs.py b/emu_test/utils/zip_upload_logs.py
index a807e43..608c37e 100644
--- a/emu_test/utils/zip_upload_logs.py
+++ b/emu_test/utils/zip_upload_logs.py
@@ -46,6 +46,7 @@
 
     # if it is adb stress test log, zip and upload to GCS
     if 'adb_stress_logs' in args.log_dir:
+      print 'Running command in directory: %s' % (os.getcwd())
       verbose_call(['zip', '-r', args.zip_name, args.log_dir])
       adb_stress_gs_dst = 'gs://adb_test_traces/%s/' % builderName
       verbose_call(['python', gsutil_path, 'cp', args.zip_name, adb_stress_gs_dst])