Merge "Remove use of private API." into jb-mr1-dev
diff --git a/scripts/app_engine_server/redirects.yaml b/scripts/app_engine_server/redirects.yaml
index 0e226ce..23fbeb2 100644
--- a/scripts/app_engine_server/redirects.yaml
+++ b/scripts/app_engine_server/redirects.yaml
@@ -296,6 +296,10 @@
   type: permanent
   comment: Redirect to new location
 
+- src: /guide/practices/accessibility.html
+  dst: /guide/topics/ui/accessibility/index.html
+  type: permanent
+  
 # new one  
 - src: /resources/dashboard/.*
   dst: /about/dashboards/index.html
@@ -310,7 +314,7 @@
 - src: /guide/tutorials/
   dst: /resources/tutorials/
   type: permanent
-  
+
 - src: /resources/tutorials/views/hello-linearlayout.html
   dst: /guide/topics/ui/layout/linear.html
   type: permanent
diff --git a/testrunner/.gitignore b/testrunner/.gitignore
index 0d20b64..b3421b0 100644
--- a/testrunner/.gitignore
+++ b/testrunner/.gitignore
@@ -1 +1,2 @@
 *.pyc
+.*
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index ddc50d5..5191340 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -131,6 +131,17 @@
       logger.Log("ADB Pull Failed: Source file %s does not exist." % src)
       return False
 
+  def Install(self, apk_path):
+    """Installs apk on device.
+
+    Args:
+      apk_path: file path to apk file on host
+
+    Returns:
+      output of install command
+    """
+    return self.SendCommand("install -r %s" % apk_path)
+
   def DoesFileExist(self, src):
     """Checks if the given path exists on device target.
 
diff --git a/testrunner/coverage.py b/testrunner/coverage.py
index 4322e26..1c8ec2f 100755
--- a/testrunner/coverage.py
+++ b/testrunner/coverage.py
@@ -289,25 +289,6 @@
   os.environ["EMMA_INSTRUMENT"] = "true"
 
 
-def TestDeviceCoverageSupport(adb):
-  """Check if device has support for generating code coverage metrics.
-
-  This tries to dump emma help information on device, a response containing
-  help information will indicate that emma is already on system class path.
-
-  Returns:
-    True if device can support code coverage. False otherwise.
-  """
-  try:
-    output = adb.SendShellCommand("exec app_process / emma -h")
-
-    if output.find('emma usage:') == 0:
-      return True
-  except errors.AbortError:
-    pass
-  return False
-
-
 def Run():
   """Does coverage operations based on command line args."""
   # TODO: do we want to support combining coverage for a single target
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 6c1b1b6..9082d79 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -33,6 +33,7 @@
 import glob
 import optparse
 import os
+import re
 from sets import Set
 import sys
 import time
@@ -73,6 +74,13 @@
 
   _DALVIK_VERIFIER_OFF_PROP = "dalvik.vm.dexopt-flags = v=n"
 
+  # regular expression to match install: statements in make output
+  _RE_MAKE_INSTALL = re.compile(r'Install:\s(.+)')
+
+  # regular expression to find remote device path from a file path relative
+  # to build root
+  _RE_MAKE_INSTALL_PATH = re.compile(r'out\/target\/product\/\w+\/(.+)$')
+
   def __init__(self):
     # disable logging of timestamp
     self._root_path = android_build.GetTop()
@@ -243,23 +251,11 @@
       self._adb.EnableAdbRoot()
     else:
       logger.Log("adb root")
-    rebuild_libcore = False
     if target_set:
       if self._options.coverage:
         coverage.EnableCoverageBuild()
-        # hack to remove core library intermediates
-        # hack is needed because:
-        # 1. EMMA_INSTRUMENT changes what source files to include in libcore
-        #    but it does not trigger a rebuild
-        # 2. there's no target (like "clear-intermediates") to remove the files
-        #    decently
-        rebuild_libcore = not coverage.TestDeviceCoverageSupport(self._adb)
-        if rebuild_libcore:
-          cmd = "rm -rf %s" % os.path.join(
-              self._root_path,
-              "out/target/common/obj/JAVA_LIBRARIES/core_intermediates/")
-          logger.Log(cmd)
-          run_command.RunCommand(cmd, return_output=False)
+        target_set.append("external/emma/Android.mk")
+        # TODO: detect if external/emma exists
 
       target_build_string = " ".join(target_set)
       extra_args_string = " ".join(extra_args_set)
@@ -270,17 +266,38 @@
           target_build_string, self._options.make_jobs, self._root_path,
           extra_args_string)
       logger.Log(cmd)
+      if not self._options.preview:
+        output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
+        self._DoInstall(output)
 
-      if self._options.preview:
-        # in preview mode, just display to the user what command would have been
-        # run
-        logger.Log("adb sync")
-      else:
-        # set timeout for build to 10 minutes, since libcore may need to
-        # be rebuilt
-        run_command.RunCommand(cmd, return_output=False, timeout_time=600)
-        logger.Log("Syncing to device...")
-        self._adb.Sync(runtime_restart=rebuild_libcore)
+  def _DoInstall(self, make_output):
+    """Install artifacts from build onto device.
+
+    Looks for 'install:' text from make output to find artifacts to install.
+
+    Args:
+      make_output: stdout from make command
+    """
+    for line in make_output.split("\n"):
+      m = self._RE_MAKE_INSTALL.match(line)
+      if m:
+        install_path = m.group(1)
+        if install_path.endswith(".apk"):
+          abs_install_path = os.path.join(self._root_path, install_path)
+          logger.Log("adb install -r %s" % abs_install_path)
+          logger.Log(self._adb.Install(abs_install_path))
+        else:
+          self._PushInstallFileToDevice(install_path)
+
+  def _PushInstallFileToDevice(self, install_path):
+    m = self._RE_MAKE_INSTALL_PATH.match(install_path)
+    if m:
+      remote_path = m.group(1)
+      abs_install_path = os.path.join(self._root_path, install_path)
+      logger.Log("adb push %s %s", abs_install_path, remote_path)
+      self._adb.Push(abs_install_path, remote_path)
+    else:
+      logger.Log("Error: Failed to recognize path of file to install %s" % install_path)
 
   def _DoFullBuild(self, tests):
     """If necessary, run a full 'make' command for the tests that need it."""
@@ -309,8 +326,9 @@
       if not self._options.preview:
         old_dir = os.getcwd()
         os.chdir(self._root_path)
-        run_command.RunCommand(cmd, return_output=False)
+        output = run_command.RunCommand(cmd, return_output=False)
         os.chdir(old_dir)
+        self._DoInstall(output)
 
   def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
     if not test_suite.IsFullMake():
@@ -369,7 +387,7 @@
     If one or more tests needs dalvik verifier off, and it is not already off,
     turns off verifier and reboots device to allow change to take effect.
     """
-    # hack to check if these are framework/base tests. If so, turn off verifier
+    # hack to check if these are frameworks/base tests. If so, turn off verifier
     # to allow framework tests to access package-private framework api
     framework_test = False
     for test in test_list:
diff --git a/testrunner/test_defs/instrumentation_test.py b/testrunner/test_defs/instrumentation_test.py
index ede7ceb..12633b2 100644
--- a/testrunner/test_defs/instrumentation_test.py
+++ b/testrunner/test_defs/instrumentation_test.py
@@ -33,9 +33,6 @@
 
   DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
 
-  # dependency on libcore (used for Emma)
-  _LIBCORE_BUILD_PATH = "libcore"
-
   def __init__(self):
     test_suite.AbstractTestSuite.__init__(self)
     self._package_name = None
@@ -87,8 +84,6 @@
     return self
 
   def GetBuildDependencies(self, options):
-    if options.coverage:
-      return [self._LIBCORE_BUILD_PATH]
     return []
 
   def Run(self, options, adb):
@@ -145,8 +140,6 @@
       logger.Log(adb_cmd)
     elif options.coverage:
       coverage_gen = coverage.CoverageGenerator(adb)
-      adb.WaitForInstrumentation(self.GetPackageName(),
-                                 self.GetRunnerName())
       # need to parse test output to determine path to coverage file
       logger.Log("Running in coverage mode, suppressing test output")
       try:
@@ -168,8 +161,6 @@
       if coverage_file is not None:
         logger.Log("Coverage report generated at %s" % coverage_file)
     else:
-      adb.WaitForInstrumentation(self.GetPackageName(),
-                                 self.GetRunnerName())
       adb.StartInstrumentationNoResults(
           package_name=self.GetPackageName(),
           runner_name=self.GetRunnerName(),