Merge "Add flag to grant permissions when running tests." into mnc-dev
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index fdbcb78..cd39480 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -131,16 +131,17 @@
       logger.Log("ADB Pull Failed: Source file %s does not exist." % src)
       return False
 
-  def Install(self, apk_path):
+  def Install(self, apk_path, extra_flags):
     """Installs apk on device.
 
     Args:
       apk_path: file path to apk file on host
+      extra_flags: Additional flags to use with adb install
 
     Returns:
       output of install command
     """
-    return self.SendCommand("install -r %s" % apk_path)
+    return self.SendCommand("install -r %s %s" % (extra_flags, apk_path))
 
   def DoesFileExist(self, src):
     """Checks if the given path exists on device target.
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 761652f..9b011a6 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -153,6 +153,10 @@
     parser.add_option("--coverage-target", dest="coverage_target_path",
                       default=None,
                       help="Path to app to collect code coverage target data for.")
+    parser.add_option("-k", "--skip-permissions", dest="skip_permissions",
+                      default=False, action="store_true",
+                      help="Do not grant runtime permissions during test package"
+                      " installation.")
     parser.add_option("-x", "--path", dest="test_path",
                       help="Run test(s) at given file system path")
     parser.add_option("-t", "--all-tests", dest="all_tests",
@@ -247,19 +251,27 @@
 
   def _DoBuild(self):
     logger.SilentLog("Building tests...")
-
     tests = self._GetTestsToRun()
+
+    # Build and install tests that do not get granted permissions
+    self._DoPermissionAwareBuild(tests, False)
+
+    # Build and install tests that require granted permissions
+    self._DoPermissionAwareBuild(tests, True)
+
+  def _DoPermissionAwareBuild(self, tests, test_requires_permissions):
     # turn off dalvik verifier if necessary
     # TODO: skip turning off verifier for now, since it puts device in bad
     # state b/14088982
     #self._TurnOffVerifier(tests)
-    self._DoFullBuild(tests)
+    self._DoFullBuild(tests, test_requires_permissions)
 
     target_tree = make_tree.MakeTree()
 
     extra_args_set = []
     for test_suite in tests:
-      self._AddBuildTarget(test_suite, target_tree, extra_args_set)
+      if test_suite.IsGrantedPermissions() == test_requires_permissions:
+        self._AddBuildTarget(test_suite, target_tree, extra_args_set)
 
     if not self._options.preview:
       self._adb.EnableAdbRoot()
@@ -301,9 +313,9 @@
           output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
         run_command.SetAbortOnError(False)
         logger.SilentLog(output)
-        self._DoInstall(output)
+        self._DoInstall(output, test_requires_permissions)
 
-  def _DoInstall(self, make_output):
+  def _DoInstall(self, make_output, test_requires_permissions):
     """Install artifacts from build onto device.
 
     Looks for 'install:' text from make output to find artifacts to install.
@@ -323,8 +335,11 @@
         for install_path in re.split(r'\s+', install_paths):
           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))
+            extra_flags = ""
+            if test_requires_permissions and not self._options.skip_permissions:
+              extra_flags = "-g"
+            logger.Log("adb install -r %s %s" % (extra_flags, abs_install_path))
+            logger.Log(self._adb.Install(abs_install_path, extra_flags))
           else:
             self._PushInstallFileToDevice(install_path)
 
@@ -341,12 +356,12 @@
     else:
       logger.Log("Error: Failed to recognize path of file to install %s" % install_path)
 
-  def _DoFullBuild(self, tests):
+  def _DoFullBuild(self, tests, test_requires_permissions):
     """If necessary, run a full 'make' command for the tests that need it."""
     extra_args_set = Set()
 
     for test in tests:
-      if test.IsFullMake():
+      if test.IsFullMake() and test.IsGrantedPermissions() == test_requires_permissions:
         if test.GetExtraBuildArgs():
           # extra args contains the args to pass to 'make'
           extra_args_set.add(test.GetExtraBuildArgs())
@@ -365,7 +380,7 @@
         output = run_command.RunCommand(cmd, return_output=True)
         logger.SilentLog(output)
         os.chdir(old_dir)
-        self._DoInstall(output)
+        self._DoInstall(output, test_requires_permissions)
 
   def _AddBuildTarget(self, test_suite, target_tree, extra_args_set):
     if not test_suite.IsFullMake():
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 4d9ee5f..237cec3 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -506,7 +506,7 @@
     continuous="true"
     coverage_target="Phone" />
 
-<test name="telecomm-unit"
+<test name="telecom-unit"
     build_path="packages/services/Telecomm"
     package="com.android.server.telecom.tests"
     continuous="true"
diff --git a/testrunner/test_defs/test_suite.py b/testrunner/test_defs/test_suite.py
index d0bd9ee..5bd9a19 100644
--- a/testrunner/test_defs/test_suite.py
+++ b/testrunner/test_defs/test_suite.py
@@ -33,6 +33,7 @@
     self._description = ''
     self._extra_build_args = ''
     self._is_full_make = False
+    self._is_granted_permissions = True
 
   def GetName(self):
     return self._name
@@ -65,6 +66,14 @@
     self._is_continuous = continuous
     return self._is_continuous
 
+  def IsGrantedPermissions(self):
+    """Return true if the test should be granted runtime permissions on install."""
+    return self._is_granted_permissions
+
+  def SetIsGrantedPermissions(self, is_granted_permissions):
+    self._is_granted_permissions = is_granted_permissions
+    return self._is_granted_permissions
+
   def GetSuite(self):
     """Returns the name of test' suite, or None."""
     return self._suite
diff --git a/testrunner/test_defs/xml_suite_helper.py b/testrunner/test_defs/xml_suite_helper.py
index 6cf2e6c..6805fcd 100644
--- a/testrunner/test_defs/xml_suite_helper.py
+++ b/testrunner/test_defs/xml_suite_helper.py
@@ -40,6 +40,7 @@
   _DESCRIPTION_ATTR = 'description'
   _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
   _FULL_MAKE_ATTR = 'full_make'
+  _GRANTED_PERMISSIONS_ATTR = 'granted_permissions'
 
   def Parse(self, element):
     """Populates common suite attributes from given suite xml element.
@@ -72,6 +73,9 @@
     test_suite.SetContinuous(self._ParseAttribute(suite_element,
                                                   self._CONTINUOUS_ATTR,
                                                   False, default_value=False))
+    test_suite.SetIsGrantedPermissions(self._ParseAttribute(suite_element,
+                                                  self._GRANTED_PERMISSIONS_ATTR,
+                                                  False, default_value=True))
     test_suite.SetSuite(self._ParseAttribute(suite_element, self._SUITE_ATTR, False,
                                            default_value=None))
     test_suite.SetDescription(self._ParseAttribute(suite_element,
@@ -88,6 +92,8 @@
                       default_value=None):
     if suite_element.hasAttribute(attribute_name):
       value = suite_element.getAttribute(attribute_name)
+      if default_value in (True, False):
+        value = value.lower() == "true"
     elif mandatory:
       error_msg = ('Could not find attribute %s in %s' %
                    (attribute_name, self.TAG_NAME))