Merge "DO NOT MERGE:Skip testSanity for the data only devices" into pie-cts-dev
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index e2459d0..16f7610 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -32,6 +32,8 @@
     private static final String VERSION_NAME = "version_name";
     private static final String SYSTEM_PRIV = "system_priv";
     private static final String PRIV_APP_DIR = "/system/priv-app";
+    private static final String MIN_SDK = "min_sdk";
+    private static final String TARGET_SDK = "target_sdk";
 
     @Override
     protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
@@ -45,6 +47,9 @@
             if (pkg.applicationInfo != null) {
                 String dir = pkg.applicationInfo.sourceDir;
                 store.addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
+
+                store.addResult(MIN_SDK, pkg.applicationInfo.minSdkVersion);
+                store.addResult(TARGET_SDK, pkg.applicationInfo.targetSdkVersion);
             }
             store.endGroup();
         }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
index 6849d0c..8ac50af 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
@@ -15,18 +15,23 @@
  */
 package android.appsecurity.cts;
 
-import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
 
-import android.platform.test.annotations.AppModeFull;
+import com.android.ddmlib.Log.LogLevel;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.util.FileUtil;
 
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 
 import java.io.File;
@@ -35,104 +40,114 @@
  * Set of tests that verify that corrupt APKs are properly rejected by PackageManager and
  * do not cause the system to crash.
  */
-@AppModeFull // TODO: Needs porting to instant
 public class CorruptApkTests extends DeviceTestCase implements IBuildReceiver {
-    private final String B71360999_PKG = "com.android.appsecurity.b71360999";
-    private final String B71361168_PKG = "com.android.appsecurity.b71361168";
-    private final String B79488511_PKG = "com.android.appsecurity.b79488511";
 
     private IBuildInfo mBuildInfo;
 
+    /** A container for information about the system_server process. */
+    private class SystemServerInformation {
+        final long mPid;
+        final long mStartTime;
+
+        SystemServerInformation(long pid, long startTime) {
+            this.mPid = pid;
+            this.mStartTime = startTime;
+        }
+
+        @Override
+        public boolean equals(Object actual) {
+            return (actual instanceof SystemServerInformation)
+                && mPid == ((SystemServerInformation) actual).mPid
+                && mStartTime == ((SystemServerInformation) actual).mStartTime;
+        }
+    }
+
+    /** Retrieves the process id and elapsed run time of system_server. */
+    private SystemServerInformation retrieveInfo() throws DeviceNotAvailableException {
+        ITestDevice device = getDevice();
+
+        // Retrieve the process id of system_server
+        String pidResult = device.executeShellCommand("pidof system_server").trim();
+        assertNotNull("Failed to retrieve pid of system_server", pidResult);
+        long pid = 0;
+        try {
+            pid = Long.parseLong(pidResult);
+        } catch (NumberFormatException | IndexOutOfBoundsException e) {
+            fail("Unable to parse pid of system_server '" + pidResult + "'");
+        }
+
+        // Retrieve the start time of system_server
+        long startTime = 0;
+        String pidStats = device.executeShellCommand("cat /proc/" + pid + "/stat");
+        assertNotNull("Failed to retrieve stat of system_server with pid '" + pid + "'", pidStats);
+        try {
+            String startTimeJiffies = pidStats.split("\\s+")[21];
+            startTime = Long.parseLong(startTimeJiffies);
+        } catch (NumberFormatException | IndexOutOfBoundsException e) {
+            fail("Unable to parse system_server stat file '" + pidStats + "'");
+        }
+
+        return new SystemServerInformation(pid, startTime);
+    }
+
     @Override
     public void setBuild(IBuildInfo buildInfo) {
         mBuildInfo = buildInfo;
     }
 
+   /** Uninstall any test APKs already present on device. */
+    private void uninstallApks() throws DeviceNotAvailableException {
+        ITestDevice device = getDevice();
+        device.uninstallPackage("com.android.appsecurity.b71360999");
+        device.uninstallPackage("com.android.appsecurity.b71361168");
+        device.uninstallPackage("com.android.appsecurity.b79488511");
+    }
+
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        uninstall(B71360999_PKG);
-        uninstall(B71361168_PKG);
-        uninstall(B79488511_PKG);
+        uninstallApks();
     }
 
     @After
     @Override
     public void tearDown() throws Exception {
         super.tearDown();
-        uninstall(B71360999_PKG);
-        uninstall(B71361168_PKG);
-        uninstall(B79488511_PKG);
-    }
-
-    /** Uninstall the apk if the test failed previously. */
-    public void uninstall(String pkg) throws Exception {
-        ITestDevice device = getDevice();
-        if (device.getInstalledPackageNames().contains(pkg)) {
-            device.uninstallPackage(pkg);
-        }
+        uninstallApks();
     }
 
     /**
-     * Tests that apks described in b/71360999 do not install successfully.
+     * Asserts that installing the application does not cause a native error causing system_server
+     * to crash (typically the result of a buffer overflow or an out-of-bounds read).
      */
-    public void testFailToInstallCorruptStringPoolHeader_b71360999() throws Exception {
-        final String APK_PATH = "CtsCorruptApkTests_b71360999.apk";
-        assertInstallNoFatalError(APK_PATH, B71360999_PKG);
-    }
+    private void assertInstallDoesNotCrashSystem(String apk) throws Exception {
+        SystemServerInformation beforeInfo = retrieveInfo();
 
-    /**
-     * Tests that apks described in b/71361168 do not install successfully.
-     */
-    public void testFailToInstallCorruptStringPoolHeader_b71361168() throws Exception {
-        final String APK_PATH = "CtsCorruptApkTests_b71361168.apk";
-        assertInstallNoFatalError(APK_PATH, B71361168_PKG);
-    }
-
-    /**
-     * Tests that apks described in b/79488511 do not install successfully.
-     */
-    public void testFailToInstallCorruptStringPoolHeader_b79488511() throws Exception {
-        final String APK_PATH = "CtsCorruptApkTests_b79488511.apk";
-        assertInstallNoFatalError(APK_PATH, B79488511_PKG);
-    }
-
-    /**
-     * Assert that installing the app does not cause a native error caused by a buffer overflow
-     * or an out-of-bounds read.
-     **/
-    private void assertInstallNoFatalError(String filename, String pkg) throws Exception {
-        ITestDevice device = getDevice();
-        device.clearLogcat();
-
-        final String result = device.installPackage(
-                new CompatibilityBuildHelper(mBuildInfo).getTestFile(filename),
-                true /*reinstall*/);
-
-        // Starting from P, corrupt apks should always fail to install
-        if (device.getApiLevel() >= 28) {
-            assertThat(result).isNotNull();
-            assertThat(result).isNotEmpty();
-            assertThat(device.getInstalledPackageNames()).doesNotContain(pkg);
+        final String result = getDevice().installPackage(
+                new CompatibilityBuildHelper(mBuildInfo).getTestFile(apk),
+                false /*reinstall*/);
+        CLog.logAndDisplay(LogLevel.INFO, "Result: '" + result + "'");
+        if (result != null) {
+            assertFalse("Install package segmentation faulted",
+                result.toLowerCase().contains("segmentation fault"));
         }
 
-        // This catches if the device fails to install the app because a segmentation fault
-        // or out of bounds read created by the bug occurs
-        File tmpTxtFile = null;
-        InputStreamSource source = device.getLogcat(200 * 1024);
-        try {
-            assertNotNull(source);
-            tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
-            FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
-            String s = FileUtil.readStringFromFile(tmpTxtFile);
-            assertFalse(s.contains("SIGSEGV"));
-            assertFalse(s.contains("==ERROR"));
-        } finally {
-            source.close();
-            if (tmpTxtFile != null) {
-                FileUtil.deleteFile(tmpTxtFile);
-            }
-        }
+        assertEquals("system_server restarted", beforeInfo, retrieveInfo());
+    }
+
+    /** Tests that installing the APK described in b/71360999 does not crash the device. */
+    public void testSafeInstallOfCorruptAPK_b71360999() throws Exception {
+        assertInstallDoesNotCrashSystem("CtsCorruptApkTests_b71360999.apk");
+    }
+
+    /** Tests that installing the APK described in b/71361168 does not crash the device. */
+    public void testSafeInstallOfCorruptAPK_b71361168() throws Exception {
+        assertInstallDoesNotCrashSystem("CtsCorruptApkTests_b71361168.apk");
+    }
+
+    /** Tests that installing the APK described in b/79488511 does not crash the device. */
+    public void testSafeInstallOfCorruptAPK_b79488511() throws Exception {
+        assertInstallDoesNotCrashSystem("CtsCorruptApkTests_b79488511.apk");
     }
 }
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
old mode 100644
new mode 100755
index bbe6855..3227770
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -379,6 +379,8 @@
         localBroadcastManager.registerReceiver(broadcastReceiver,
                 new IntentFilter(BasicAdminReceiver.ACTION_USER_STOPPED));
 
+        Thread.sleep(USER_SWITCH_DELAY);
+
         try {
             assertEquals(UserManager.USER_OPERATION_SUCCESS,
                     mDevicePolicyManager.stopUser(getWho(), userHandle));
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
index 4fa6235..e5598bb 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.deviceowner;
 
+import static android.provider.Settings.Global.AIRPLANE_MODE_ON;
 
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.FreezePeriod;
@@ -27,12 +28,17 @@
 import android.icu.util.Calendar;
 import android.provider.Settings;
 import android.provider.Settings.Global;
+import android.util.Log;
 import android.util.Pair;
 
+import android.provider.Settings;
+import android.provider.Settings.Global;
+
 import java.time.LocalDate;
 import java.time.MonthDay;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
@@ -42,7 +48,10 @@
  */
 public class SystemUpdatePolicyTest extends BaseDeviceOwnerTest {
 
+    private static final String TAG = "SystemUpdatePolicyTest";
+
     private static final int TIMEOUT_MS = 20_000;
+    private static final int TIMEOUT_SEC = 5;
 
     private final Semaphore mPolicyChangedSemaphore = new Semaphore(0);
     private final Semaphore mTimeChangedSemaphore = new Semaphore(0);
@@ -61,6 +70,7 @@
     private int mSavedAutoTimeConfig;
     private LocalDate mSavedSystemDate;
     private boolean mRestoreDate;
+    private int mSavedAirplaneMode;
 
     @Override
     protected void setUp() throws Exception {
@@ -75,6 +85,12 @@
         executeShellCommand("settings put global auto_time 0");
         mSavedSystemDate = LocalDate.now();
         mRestoreDate = false;
+        mSavedAirplaneMode = getAirplaneMode();
+        Log.i(TAG, "Before testing, AIRPLANE_MODE is set to: " + mSavedAirplaneMode);
+        if (mSavedAirplaneMode == 0) {
+            // No need to set mode if AirplaneMode is 1 or error.
+            setAirplaneModeAndWaitBroadcast(1);
+        }
     }
 
     @Override
@@ -89,6 +105,10 @@
         // This needs to happen last since setSystemDate() relies on the receiver for
         // synchronization.
         mContext.unregisterReceiver(policyChangedReceiver);
+        if (mSavedAirplaneMode == 0) {
+            // Restore AirplaneMode value.
+            setAirplaneModeAndWaitBroadcast(0);
+        }
         super.tearDown();
     }
 
@@ -341,4 +361,42 @@
             fail("Interrupted while waiting for broadcast.");
         }
     }
+
+    private int getAirplaneMode() throws Settings.SettingNotFoundException {
+        int airplaneMode = 0xFF;
+        try {
+            airplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON);
+        } catch (Settings.SettingNotFoundException e) {
+            airplaneMode = 0xFF;
+            // if the mode is not supported, return a non zero value.
+            Log.i(TAG, "Airplane mode is not found in Settings. Skipping AirplaneMode update");
+        } finally {
+            return airplaneMode;
+        }
+    }
+
+    private boolean setAirplaneModeAndWaitBroadcast (int state) throws Exception {
+        Log.i(TAG, "setAirplaneModeAndWaitBroadcast setting state(0=disable, 1=enable): " + state);
+
+        final CountDownLatch latch = new CountDownLatch(1);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                Log.i(TAG, "Received broadcast for AirplaneModeUpdate");
+                latch.countDown();
+            }
+        };
+        mContext.registerReceiver(receiver, new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
+        try {
+            Settings.Global.putInt(mContext.getContentResolver(), AIRPLANE_MODE_ON, state);
+            if (!latch.await(TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                Log.d(TAG, "Failed to receive broadcast in " + TIMEOUT_SEC + "sec");
+                return false;
+            }
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+        return true;
+    }
 }
diff --git a/hostsidetests/jvmti/attaching/host/src/android/jvmti/cts/JvmtiAttachingHostTest.java b/hostsidetests/jvmti/attaching/host/src/android/jvmti/cts/JvmtiAttachingHostTest.java
index becabe1..9269a27 100644
--- a/hostsidetests/jvmti/attaching/host/src/android/jvmti/cts/JvmtiAttachingHostTest.java
+++ b/hostsidetests/jvmti/attaching/host/src/android/jvmti/cts/JvmtiAttachingHostTest.java
@@ -49,6 +49,7 @@
 
     private CompatibilityBuildHelper mBuildHelper;
     private IAbi mAbi;
+    private int mCurrentUser;
 
     @Override
     public void setBuild(IBuildInfo arg0) {
@@ -66,6 +67,11 @@
 
     private final static String AGENT = "libctsjvmtiattachagent.so";
 
+    @Override
+    protected void setUp() throws Exception {
+        mCurrentUser = getDevice().getCurrentUser();
+    }
+
     public void testJvmtiAttachDuringBind() throws Exception {
         runJvmtiAgentLoadTest((ITestDevice device, String pkg, String apk, String abiName) -> {
             try {
@@ -79,7 +85,8 @@
     public void testJvmtiAttachEarly() throws Exception {
         runJvmtiAgentLoadTest((ITestDevice device, String pkg, String apk, String abiName) -> {
             try {
-                String pwd = device.executeShellCommand("run-as " + pkg + " pwd");
+                String pwd = device.executeShellCommand(
+                        "run-as " + pkg + " --user " + mCurrentUser + " pwd");
                 if (pwd == null) {
                     throw new RuntimeException("pwd failed");
                 }
@@ -125,7 +132,8 @@
     public void testJvmtiAgentAppExternal() throws Exception {
         runJvmtiAgentLoadTest((ITestDevice device, String pkg, String apk, String abiName) -> {
             try {
-                String pwd = device.executeShellCommand("run-as " + pkg + " pwd");
+                String pwd = device.executeShellCommand(
+                        "run-as " + pkg + " --user " + mCurrentUser + " pwd");
                 if (pwd == null) {
                     throw new RuntimeException("pwd failed");
                 }
@@ -219,13 +227,14 @@
             }
 
             String runAsCp = device.executeShellCommand(
-                    "run-as " + pkg + " cp " + libInTmp + " " + libInDataData);
+                    "run-as " + pkg + " --user " + mCurrentUser +
+                            " cp " + libInTmp + " " + libInDataData);
             if (runAsCp != null && !runAsCp.trim().isEmpty()) {
                 throw new RuntimeException(runAsCp.trim());
             }
 
-            String runAsChmod = device
-                    .executeShellCommand("run-as " + pkg + " chmod a+x " + libInDataData);
+            String runAsChmod = device.executeShellCommand(
+                    "run-as " + pkg + " --user " + mCurrentUser + " chmod a+x " + libInDataData);
             if (runAsChmod != null && !runAsChmod.trim().isEmpty()) {
                 throw new RuntimeException(runAsChmod.trim());
             }
diff --git a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
index f80492c..edc685a 100644
--- a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
+++ b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
@@ -59,6 +59,7 @@
 
     private CompatibilityBuildHelper mBuildHelper;
     private IAbi mAbi;
+    private int mCurrentUser;
 
     @Override
     public void setBuild(IBuildInfo arg0) {
@@ -70,6 +71,11 @@
         mAbi = arg0;
     }
 
+    @Override
+    protected void setUp() throws Exception {
+        mCurrentUser = getDevice().getCurrentUser();
+    }
+
     public void testJvmti() throws Exception {
         final ITestDevice device = getDevice();
 
@@ -123,7 +129,8 @@
         @Override
         public void run() {
             try {
-                String pwd = mDevice.executeShellCommand("run-as " + mPkg + " pwd");
+                String pwd = mDevice.executeShellCommand(
+                        "run-as " + mPkg + " --user " + mCurrentUser + " pwd");
                 if (pwd == null) {
                     throw new RuntimeException("pwd failed");
                 }
@@ -165,13 +172,15 @@
                 }
 
                 String runAsCp = mDevice.executeShellCommand(
-                        "run-as " + mPkg + " cp " + libInTmp + " " + libInDataData);
+                        "run-as " + mPkg + " --user " + mCurrentUser +
+                                " cp " + libInTmp + " " + libInDataData);
                 if (runAsCp != null && !runAsCp.trim().isEmpty()) {
                     throw new RuntimeException(runAsCp.trim());
                 }
 
-                String runAsChmod = mDevice
-                        .executeShellCommand("run-as " + mPkg + " chmod a+x " + libInDataData);
+                String runAsChmod = mDevice.executeShellCommand(
+                        "run-as " + mPkg + " --user " + mCurrentUser +
+                                " chmod a+x " + libInDataData);
                 if (runAsChmod != null && !runAsChmod.trim().isEmpty()) {
                     throw new RuntimeException(runAsChmod.trim());
                 }
diff --git a/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java b/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
index 3fcbba9..01e7795 100644
--- a/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
+++ b/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
@@ -29,13 +29,13 @@
  * Base class for multi user tests.
  */
 public class BaseMultiUserTest implements IDeviceTest {
-    protected static final int USER_SYSTEM = 0; // From the UserHandle class.
-
     /** Whether multi-user is supported. */
     protected boolean mSupportsMultiUser;
     protected boolean mIsSplitSystemUser;
+    protected int mInitialUserId;
     protected int mPrimaryUserId;
-    /** Users we shouldn't delete in the tests */
+
+    /** Users we shouldn't delete in the tests. */
     private ArrayList<Integer> mFixedUsers;
 
     private ITestDevice mDevice;
@@ -44,22 +44,21 @@
     public void setUp() throws Exception {
         mSupportsMultiUser = getDevice().getMaxNumberOfUsersSupported() > 1;
         mIsSplitSystemUser = checkIfSplitSystemUser();
+
+        mInitialUserId = getDevice().getCurrentUser();
         mPrimaryUserId = getDevice().getPrimaryUserId();
-        mFixedUsers = new ArrayList<>();
-        mFixedUsers.add(mPrimaryUserId);
-        if (mPrimaryUserId != USER_SYSTEM) {
-            mFixedUsers.add(USER_SYSTEM);
-        }
-        getDevice().switchUser(mPrimaryUserId);
-        removeTestUsers();
+
+        // Test should not modify / remove any of the existing users.
+        mFixedUsers = getDevice().listUsers();
     }
 
     @After
     public void tearDown() throws Exception {
-        if (getDevice().getCurrentUser() != mPrimaryUserId) {
-            CLog.w("User changed during test. Switching back to " + mPrimaryUserId);
-            getDevice().switchUser(mPrimaryUserId);
+        if (getDevice().getCurrentUser() != mInitialUserId) {
+            CLog.w("User changed during test. Switching back to " + mInitialUserId);
+            getDevice().switchUser(mInitialUserId);
         }
+        // Remove the users created during this test.
         removeTestUsers();
     }
 
@@ -131,4 +130,4 @@
                 || "1".equals(commandOuput) || "true".equals(commandOuput)
                 || "on".equals(commandOuput);
     }
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/multiuser/src/android/host/multiuser/CreateUsersNoAppCrashesTest.java b/hostsidetests/multiuser/src/android/host/multiuser/CreateUsersNoAppCrashesTest.java
index 9a4f829..1d8a13e 100644
--- a/hostsidetests/multiuser/src/android/host/multiuser/CreateUsersNoAppCrashesTest.java
+++ b/hostsidetests/multiuser/src/android/host/multiuser/CreateUsersNoAppCrashesTest.java
@@ -45,19 +45,11 @@
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class CreateUsersNoAppCrashesTest extends BaseMultiUserTest {
-    private int mInitialUserId;
-    private static final long LOGCAT_POLL_INTERVAL_MS = 5000;
+    private static final long LOGCAT_POLL_INTERVAL_MS = 1000;
     private static final long USER_SWITCH_COMPLETE_TIMEOUT_MS = 180000;
 
     @Rule public AppCrashRetryRule appCrashRetryRule = new AppCrashRetryRule();
 
-    @Before
-    public void setUp() throws Exception {
-        CLog.e("setup_CreateUsersNoAppCrashesTest");
-        super.setUp();
-        mInitialUserId = getDevice().getCurrentUser();
-    }
-
     @Presubmit
     @Test
     public void testCanCreateGuestUser() throws Exception {
@@ -70,7 +62,6 @@
                 false /* ephemeral */);
         assertSwitchToNewUser(userId);
         assertSwitchToUser(userId, mInitialUserId);
-
     }
 
     @Presubmit
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index a8e4574..331872d 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -228,7 +228,7 @@
 
         Thread.sleep(WAIT_TIME_SHORT);
         setAppBreadcrumbPredicate();
-        Thread.sleep(WAIT_TIME_SHORT);
+        Thread.sleep(WAIT_TIME_LONG);
 
         List<Atom> atomList = getGaugeMetricDataList();
 
diff --git a/hostsidetests/theme/assets/24/400dpi.zip b/hostsidetests/theme/assets/24/400dpi.zip
new file mode 100755
index 0000000..b76e564
--- /dev/null
+++ b/hostsidetests/theme/assets/24/400dpi.zip
@@ -0,0 +1 @@
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>hostsidetests/theme/assets/26/400dpi.zip - platform/cts - Git at Google</title><link rel="stylesheet" type="text/css" href="/+static/base.8PwAX-dsywmU2hx_vi_YSA.cache.css"><link rel="stylesheet" type="text/css" href="/+static/prettify/prettify.pZ5FqzM6cPxAflH0va2Ucw.cache.css"><!-- default customHeadTagPart --></head><body class="Site"><header class="Site-header"><div class="Header"><a class="Header-image" href="/"><img src="//www.gstatic.com/images/branding/lockups/2x/lockup_git_color_108x24dp.png" width="108" height="24" alt="Google Git"></a><div class="Header-menu"> <a class="Header-menuItem" href="https://accounts.google.com/AccountChooser?service=gerritcodereview&amp;continue=https://android.googlesource.com/login/platform/cts/%2B/android-cts-8.0_r14/hostsidetests/theme/assets/26/400dpi.zip">Sign in</a> </div></div></header><div class="Site-content"><div class="Container "><div class="Breadcrumbs"><a class="Breadcrumbs-crumb" href="/?format=HTML">android</a> / <a class="Breadcrumbs-crumb" href="/platform/">platform</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/">cts</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14">android-cts-8.0_r14</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14/">.</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14/hostsidetests">hostsidetests</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14/hostsidetests/theme">theme</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14/hostsidetests/theme/assets">assets</a> / <a class="Breadcrumbs-crumb" href="/platform/cts/+/android-cts-8.0_r14/hostsidetests/theme/assets/26">26</a> / <span class="Breadcrumbs-crumb">400dpi.zip</span></div><div class="u-sha1 u-monospace BlobSha1">blob: d624bd54df060b534c62c07b8cf8b70b126b8f58 [<a href="/platform/cts/+/android-cts-8.0_r14/hostsidetests/theme/assets/26/400dpi.zip">file</a>] [<a href="/platform/cts/+log/android-cts-8.0_r14/hostsidetests/theme/assets/26/400dpi.zip">log</a>] [<a href="/platform/cts/+blame/android-cts-8.0_r14/hostsidetests/theme/assets/26/400dpi.zip">blame</a>]</div><div class="FileContents-binary">8615086-byte binary file</div></div> <!-- Container --></div> <!-- Site-content --><footer class="Site-footer"><div class="Footer"><span class="Footer-poweredBy">Powered by <a href="https://gerrit.googlesource.com/gitiles/">Gitiles</a>| <a href="https://policies.google.com/privacy">Privacy</a></span><span class="Footer-formats"><a class="u-monospace Footer-formatsItem" href="?format=TEXT">txt</a> <a class="u-monospace Footer-formatsItem" href="?format=JSON">json</a></span></div></footer></body></html>
\ No newline at end of file
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index 09d99a3..871503f 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -507,7 +507,7 @@
         }
     }
 
-  public void testWifiFeature() throws Exception {
+    public void testWifiFeature() throws Exception {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
             // no WiFi, skip the test
             return;
@@ -522,6 +522,13 @@
         }
     }
 
+    public void testAudioOutputFeature() throws Exception {
+        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+                mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)) {
+            assertAvailable(PackageManager.FEATURE_AUDIO_OUTPUT);
+        }
+    }
+
     private void assertAvailable(String feature) {
         assertTrue("PackageManager#hasSystemFeature should return true for " + feature,
                 mPackageManager.hasSystemFeature(feature));
diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java
index e267503..9694d17 100644
--- a/tests/app/src/android/app/cts/WallpaperManagerTest.java
+++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java
@@ -100,6 +100,52 @@
     }
 
     @Test
+    public void setBitmapTest_1x1Pixel() {
+        ensureCleanState();
+
+        Bitmap tmpWallpaper = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(tmpWallpaper);
+        canvas.drawColor(Color.RED);
+
+        try {
+            int which = WallpaperManager.FLAG_SYSTEM;
+            int oldWallpaperId = mWallpaperManager.getWallpaperId(which);
+            mWallpaperManager.suggestDesiredDimensions(tmpWallpaper.getWidth(),
+                    tmpWallpaper.getHeight());
+            mWallpaperManager.setBitmap(tmpWallpaper);
+            int newWallpaperId = mWallpaperManager.getWallpaperId(which);
+            Assert.assertNotEquals(oldWallpaperId, newWallpaperId);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            tmpWallpaper.recycle();
+        }
+    }
+
+    @Test
+    public void setBitmapTest_1x1Pixel_FullscreenDesired() {
+        ensureCleanState();
+
+        Bitmap tmpWallpaper = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(tmpWallpaper);
+        canvas.drawColor(Color.RED);
+
+        try {
+            int which = WallpaperManager.FLAG_SYSTEM;
+            int oldWallpaperId = mWallpaperManager.getWallpaperId(which);
+            final Point displaySize = getScreenSize();
+            mWallpaperManager.suggestDesiredDimensions(displaySize.x, displaySize.y);
+            mWallpaperManager.setBitmap(tmpWallpaper);
+            int newWallpaperId = mWallpaperManager.getWallpaperId(which);
+            Assert.assertNotEquals(oldWallpaperId, newWallpaperId);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            tmpWallpaper.recycle();
+        }
+    }
+
+    @Test
     public void setResourceTest() {
         try {
             int which = WallpaperManager.FLAG_SYSTEM;
@@ -226,33 +272,30 @@
      * Suggesting desired dimensions is only a hint to the system that can be ignored.
      *
      * Test if the desired minimum width or height the WallpaperManager returns
-     * is greater than 0. If so, then we check whether that the size is at least the
-     * as big as the screen.
+     * is greater than 0.
      */
     @Test
     public void suggestDesiredDimensionsTest() {
         final Point min = getScreenSize();
         final int w = min.x * 3;
         final int h = min.y * 2;
-        assertDesiredMinimum(new Point(min.x / 2, min.y / 2), min);
+        assertDesiredDimension(new Point(min.x / 2, min.y / 2), new Point(min.x / 2, min.y / 2));
 
-        assertDesiredMinimum(new Point(w, h), min);
+        assertDesiredDimension(new Point(w, h), new Point(w, h));
 
-        assertDesiredMinimum(new Point(min.x / 2, h), min);
+        assertDesiredDimension(new Point(min.x / 2, h), new Point(min.x / 2, h));
 
-        assertDesiredMinimum(new Point(w, min.y / 2), min);
+        assertDesiredDimension(new Point(w, min.y / 2), new Point(w, min.y / 2));
     }
 
-    private void assertDesiredMinimum(Point suggestedSize, Point minSize) {
+    private void assertDesiredDimension(Point suggestedSize, Point expectedSize) {
         mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y);
         Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(),
                 mWallpaperManager.getDesiredMinimumHeight());
-        if (actualSize.x > 0 || actualSize.y > 0) {
-            if ((actualSize.x < minSize.x || actualSize.y < minSize.y)) {
-                throw new AssertionError("Expected at least x: " + minSize.x + " y: "
-                        + minSize.y + ", got x: " + actualSize.x +
-                        " y: " + actualSize.y);
-            }
+        if (actualSize.x <= 0 || actualSize.y <= 0) {
+            throw new AssertionError("Expected x: " + expectedSize.x + " y: "
+                    + expectedSize.y + ", got x: " + actualSize.x +
+                    " y: " + actualSize.y);
         }
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
index ec3074b..18ef5aa 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SessionLifecycleTest.java
@@ -34,8 +34,11 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
+import android.app.ActivityManager;
+import android.content.Context;
 import android.app.PendingIntent;
 import android.app.assist.AssistStructure;
 import android.content.Intent;
@@ -148,6 +151,9 @@
     @Test
     public void testDatasetAuthResponseWhileAutofilledAppIsLifecycled() throws Exception {
         assumeTrue("Rotation is supported", Helper.isRotationSupported(mContext));
+        final ActivityManager activityManager = (ActivityManager) getContext()
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        assumeFalse(activityManager.isLowRamDevice());
 
         // Set service.
         enableService();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
index eb6e62c..74f4546 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAmProfileTests.java
@@ -26,14 +26,9 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
-import android.support.test.InstrumentationRegistry;
 
-import org.junit.Before;
 import org.junit.Test;
 
-import java.io.File;
-import java.io.FileInputStream;
-
 /**
  * Build/Install/Run:
  *     atest CtsActivityManagerDeviceTestCases:ActivityManagerAmProfileTests
@@ -46,17 +41,6 @@
     private static final String FIRST_WORD_NO_STREAMING = "*version\n";
     private static final String FIRST_WORD_STREAMING = "SLOW";  // Magic word set by runtime.
 
-    private String mReadableFilePath = null;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mReadableFilePath = InstrumentationRegistry.getContext()
-            .getExternalFilesDir(null)
-            .getPath() + "/profile.trace";
-    }
-
     /**
      * Test am profile functionality with the following 3 configurable options:
      *    starting the activity before start profiling? yes;
@@ -161,28 +145,17 @@
 
     private void verifyOutputFileFormat(final boolean streaming) throws Exception {
         // This is a hack. The am service has to write to /data/local/tmp because it doesn't have
-        // access to the sdcard but the test app can't read there
-        executeShellCommand("mv " + OUTPUT_FILE_PATH + " " + mReadableFilePath);
+        // access to the sdcard. The test cannot read from /data/local/tmp. This allows us to
+        // scan the content to validate what is needed for this test.
+        final String firstLine = executeShellCommand("head -1 " + OUTPUT_FILE_PATH);
 
         final String expectedFirstWord = streaming ? FIRST_WORD_STREAMING : FIRST_WORD_NO_STREAMING;
-        final byte[] data = readFile(mReadableFilePath);
-        assertThat("data size", data.length, greaterThanOrEqualTo(expectedFirstWord.length()));
-        final String actualFirstWord = new String(data, 0, expectedFirstWord.length());
+        assertThat(
+                "data size", firstLine.length(), greaterThanOrEqualTo(expectedFirstWord.length()));
+        final String actualFirstWord = firstLine.substring(0, expectedFirstWord.length());
         assertEquals("Unexpected first word", expectedFirstWord, actualFirstWord);
 
         // Clean up.
-        executeShellCommand("rm -f " + OUTPUT_FILE_PATH + " " + mReadableFilePath);
-    }
-
-    private static byte[] readFile(String clientPath) throws Exception {
-        final File file = new File(clientPath);
-        assertTrue("File not found on client: " + clientPath, file.isFile());
-        final int size = (int) file.length();
-        final byte[] bytes = new byte[size];
-        try (final FileInputStream fis = new FileInputStream(file)) {
-            final int readSize = fis.read(bytes, 0, bytes.length);
-            assertEquals("Read all data", bytes.length, readSize);
-            return bytes;
-        }
+        executeShellCommand("rm -f " + OUTPUT_FILE_PATH);
     }
 }
diff --git a/tests/tests/car/Android.mk b/tests/tests/car/Android.mk
index 7310085..049a8a6 100644
--- a/tests/tests/car/Android.mk
+++ b/tests/tests/car/Android.mk
@@ -24,7 +24,10 @@
 # When built, explicitly put it in the data partition.
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	android-support-test \
+	compatibility-device-util \
+	ctstestrunner
 
 LOCAL_JAVA_LIBRARIES := android.car android.test.base.stubs
 
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
index 984d896..76e2e3c 100644
--- a/tests/tests/car/AndroidManifest.xml
+++ b/tests/tests/car/AndroidManifest.xml
@@ -17,6 +17,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.car.cts">
     <uses-feature android:name="android.hardware.type.automotive" />
+    <uses-permission android:name="android.car.permission.CAR_EXTERIOR_ENVIRONMENT" />
+    <uses-permission android:name="android.car.permission.CAR_INFO" />
+
     <application>
         <uses-library android:name="android.test.runner" />
     </application>
diff --git a/tests/tests/car/AndroidTest.xml b/tests/tests/car/AndroidTest.xml
index c931169..558e7be 100644
--- a/tests/tests/car/AndroidTest.xml
+++ b/tests/tests/car/AndroidTest.xml
@@ -23,4 +23,5 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.car.cts" />
     </test>
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.CarModuleController"/>
 </configuration>
diff --git a/tests/tests/car/src/android/car/cts/CarApiTestBase.java b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
index d982c1b..7cf6a73 100644
--- a/tests/tests/car/src/android/car/cts/CarApiTestBase.java
+++ b/tests/tests/car/src/android/car/cts/CarApiTestBase.java
@@ -16,18 +16,31 @@
 
 package android.car.cts;
 
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeTrue;
+
 import android.car.Car;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
 import android.test.AndroidTestCase;
 
+import com.android.compatibility.common.util.FeatureUtil;
+
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.After;
 
-public class CarApiTestBase extends AndroidTestCase {
+public abstract class CarApiTestBase {
     protected static final long DEFAULT_WAIT_TIMEOUT_MS = 1000;
 
     private Car mCar;
@@ -39,18 +52,21 @@
         assertTrue(Looper.getMainLooper().isCurrentThread());
     }
 
-    @Override
     protected void setUp() throws Exception {
-        super.setUp();
-        mCar = Car.createCar(getContext(), mConnectionListener, null);
+        assumeTrue(FeatureUtil.isAutomotive());
+
+        Context context =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        mCar = Car.createCar(context, mConnectionListener, null);
         mCar.connect();
         mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        mCar.disconnect();
+    @After
+    public void disconnectCar() throws Exception {
+        if (mCar != null) {
+            mCar.disconnect();
+        }
     }
 
     protected synchronized Car getCar() {
diff --git a/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
index 2dd0a81..910819d 100644
--- a/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
@@ -15,30 +15,44 @@
  */
 package android.car.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import static android.car.CarAppFocusManager.APP_FOCUS_REQUEST_SUCCEEDED;
 import static android.car.CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION;
 import static android.car.CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND;
 
 import android.car.Car;
 import android.car.CarAppFocusManager;
+import android.content.Context;
 import android.platform.test.annotations.RequiresDevice;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+
 import android.util.Log;
 
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.After;
 import org.junit.Assert;
-
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
 @RequiresDevice
+@RunWith(AndroidJUnit4.class)
 public class CarAppFocusManagerTest extends CarApiTestBase {
     private static final String TAG = CarAppFocusManagerTest.class.getSimpleName();
     private CarAppFocusManager mManager;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
         mManager = (CarAppFocusManager) getCar().getCarManager(Car.APP_FOCUS_SERVICE);
         assertNotNull(mManager);
@@ -57,6 +71,7 @@
 
     }
 
+    @Test
     public void testSetActiveNullListener() throws Exception {
         try {
             mManager.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, null);
@@ -66,6 +81,7 @@
         }
     }
 
+    @Test
     public void testRegisterNull() throws Exception {
         try {
             mManager.addFocusListener(null, 0);
@@ -75,6 +91,7 @@
         }
     }
 
+    @Test
     public void testRegisterUnregister() throws Exception {
         FocusChangedListerner listener = new FocusChangedListerner();
         FocusChangedListerner listener2 = new FocusChangedListerner();
@@ -84,10 +101,14 @@
         mManager.removeFocusListener(listener2);
     }
 
+    @Test
     public void testFocusChange() throws Exception {
+        Context context =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+
         DefaultServiceConnectionListener connectionListener =
                 new DefaultServiceConnectionListener();
-        Car car2 = Car.createCar(getContext(), connectionListener, null);
+        Car car2 = Car.createCar(context, connectionListener, null);
         car2.connect();
         connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
         CarAppFocusManager manager2 = (CarAppFocusManager)
@@ -216,10 +237,13 @@
         manager2.removeFocusListener(change2);
     }
 
+    @Test
     public void testFilter() throws Exception {
         DefaultServiceConnectionListener connectionListener =
                 new DefaultServiceConnectionListener();
-        Car car2 = Car.createCar(getContext(), connectionListener);
+        Context context =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        Car car2 = Car.createCar(context, connectionListener);
         car2.connect();
         connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
         CarAppFocusManager manager2 = (CarAppFocusManager)
@@ -274,6 +298,7 @@
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, false));
     }
 
+    @Test
     public void testMultipleChangeListenersPerManager() throws Exception {
         FocusChangedListerner listener = new FocusChangedListerner();
         FocusChangedListerner listener2 = new FocusChangedListerner();
diff --git a/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
index e9de083..51cd291 100644
--- a/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarInfoManagerTest.java
@@ -15,29 +15,38 @@
  */
 package android.car.cts;
 
+import static org.junit.Assert.assertNotNull;
+
 import android.car.Car;
 import android.car.CarInfoManager;
 import android.os.Bundle;
 import android.platform.test.annotations.RequiresDevice;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
 @RequiresDevice
+@RunWith(AndroidJUnit4.class)
 public class CarInfoManagerTest extends CarApiTestBase {
 
     private CarInfoManager mCarInfoManager;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
         mCarInfoManager = (CarInfoManager) getCar().getCarManager(Car.INFO_SERVICE);
     }
 
+    @Test
     public void testVehicleId() throws Exception {
         assertNotNull(mCarInfoManager.getVehicleId());
     }
 
+    @Test
     public void testNullables() throws Exception {
         // no guarantee of existence. just call and check if it throws exception.
         mCarInfoManager.getManufacturer();
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 4ba2cbf..0c3aebc 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -15,20 +15,35 @@
  */
 package android.car.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import android.car.Car;
 import android.car.CarNotConnectedException;
 import android.car.content.pm.CarPackageManager;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.platform.test.annotations.RequiresDevice;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import java.util.List;
 
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RequiresDevice
+@RunWith(AndroidJUnit4.class)
 public class CarPackageManagerTest extends CarApiTestBase {
 
     private CarPackageManager mCarPm;
@@ -37,14 +52,14 @@
     /** Name of the meta-data attribute for the automotive application XML resource */
     private static final String METADATA_ATTRIBUTE = "android.car.application";
 
-
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
         mCarPm = (CarPackageManager) getCar().getCarManager(Car.PACKAGE_SERVICE);
     }
 
-   public void testActivityDistractionOptimized() throws Exception {
+    @Test
+    public void testActivityDistractionOptimized() throws Exception {
        assertFalse(mCarPm.isActivityDistractionOptimized("com.basic.package", "DummyActivity"));
        // Real system activity is not allowed as well.
        assertFalse(mCarPm.isActivityDistractionOptimized("com.android.phone", "CallActivity"));
@@ -69,8 +84,10 @@
        }
    }
 
+    @Test
     public void testSystemActivitiesAllowed() throws CarNotConnectedException {
-        List<PackageInfo> packages = getContext().getPackageManager().getInstalledPackages(
+        Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(
                 PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
 
         for (PackageInfo info : packages) {
@@ -95,6 +112,8 @@
         }
     }
 
+    @Test
+    @Ignore // Enable when b/120125891 is fixed
     public void testServiceDistractionOptimized() throws Exception {
         assertFalse(mCarPm.isServiceDistractionOptimized("com.basic.package", ""));
         assertTrue(mCarPm.isServiceDistractionOptimized("com.android.settings", "Any"));
diff --git a/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
index 21358a6..3b9d8eb 100644
--- a/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarSensorManagerTest.java
@@ -16,30 +16,50 @@
 
 package android.car.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
 import android.car.Car;
 import android.car.hardware.CarSensorEvent;
 import android.car.hardware.CarSensorManager;
 import android.platform.test.annotations.RequiresDevice;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.CddTest;
+
+import java.util.stream.IntStream;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @SmallTest
 @RequiresDevice
+@RunWith(AndroidJUnit4.class)
 public class CarSensorManagerTest extends CarApiTestBase {
 
-    private CarSensorManager mCarSensorManager;
+    private int[] mSupportedSensors;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
-        mCarSensorManager = (CarSensorManager) getCar().getCarManager(Car.SENSOR_SERVICE);
+        CarSensorManager carSensorManager =
+                (CarSensorManager) getCar().getCarManager(Car.SENSOR_SERVICE);
+        mSupportedSensors = carSensorManager.getSupportedSensors();
+        assertNotNull(mSupportedSensors);
     }
 
+    @CddTest(requirement="2.5.1")
+    @Test
+    @Ignore // Enable when b/120125891 is fixed
     public void testRequiredSensorsForDrivingState() throws Exception {
-        int[] supportedSensors = mCarSensorManager.getSupportedSensors();
-        assertNotNull(supportedSensors);
         boolean foundSpeed = false;
         boolean foundGear = false;
-        for (int sensor: supportedSensors) {
+        for (int sensor: mSupportedSensors) {
             if (sensor == CarSensorManager.SENSOR_TYPE_CAR_SPEED) {
                 foundSpeed = true;
             } else if ( sensor == CarSensorManager.SENSOR_TYPE_GEAR) {
@@ -51,4 +71,12 @@
         }
         assertTrue(foundGear && foundSpeed);
     }
+
+    @CddTest(requirement="2.5.1")
+    @Test
+    public void testMustSupportNightSensor() {
+        assertTrue("Must support SENSOR_TYPE_NIGHT",
+                IntStream.of(mSupportedSensors)
+                        .anyMatch(x -> x == CarSensorManager.SENSOR_TYPE_NIGHT));
+    }
 }
diff --git a/tests/tests/car/src/android/car/cts/CarTest.java b/tests/tests/car/src/android/car/cts/CarTest.java
index 61b16bb..e406008 100644
--- a/tests/tests/car/src/android/car/cts/CarTest.java
+++ b/tests/tests/car/src/android/car/cts/CarTest.java
@@ -15,30 +15,53 @@
  */
 package android.car.cts;
 
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
 import android.car.Car;
 import android.content.ComponentName;
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.platform.test.annotations.RequiresDevice;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.FeatureUtil;
+
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
 @RequiresDevice
-public class CarTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class CarTest {
 
     private static final long DEFAULT_WAIT_TIMEOUT_MS = 2000;
 
     private Car mCar;
     private DefaultServiceConnectionListener mServiceConnectionListener;
 
+    @Before
+    public void setUp() {
+        assumeTrue(FeatureUtil.isAutomotive());
+    }
+
+    @Test
     public void testConnection() throws Exception {
         mServiceConnectionListener = new DefaultServiceConnectionListener();
-        mCar = Car.createCar(getContext(), mServiceConnectionListener);
+        mCar = Car.createCar(
+            InstrumentationRegistry.getInstrumentation().getTargetContext(),
+                    mServiceConnectionListener);
         assertFalse(mCar.isConnected());
         assertFalse(mCar.isConnecting());
         mCar.connect();
diff --git a/tests/tests/car/src/android/car/cts/ExceptionsTest.java b/tests/tests/car/src/android/car/cts/ExceptionsTest.java
index 904650f..4a14de9 100644
--- a/tests/tests/car/src/android/car/cts/ExceptionsTest.java
+++ b/tests/tests/car/src/android/car/cts/ExceptionsTest.java
@@ -15,18 +15,35 @@
  */
 package android.car.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeTrue;
+
 import android.car.CarNotConnectedException;
 import android.platform.test.annotations.RequiresDevice;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.compatibility.common.util.FeatureUtil;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
 @RequiresDevice
-public class ExceptionsTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class ExceptionsTest {
     private static final String MESSAGE = "Oops!";
     private static final Exception CAUSE = new RuntimeException();
 
+    @Before
+    public void setUp() {
+        assumeTrue(FeatureUtil.isAutomotive());
+    }
+
+    @Test
     public void testCarNotConnectedException() {
         CarNotConnectedException exception = new CarNotConnectedException();
         assertNull(exception.getMessage());
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index 569b3501..7ac5246 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -24,6 +24,7 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.compatibility.common.util.CddTest;
 import com.android.compatibility.common.util.FeatureUtil;
 
 import java.util.HashSet;
@@ -34,16 +35,22 @@
  */
 public class ConfigurationTest extends AndroidTestCase {
 
-    @Presubmit
-    public void testScreenConfiguration() {
+    private DisplayMetrics mMetrics;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
         WindowManager windowManager =
                 (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
         Display display = windowManager.getDefaultDisplay();
-        DisplayMetrics metrics = new DisplayMetrics();
-        display.getMetrics(metrics);
+        mMetrics = new DisplayMetrics();
+        display.getMetrics(mMetrics);
+    }
 
-        double xInches = (double) metrics.widthPixels / metrics.xdpi;
-        double yInches = (double) metrics.heightPixels / metrics.ydpi;
+    @Presubmit
+    public void testScreenConfiguration() {
+        double xInches = (double) mMetrics.widthPixels / mMetrics.xdpi;
+        double yInches = (double) mMetrics.heightPixels / mMetrics.ydpi;
         double diagonalInches = Math.sqrt(Math.pow(xInches, 2) + Math.pow(yInches, 2));
         double minSize = 2.5d;
         if (FeatureUtil.isWatch()) {
@@ -56,7 +63,7 @@
         assertTrue("Screen diagonal must be at least " + minSize + " inches: " + diagonalInches,
                 diagonalInches >= minSize);
 
-        double density = 160.0d * metrics.density;
+        double density = 160.0d * mMetrics.density;
         assertTrue("Screen density must be at least 100 dpi: " + density, density >= 100.0d);
 
         Set<Integer> allowedDensities = new HashSet<Integer>();
@@ -77,10 +84,22 @@
         allowedDensities.add(DisplayMetrics.DENSITY_560);
         allowedDensities.add(DisplayMetrics.DENSITY_XXXHIGH);
         assertTrue("DisplayMetrics#densityDpi must be one of the DisplayMetrics.DENSITY_* values: "
-                + allowedDensities, allowedDensities.contains(metrics.densityDpi));
+                + allowedDensities, allowedDensities.contains(mMetrics.densityDpi));
 
-        assertEquals(metrics.density,
-                (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT,
+        assertEquals(mMetrics.density,
+                (float) mMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT,
                 0.5f / DisplayMetrics.DENSITY_DEFAULT);
     }
+
+    @CddTest(requirement="2.5.1")
+    public void testAutomotiveMinimumScreenSize() {
+        if (!FeatureUtil.isAutomotive()) {
+            return;
+        }
+        float dpHeight = mMetrics.heightPixels / mMetrics.density;
+        float dpWidth = mMetrics.widthPixels / mMetrics.density;
+
+        assertTrue("Height must be >= 480dp, found: " + dpHeight, dpHeight >= 480);
+        assertTrue("Width must be >= 750dp, found: " + dpWidth, dpWidth >= 750);
+    }
 }
diff --git a/tests/tests/graphics/jni/android_graphics_cts_BasicVulkanGpuTest.cpp b/tests/tests/graphics/jni/android_graphics_cts_BasicVulkanGpuTest.cpp
index c9ed883..6c90941 100644
--- a/tests/tests/graphics/jni/android_graphics_cts_BasicVulkanGpuTest.cpp
+++ b/tests/tests/graphics/jni/android_graphics_cts_BasicVulkanGpuTest.cpp
@@ -75,9 +75,6 @@
     // Could not initialize Vulkan due to lack of device support, skip test.
     return;
   }
-  VkImageRenderer renderer(&init, kTestImageWidth, kTestImageHeight,
-                           formatDesc.vkFormat, formatDesc.pixelWidth);
-  ASSERT(renderer.init(env, assetMgr), "Unable to initialize VkRenderer.");
 
   // Create and initialize buffer based on parameters.
   AHardwareBuffer_Desc hwbDesc{
@@ -96,6 +93,10 @@
     return;
   }
 
+  VkImageRenderer renderer(&init, kTestImageWidth, kTestImageHeight,
+                           formatDesc.vkFormat, formatDesc.pixelWidth);
+  ASSERT(renderer.init(env, assetMgr), "Unable to initialize VkRenderer.");
+
   // Populate the buffer with well-defined data.
   AHardwareBuffer_describe(buffer, &hwbDesc);
   uint8_t *bufferAddr;
diff --git a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
index af5e943..99c4067 100644
--- a/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssNavigationMessageTest.java
@@ -42,6 +42,7 @@
     private static final String TAG = "GpsNavMsgTest";
     private static final int EVENTS_COUNT = 5;
     private TestGnssNavigationMessageListener mTestGnssNavigationMessageListener;
+    private TestLocationListener mLocationListener;
 
     @Override
     protected void setUp() throws Exception {
@@ -51,6 +52,10 @@
 
     @Override
     protected void tearDown() throws Exception {
+        // Unregister listeners
+        if (mLocationListener != null) {
+            mTestLocationManager.removeLocationUpdates(mLocationListener);
+        }
         // Unregister GnssNavigationMessageListener
         if (mTestGnssNavigationMessageListener != null) {
             mTestLocationManager
@@ -73,6 +78,9 @@
             return;
         }
 
+        mLocationListener = new TestLocationListener(EVENTS_COUNT);
+        mTestLocationManager.requestLocationUpdates(mLocationListener);
+
         // Register Gps Navigation Message Listener.
         mTestGnssNavigationMessageListener =
                 new TestGnssNavigationMessageListener(TAG, EVENTS_COUNT);
diff --git a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
index 20c9d3a..48faf49 100644
--- a/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/VpxCodecTestBase.java
@@ -367,24 +367,27 @@
 
     /**
      * Packs YUV420 frame by moving it to a smaller size buffer with stride and slice
-     * height equal to the original frame width and height.
+     * height equal to the crop window.
      */
-    private static byte[] PackYUV420(int width, int height,
+    private static byte[] PackYUV420(int left, int top, int width, int height,
             int stride, int sliceHeight, byte[] src) {
         byte[] dst = new byte[width * height * 3 / 2];
         // Y copy.
         for (int i = 0; i < height; i++) {
-            System.arraycopy(src, i * stride, dst, i * width, width);
+            System.arraycopy(src, (i + top) * stride + left, dst, i * width, width);
         }
         // U and V copy.
         int u_src_offset = stride * sliceHeight;
         int v_src_offset = u_src_offset + u_src_offset / 4;
         int u_dst_offset = width * height;
         int v_dst_offset = u_dst_offset + u_dst_offset / 4;
+        // Downsample and align to floor-2 for crop origin.
+        left /= 2;
+        top /= 2;
         for (int i = 0; i < height / 2; i++) {
-            System.arraycopy(src, u_src_offset + i * (stride / 2),
+            System.arraycopy(src, u_src_offset + (i + top) * (stride / 2) + left,
                     dst, u_dst_offset + i * (width / 2), width / 2);
-            System.arraycopy(src, v_src_offset + i * (stride / 2),
+            System.arraycopy(src, v_src_offset + (i + top) * (stride / 2) + left,
                     dst, v_dst_offset + i * (width / 2), width / 2);
         }
         return dst;
@@ -532,6 +535,10 @@
         int frameCount = ivf.getFrameCount();
         int frameStride = frameWidth;
         int frameSliceHeight = frameHeight;
+        int cropLeft = 0;
+        int cropTop = 0;
+        int cropWidth = frameWidth;
+        int cropHeight = frameHeight;
         assertTrue(frameWidth > 0);
         assertTrue(frameHeight > 0);
         assertTrue(frameCount > 0);
@@ -634,6 +641,28 @@
                             " x " + frameSliceHeight);
                     frameStride = Math.max(frameWidth, frameStride);
                     frameSliceHeight = Math.max(frameHeight, frameSliceHeight);
+
+                    // Parse crop window for the area of recording decoded frame data.
+                    if (format.containsKey("crop-left")) {
+                        cropLeft = format.getInteger("crop-left");
+                    }
+                    if (format.containsKey("crop-top")) {
+                        cropTop = format.getInteger("crop-top");
+                    }
+                    if (format.containsKey("crop-right")) {
+                        cropWidth = format.getInteger("crop-right") - cropLeft + 1;
+                    } else {
+                        cropWidth = frameWidth;
+                    }
+                    if (format.containsKey("crop-bottom")) {
+                        cropHeight = format.getInteger("crop-bottom") - cropTop + 1;
+                    } else {
+                        cropHeight = frameHeight;
+                    }
+                    Log.d(TAG, "Frame crop window origin: " + cropLeft + " x " + cropTop
+                            + ", size: " + cropWidth + " x " + cropHeight);
+                    cropWidth = Math.min(frameWidth - cropLeft, cropWidth);
+                    cropHeight = Math.min(frameHeight - cropTop, cropHeight);
                 }
                 result = decoder.dequeueOutputBuffer(bufferInfo, DEFAULT_DEQUEUE_TIMEOUT_US);
             }
@@ -660,11 +689,11 @@
                             frame = NV12ToYUV420(frameWidth, frameHeight,
                                     frameStride, frameSliceHeight, frame);
                         }
-                        int writeLength = Math.min(frameWidth * frameHeight * 3 / 2, frame.length);
+                        int writeLength = Math.min(cropWidth * cropHeight * 3 / 2, frame.length);
                         // Pack frame if necessary.
                         if (writeLength < frame.length &&
-                                (frameStride > frameWidth || frameSliceHeight > frameHeight)) {
-                            frame = PackYUV420(frameWidth, frameHeight,
+                                (frameStride > cropWidth || frameSliceHeight > cropHeight)) {
+                            frame = PackYUV420(cropLeft, cropTop, cropWidth, cropHeight,
                                     frameStride, frameSliceHeight, frame);
                         }
                         yuv.write(frame, 0, writeLength);
diff --git a/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java b/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java
index 3e9122b..45fd6d8 100644
--- a/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java
+++ b/tests/tests/multiuser/src/android/multiuser/cts/SplitSystemUserTest.java
@@ -20,27 +20,20 @@
 
 import android.os.UserManager;
 import android.test.InstrumentationTestCase;
-import android.util.Log;
 
 public class SplitSystemUserTest extends InstrumentationTestCase {
 
-    private static final String TAG = SplitSystemUserTest.class.getSimpleName();
-
     public void testSplitSystemUserIsDisabled() throws Exception {
-        // Verify that am get-current-user and UserManager.isSystemUser both return 0
-        String curUser = SystemUtil.runShellCommand(getInstrumentation(), "am get-current-user");
-        Log.i(TAG, "am get-current-user: " + curUser);
-        assertEquals("Test must be running under user 0", "0", trim(curUser));
-        UserManager um = getInstrumentation().getContext().getSystemService(UserManager.class);
-        assertTrue("Test must be running under system user", um.isSystemUser());
-
-        // Check that ro.fw.system_user_split property is not set
+        // Check that ro.fw.system_user_split property is not set.
         String splitEnabledStr = trim(SystemUtil.runShellCommand(getInstrumentation(),
                 "getprop ro.fw.system_user_split"));
         boolean splitEnabled = "y".equals(splitEnabledStr) || "yes".equals(splitEnabledStr)
                 || "1".equals(splitEnabledStr) || "true".equals(splitEnabledStr)
                 || "on".equals(splitEnabledStr);
         assertFalse("ro.fw.system_user_split must not be enabled", splitEnabled);
+
+        // Check UserManager.isSplitSystemUser returns false as well.
+        assertFalse("UserManager.isSplitSystemUser must be false", UserManager.isSplitSystemUser());
     }
 
     private static String trim(String s) {
diff --git a/tests/tests/permission2/Android.mk b/tests/tests/permission2/Android.mk
index e44cd14..c8b71c5 100755
--- a/tests/tests/permission2/Android.mk
+++ b/tests/tests/permission2/Android.mk
@@ -28,7 +28,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
 	compatibility-device-util \
-	ctstestrunner
+	ctstestrunner \
+	guava
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
index 585f9c6..517f451 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
@@ -16,27 +16,40 @@
 
 package android.permission2.cts;
 
-import com.android.compatibility.common.util.SystemUtil;
+import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
+import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
+
+import static com.google.common.collect.Maps.filterValues;
+import static com.google.common.collect.Sets.difference;
+import static com.google.common.collect.Sets.intersection;
+import static com.google.common.collect.Sets.newHashSet;
 
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionInfo;
 import android.support.test.InstrumentationRegistry;
 import android.test.AndroidTestCase;
+import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.compatibility.common.util.PropertyUtil;
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
-import static android.content.pm.PackageManager.GET_PERMISSIONS;
-import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
-
 /**
  * Tests enforcement of signature|privileged permission whitelist:
  * <ul>
@@ -65,8 +78,11 @@
         }
 
         List<PackageInfo> installedPackages = pm
-                .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES);
+                .getInstalledPackages(MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
+        installedPackages.sort(Comparator.comparing(p -> p.packageName));
 
+        Map<String, Set<String>> packagesGrantedNotInWhitelist = new HashMap<>();
+        Map<String, Set<String>> packagesNotGrantedNotRemovedNotInDenylist = new HashMap<>();
         for (PackageInfo pkg : installedPackages) {
             String packageName = pkg.packageName;
             if (!pkg.applicationInfo.isPrivilegedApp()
@@ -74,57 +90,116 @@
                 continue;
             }
 
-            Set<String> requestedPrivPermissions = new TreeSet<>();
-            Set<String> grantedPrivPermissions = new TreeSet<>();
-            PackageInfo factoryPackageInfo = pm
+            PackageInfo factoryPkg = pm
                     .getPackageInfo(packageName, MATCH_FACTORY_ONLY | GET_PERMISSIONS);
 
-            assertNotNull("No system image version found for " + packageName, factoryPackageInfo);
-            String[] requestedPermissions = factoryPackageInfo.requestedPermissions;
-            int[] requestedPermissionsFlags = factoryPackageInfo.requestedPermissionsFlags;
+            assertNotNull("No system image version found for " + packageName, factoryPkg);
 
-            if (requestedPermissions == null || requestedPermissions.length == 0) {
-                continue;
+            Set<String> factoryRequestedPrivPermissions;
+            if (factoryPkg.requestedPermissions == null) {
+                factoryRequestedPrivPermissions = Collections.emptySet();
+            } else {
+                factoryRequestedPrivPermissions = intersection(
+                        newHashSet(factoryPkg.requestedPermissions), platformPrivPermissions);
             }
-            // Collect 2 sets: requestedPermissions and grantedPrivPermissions
-            for (int i = 0; i < requestedPermissions.length; i++) {
-                String permission = requestedPermissions[i];
-                if (platformPrivPermissions.contains(permission)) {
-                    requestedPrivPermissions.add(permission);
-                    if ((requestedPermissionsFlags[i]
-                            & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
-                        grantedPrivPermissions.add(permission);
+
+            Map<String, Boolean> requestedPrivPermissions = new ArrayMap<>();
+            if (pkg.requestedPermissions != null) {
+                for (int i = 0; i < pkg.requestedPermissions.length; i++) {
+                    String permission = pkg.requestedPermissions[i];
+                    if (platformPrivPermissions.contains(permission)) {
+                        requestedPrivPermissions.put(permission,
+                                (pkg.requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
+                                        != 0);
                     }
                 }
             }
+
             // If an app is requesting any privileged permissions, log the details and verify
             // that granted permissions are whitelisted
-            if (!requestedPrivPermissions.isEmpty()) {
-                Set<String> notGranted = new TreeSet<>(requestedPrivPermissions);
-                notGranted.removeAll(grantedPrivPermissions);
+            if (!factoryRequestedPrivPermissions.isEmpty() && !requestedPrivPermissions.isEmpty()) {
+                Set<String> granted = filterValues(requestedPrivPermissions,
+                        isGranted -> isGranted).keySet();
+
+                Set<String> factoryNotGranted = difference(factoryRequestedPrivPermissions,
+                        granted);
+
+                // priv permissions that the system package requested, but the current package not
+                // anymore
+                Set<String> removed = difference(factoryRequestedPrivPermissions,
+                        requestedPrivPermissions.keySet());
+
                 Set<String> whitelist = getPrivAppPermissions(packageName);
                 Set<String> denylist = getPrivAppDenyPermissions(packageName);
-                Log.i(TAG, "Application " + packageName + "."
-                        + " Requested permissions: " + requestedPrivPermissions + "."
-                        + " Granted permissions: " + grantedPrivPermissions + "."
-                        + " Not granted: " + notGranted + "."
-                        + " Whitelisted: " + whitelist + "."
-                        + " Denylisted: " + denylist);
+                String msg = "Application " + packageName + "\n"
+                        + "  Factory requested permissions:\n"
+                        + getPrintableSet("    ", factoryRequestedPrivPermissions)
+                        + "  Granted:\n"
+                        + getPrintableSet("    ", granted)
+                        + "  Removed:\n"
+                        + getPrintableSet("    ", removed)
+                        + "  Whitelisted:\n"
+                        + getPrintableSet("    ", whitelist)
+                        + "  Denylisted:\n"
+                        + getPrintableSet("    ", denylist)
+                        + "  Factory not granted:\n"
+                        + getPrintableSet("    ", factoryNotGranted);
 
-                Set<String> grantedNotInWhitelist = new TreeSet<>(grantedPrivPermissions);
-                grantedNotInWhitelist.removeAll(whitelist);
-                Set<String> notGrantedNotInDenylist = new TreeSet<>(notGranted);
-                notGrantedNotInDenylist.removeAll(denylist);
+                for (String line : msg.split("\n")) {
+                    Log.i(TAG, line);
 
-                assertTrue("Not whitelisted permissions are granted for package "
-                                + packageName + ": " + grantedNotInWhitelist,
-                        grantedNotInWhitelist.isEmpty());
+                    // Prevent log from truncating output
+                    Thread.sleep(10);
+                }
 
-                assertTrue("Requested permissions not granted for package "
-                                + packageName + ": " + notGrantedNotInDenylist,
-                        notGrantedNotInDenylist.isEmpty());
+                Set<String> grantedNotInWhitelist = difference(granted, whitelist);
+                Set<String> factoryNotGrantedNotRemovedNotInDenylist = difference(difference(
+                        factoryNotGranted, removed), denylist);
+
+                if (!grantedNotInWhitelist.isEmpty()) {
+                    packagesGrantedNotInWhitelist.put(packageName, grantedNotInWhitelist);
+                }
+
+                if (!factoryNotGrantedNotRemovedNotInDenylist.isEmpty()) {
+                    packagesNotGrantedNotRemovedNotInDenylist.put(packageName,
+                            factoryNotGrantedNotRemovedNotInDenylist);
+                }
             }
         }
+        StringBuilder message = new StringBuilder();
+        if (!packagesGrantedNotInWhitelist.isEmpty()) {
+            message.append("Not whitelisted permissions are granted: "
+                    + packagesGrantedNotInWhitelist.toString());
+        }
+        if (!packagesNotGrantedNotRemovedNotInDenylist.isEmpty()) {
+            if (message.length() != 0) {
+                message.append(", ");
+            }
+            message.append("Requested permissions not granted: "
+                    + packagesNotGrantedNotRemovedNotInDenylist.toString());
+        }
+        if (!packagesGrantedNotInWhitelist.isEmpty()
+                || !packagesNotGrantedNotRemovedNotInDenylist.isEmpty()) {
+            fail(message.toString());
+        }
+    }
+
+    private <T> String getPrintableSet(String indendation, Set<T> set) {
+        if (set.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        for (T e : new TreeSet<>(set)) {
+            if (!TextUtils.isEmpty(e.toString().trim())) {
+                sb.append(indendation);
+                sb.append(e);
+                sb.append("\n");
+            }
+        }
+
+        return sb.toString();
     }
 
     private Set<String> getPrivAppPermissions(String packageName) throws IOException {
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
index 4ef28f4..30fdf24 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -26,6 +26,7 @@
 import android.net.Uri;
 import android.provider.BlockedNumberContract;
 import android.provider.BlockedNumberContract.BlockedNumbers;
+import android.telephony.TelephonyManager;
 
 import junit.framework.Assert;
 
@@ -69,6 +70,13 @@
     }
 
     public void testProviderInteractionsAsRegularApp_fails() {
+        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
+        // Don't run this test if we're carrier privileged.
+        if (telephonyManager.checkCarrierPrivilegesForPackage(mContext.getPackageName())
+                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            return;
+        }
+
         try {
             mAddedUris.add(mContentResolver.insert(
                     BlockedNumbers.CONTENT_URI, getContentValues("1234567890")));
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index c25c620..2c483d7 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -635,6 +635,7 @@
     public void testShowAtLocation() throws Throwable {
         int[] popupContentViewInWindowXY = new int[2];
         int[] popupContentViewOnScreenXY = new int[2];
+        Rect containingRect = new Rect();
 
         mPopupWindow = createPopupWindow(createPopupContent(CONTENT_SIZE_DP, CONTENT_SIZE_DP));
         // Do not attach within the decor; we will be measuring location
@@ -658,11 +659,12 @@
         assertTrue(mPopupWindow.isShowing());
         mPopupWindow.getContentView().getLocationInWindow(popupContentViewInWindowXY);
         mPopupWindow.getContentView().getLocationOnScreen(popupContentViewOnScreenXY);
+        upperAnchor.getWindowDisplayFrame(containingRect);
 
         assertTrue(popupContentViewInWindowXY[0] >= 0);
         assertTrue(popupContentViewInWindowXY[1] >= 0);
-        assertEquals(popupContentViewInWindowXY[0] + xOff, popupContentViewOnScreenXY[0]);
-        assertEquals(popupContentViewInWindowXY[1] + yOff, popupContentViewOnScreenXY[1]);
+        assertEquals(containingRect.left + popupContentViewInWindowXY[0] + xOff, popupContentViewOnScreenXY[0]);
+        assertEquals(containingRect.top + popupContentViewInWindowXY[1] + yOff, popupContentViewOnScreenXY[1]);
 
         dismissPopup();
     }
@@ -943,6 +945,7 @@
         int[] fstXY = new int[2];
         int[] sndXY = new int[2];
         int[] viewInWindowXY = new int[2];
+        Rect containingRect = new Rect();
         final Point popupPos = new Point();
 
         mActivityRule.runOnUiThread(() -> {
@@ -962,6 +965,7 @@
         showPopup();
         mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY);
         final View containerView = mActivity.findViewById(R.id.main_container);
+        containerView.getWindowDisplayFrame(containingRect);
 
         // update if it is not shown
         mActivityRule.runOnUiThread(() -> mPopupWindow.update(80, 80));
@@ -983,8 +987,8 @@
         assertEquals(50, mPopupWindow.getHeight());
 
         mPopupWindow.getContentView().getLocationOnScreen(fstXY);
-        assertEquals(popupPos.x + viewInWindowXY[0], fstXY[0]);
-        assertEquals(popupPos.y + viewInWindowXY[1], fstXY[1]);
+        assertEquals(containingRect.left + popupPos.x + viewInWindowXY[0], fstXY[0]);
+        assertEquals(containingRect.top + popupPos.y + viewInWindowXY[1], fstXY[1]);
 
         popupPos.set(windowInsets.getStableInsetLeft() + 4, windowInsets.getStableInsetTop());
 
@@ -998,8 +1002,8 @@
         assertEquals(50, mPopupWindow.getHeight());
 
         mPopupWindow.getContentView().getLocationOnScreen(sndXY);
-        assertEquals(popupPos.x + viewInWindowXY[0], sndXY[0]);
-        assertEquals(popupPos.y + viewInWindowXY[1], sndXY[1]);
+        assertEquals(containingRect.left + popupPos.x + viewInWindowXY[0], sndXY[0]);
+        assertEquals(containingRect.top + popupPos.y + viewInWindowXY[1], sndXY[1]);
 
         dismissPopup();
     }