Fix CTS compilation tests

mDevice.enableAdbRoot is not actually enabling the root anymore. We have
to manually "su root" all the commands for the test to pass.

Test: cts-tradefed run cts -m CtsCompilationTestCases

Bug: 36651422
Change-Id: Id9cf3cb78c987401e565bac390298349ab240c63
diff --git a/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java b/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java
index 40bf530..ce8f760 100644
--- a/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java
+++ b/hostsidetests/compilation/src/android/cts/compilation/AdbRootDependentCompilationTest.java
@@ -75,8 +75,7 @@
     private byte[] profileBytes;
     private File localProfileFile;
     private File apkFile;
-    private boolean mIsRoot;
-    private boolean mNewlyObtainedRoot;
+    private boolean mCanEnableDeviceRootAccess;
 
     @Override
     protected void setUp() throws Exception {
@@ -87,11 +86,8 @@
         assertTrue("Unknown build type: " + buildType,
                 Arrays.asList("user", "userdebug", "eng").contains(buildType));
         boolean wasRoot = mDevice.isAdbRoot();
-        mIsRoot = (!buildType.equals("user"));
-        mNewlyObtainedRoot = (mIsRoot && !wasRoot);
-        if (mNewlyObtainedRoot) {
-            mDevice.enableAdbRoot();
-        }
+        // We can only enable root access on userdebug and eng builds.
+        mCanEnableDeviceRootAccess = buildType.equals("userdebug") || buildType.equals("eng");
 
         apkFile = File.createTempFile("CtsCompilationApp", ".apk");
         try (OutputStream outputStream = new FileOutputStream(apkFile)) {
@@ -111,9 +107,6 @@
 
     @Override
     protected void tearDown() throws Exception {
-        if (mNewlyObtainedRoot) {
-            mDevice.disableAdbRoot();
-        }
         FileUtil.deleteFile(apkFile);
         FileUtil.deleteFile(localProfileFile);
         mDevice.uninstallPackage(APPLICATION_PACKAGE);
@@ -165,7 +158,7 @@
                  EnumSet.of(ProfileLocation.CUR));
         if (didRun) {
             assertTrue("ref profile should have been created by the compiler",
-                    mDevice.doesFileExist(ProfileLocation.REF.getPath()));
+                    doesFileExist(ProfileLocation.REF.getPath()));
         }
     }
 
@@ -184,10 +177,10 @@
 
     private byte[] readFileOnClient(String clientPath) throws Exception {
         assertTrue("File not found on client: " + clientPath,
-                mDevice.doesFileExist(clientPath));
+                doesFileExist(clientPath));
         File copyOnHost = File.createTempFile("host", "copy");
         try {
-            executeAdbCommand("pull", clientPath, copyOnHost.getPath());
+            executePull(clientPath, copyOnHost.getPath());
             return Files.toByteArray(copyOnHost);
         } finally {
             FileUtil.deleteFile(copyOnHost);
@@ -209,8 +202,8 @@
         // ensure no profiles initially present
         for (ProfileLocation profileLocation : ProfileLocation.values()) {
             String clientPath = profileLocation.getPath();
-            if (mDevice.doesFileExist(clientPath)) {
-                executeAdbCommand(0, "shell", "rm", clientPath);
+            if (doesFileExist(clientPath)) {
+                executeSuShellAdbCommand(0, "rm", clientPath);
             }
         }
         executeCompile("-m", "speed-profile", "-f");
@@ -247,11 +240,11 @@
      * @param compileOptions extra options to pass to the compiler on the command line
      */
     private void executeCompile(String... compileOptions) throws Exception {
-        List<String> command = new ArrayList<>(Arrays.asList("shell", "cmd", "package", "compile"));
+        List<String> command = new ArrayList<>(Arrays.asList("cmd", "package", "compile"));
         command.addAll(Arrays.asList(compileOptions));
         command.add(APPLICATION_PACKAGE);
         String[] commandArray = command.toArray(new String[0]);
-        assertEquals("Success", executeAdbCommand(1, commandArray)[0]);
+        assertEquals("Success", executeSuShellAdbCommand(1, commandArray)[0]);
     }
 
     /**
@@ -261,21 +254,21 @@
         String targetPath = location.getPath();
         // Get the owner of the parent directory so we can set it on the file
         String targetDir = location.getDirectory();
-        if (!mDevice.doesFileExist(targetDir)) {
+        if (!doesFileExist(targetDir)) {
             fail("Not found: " + targetPath);
         }
         // in format group:user so we can directly pass it to chown
-        String owner = executeAdbCommand(1, "shell", "stat", "-c", "%U:%g", targetDir)[0];
+        String owner = executeSuShellAdbCommand(1, "stat", "-c", "%U:%g", targetDir)[0];
         // for some reason, I've observed the output starting with a single space
         while (owner.startsWith(" ")) {
             owner = owner.substring(1);
         }
-        mDevice.executeAdbCommand("push", localProfileFile.getAbsolutePath(), targetPath);
-        executeAdbCommand(0, "shell", "chown", owner, targetPath);
+        executePush(localProfileFile.getAbsolutePath(), targetPath);
+        executeSuShellAdbCommand(0, "chown", owner, targetPath);
         // Verify that the file was written successfully
-        assertTrue("failed to create profile file", mDevice.doesFileExist(targetPath));
+        assertTrue("failed to create profile file", doesFileExist(targetPath));
         assertEquals(Integer.toString(profileBytes.length),
-                executeAdbCommand(1, "shell", "stat", "-c", "%s", targetPath)[0]);
+                executeSuShellAdbCommand(1, "stat", "-c", "%s", targetPath)[0]);
     }
 
     /**
@@ -283,8 +276,8 @@
      * {@code oatdump --header-only}.
      */
     private String getCompilerFilter(String odexFilePath) throws DeviceNotAvailableException {
-        String[] response = executeAdbCommand(
-                "shell", "oatdump", "--header-only", "--oat-file=" + odexFilePath);
+        String[] response = executeSuShellAdbCommand(
+                "oatdump", "--header-only", "--oat-file=" + odexFilePath);
         String prefix = "compiler-filter =";
         for (String line : response) {
             line = line.trim();
@@ -302,14 +295,14 @@
      */
     private String getOdexFilePath() throws DeviceNotAvailableException {
         // Something like "package:/data/app/android.cts.compilation-1/base.apk"
-        String pathSpec = executeAdbCommand(1, "shell", "pm", "path", APPLICATION_PACKAGE)[0];
+        String pathSpec = executeSuShellAdbCommand(1, "pm", "path", APPLICATION_PACKAGE)[0];
         Matcher matcher = Pattern.compile("^package:(.+/)base\\.apk$").matcher(pathSpec);
         boolean found = matcher.find();
         assertTrue("Malformed spec: " + pathSpec, found);
         String apkDir = matcher.group(1);
         // E.g. /data/app/android.cts.compilation-1/oat/arm64/base.odex
-        String result = executeAdbCommand(1, "shell", "find", apkDir, "-name", "base.odex")[0];
-        assertTrue("odex file not found: " + result, mDevice.doesFileExist(result));
+        String result = executeSuShellAdbCommand(1, "find", apkDir, "-name", "base.odex")[0];
+        assertTrue("odex file not found: " + result, doesFileExist(result));
         return result;
     }
 
@@ -323,23 +316,24 @@
      * TODO: Use Assume.assumeTrue() if this test gets converted to JUnit 4.
      */
     private boolean canRunTest(Set<ProfileLocation> profileLocations) throws Exception {
-        boolean result = mIsRoot && (profileLocations.isEmpty() || isUseJitProfiles());
+        boolean result = mCanEnableDeviceRootAccess &&
+                (profileLocations.isEmpty() || isUseJitProfiles());
         if (!result) {
-            System.err.printf("Skipping test [isRoot=%s, %d profiles] on %s\n",
-                    mIsRoot, profileLocations.size(), mDevice);
+            System.err.printf("Skipping test [mCanEnableDeviceRootAccess=%s, %d profiles] on %s\n",
+                    mCanEnableDeviceRootAccess, profileLocations.size(), mDevice);
         }
         return result;
     }
 
     private boolean isUseJitProfiles() throws Exception {
         boolean propUseJitProfiles = Boolean.parseBoolean(
-                executeAdbCommand(1, "shell", "getprop", "dalvik.vm.usejitprofiles")[0]);
+                executeSuShellAdbCommand(1, "getprop", "dalvik.vm.usejitprofiles")[0]);
         return propUseJitProfiles;
     }
 
-    private String[] executeAdbCommand(int numLinesOutputExpected, String... command)
+    private String[] executeSuShellAdbCommand(int numLinesOutputExpected, String... command)
             throws DeviceNotAvailableException {
-        String[] lines = executeAdbCommand(command);
+        String[] lines = executeSuShellAdbCommand(command);
         assertEquals(
                 String.format(Locale.US, "Expected %d lines output, got %d running %s: %s",
                         numLinesOutputExpected, lines.length, Arrays.toString(command),
@@ -348,10 +342,38 @@
         return lines;
     }
 
-    private String[] executeAdbCommand(String... command) throws DeviceNotAvailableException {
-        String output = mDevice.executeAdbCommand(command);
+    private String[] executeSuShellAdbCommand(String... command)
+            throws DeviceNotAvailableException {
+        // Add `shell su root` to the adb command.
+        String cmdString = String.join(" ", command);
+        String output = mDevice.executeShellCommand("su root " + cmdString);
         // "".split() returns { "" }, but we want an empty array
         String[] lines = output.equals("") ? new String[0] : output.split("\n");
         return lines;
     }
+
+    private void executePush(String hostPath, String targetPath)
+            throws DeviceNotAvailableException {
+        String tmpPath = "/data/local/tmp/" + APPLICATION_PACKAGE + ".push.tmp";
+        assertTrue(mDevice.pushFile(new File(hostPath), tmpPath));
+        executeSuShellAdbCommand("mv", tmpPath, targetPath);
+    }
+
+    private void executePull(String targetPath, String hostPath)
+            throws DeviceNotAvailableException {
+        String tmpPath = "/data/local/tmp/" + APPLICATION_PACKAGE + ".pull.tmp";
+        executeSuShellAdbCommand("cp", targetPath, tmpPath);
+        try {
+            executeSuShellAdbCommand("chmod", "606", tmpPath);
+            assertTrue(mDevice.pullFile(tmpPath, new File(hostPath)));
+        } finally {
+            executeSuShellAdbCommand("rm", tmpPath);
+        }
+    }
+
+    private boolean doesFileExist(String path) throws DeviceNotAvailableException {
+        String[] result = executeSuShellAdbCommand("ls", path);
+        // Testing for empty directories will return an empty array.
+        return !(result.length > 0 && result[0].contains("No such file"));
+    }
 }