Make coverage work without test defs.

Change-Id: I946df038e97dc5c2f40a4610d4076e13ab6bde37
diff --git a/testrunner/coverage/coverage_targets.py b/testrunner/coverage/coverage_targets.py
new file mode 100644
index 0000000..a627671
--- /dev/null
+++ b/testrunner/coverage/coverage_targets.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python2.4
+#
+#
+# Copyright 2008, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import xml.dom.minidom
+import xml.parsers
+import os
+
+
+import coverage_target
+import logger
+import errors
+
+class CoverageTargets:
+  """Accessor for the code coverage target xml file
+  Expects the following format:
+  <targets>
+    <target
+      name=""
+      type="JAVA_LIBRARIES|APPS"
+      build_path=""
+
+      [<src path=""/>] (0..*)  - These are relative to build_path. If missing,
+                                 assumes 'src'
+    >/target>
+
+    TODO: add more format checking
+  """
+
+  _TARGET_TAG_NAME = 'coverage_target'
+  _NAME_ATTR = 'name'
+  _TYPE_ATTR = 'type'
+  _BUILD_ATTR = 'build_path'
+  _SRC_TAG = 'src'
+  _PATH_ATTR = 'path'
+
+  def __init__(self, ):
+    self._target_map= {}
+
+  def __iter__(self):
+    return iter(self._target_map.values()
+
+  def Parse(self, file_path):
+    """Parse the coverage target data from from given file path, and add it to
+       the current object
+       Args:
+         file_path: absolute file path to parse
+       Raises:
+         errors.ParseError if file_path cannot be parsed
+    """
+    try:
+      doc = xml.dom.minidom.parse(file_path)
+    except IOError:
+      # Error: The results file does not exist
+      logger.Log('Results file %s does not exist' % file_path)
+      raise errors.ParseError
+    except xml.parsers.expat.ExpatError:
+      logger.Log('Error Parsing xml file: %s ' %  file_path)
+      raise errors.ParseError
+
+    target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME)
+
+    for target_element in target_elements:
+      target = coverage_target.CoverageTarget()
+      self._ParseCoverageTarget(target, target_element)
+      self._AddTarget(target)
+
+  def _AddTarget(self, target):
+    self._target_map[target.GetName()] = target
+
+  def GetBuildTargets(self):
+    """ returns list of target names """
+    build_targets = []
+    for target in self:
+      build_targets.append(target.GetName())
+    return build_targets
+
+  def GetTargets(self):
+    """ returns list of CoverageTarget"""
+    return self._target_map.values()
+
+  def GetTarget(self, name):
+    """ returns CoverageTarget for given name. None if not found """
+    try:
+      return self._target_map[name]
+    except KeyError:
+      return None
+
+  def _ParseCoverageTarget(self, target, target_element):
+    """Parse coverage data from XML.
+
+    Args:
+      target: the Coverage object to populate
+      target_element: the XML element to get data from
+    """
+    target.SetName(target_element.getAttribute(self._NAME_ATTR))
+    target.SetType(target_element.getAttribute(self._TYPE_ATTR))
+    target.SetBuildPath(target_element.getAttribute(self._BUILD_ATTR))
+    self._paths = []
+    self._ParsePaths(target, target_element)
+
+  def _ParsePaths(self, target, target_element):
+    src_elements = target_element.getElementsByTagName(self._SRC_TAG)
+    if len(src_elements) <= 0:
+      # no src tags specified. Assume build_path + src
+      target.AddPath(os.path.join(target.GetBuildPath(), "src"))
+    for src_element in src_elements:
+      rel_path = src_element.getAttribute(self._PATH_ATTR)
+      target.AddPath(os.path.join(target.GetBuildPath(), rel_path))
+
+
+def Parse(xml_file_path):
+  """parses out a file_path class from given path to xml"""
+  targets = CoverageTargets()
+  targets.Parse(xml_file_path)
+  return targets