Merge "Fix CTS transition tests for Android Wear devices." into stage-aosp-oc-cts-dev
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 107c19c..2dd5f23 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -96,10 +96,11 @@
 
 # Builds and launches CTS Verifier on a device.
 .PHONY: cts-verifier
-cts-verifier: CtsVerifier adb NotificationBot CtsPermissionApp
+cts-verifier: CtsVerifier adb NotificationBot CtsPermissionApp CtsEmptyDeviceAdmin
 	adb install -r $(PRODUCT_OUT)/data/app/CtsVerifier/CtsVerifier.apk \
 		&& adb install -r $(notification-bot) \
 		&& adb install -r $(permission-app) \
+		&& adb install -r $(empty-device-admin) \
 		&& adb shell "am start -n com.android.cts.verifier/.CtsVerifierActivity"
 
 #
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index df617d3..c684485 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -2497,15 +2497,6 @@
                 android:resource="@xml/filepaths" />
         </provider>
 
-        <provider
-            android:name="com.android.cts.verifier.admin.DeviceAdminUninstallTestActivity$DeviceAdminApkFileProvider"
-            android:authorities="com.android.cts.verifier.admin.fileprovider"
-            android:grantUriPermissions="true">
-            <meta-data
-                android:name="android.support.FILE_PROVIDER_PATHS"
-                android:resource="@xml/filepaths_admin" />
-        </provider>
-
         <activity android:name=".managedprovisioning.ByodIconSamplerActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_SAMPLE_ICON" />
diff --git a/apps/CtsVerifier/assets/apk/CtsEmptyDeviceAdmin.apk b/apps/CtsVerifier/assets/apk/CtsEmptyDeviceAdmin.apk
deleted file mode 100644
index d0ebbf4..0000000
--- a/apps/CtsVerifier/assets/apk/CtsEmptyDeviceAdmin.apk
+++ /dev/null
Binary files differ
diff --git a/apps/CtsVerifier/res/layout/da_uninstall_test_main.xml b/apps/CtsVerifier/res/layout/da_uninstall_test_main.xml
index 0415100..ff16ed5 100644
--- a/apps/CtsVerifier/res/layout/da_uninstall_test_main.xml
+++ b/apps/CtsVerifier/res/layout/da_uninstall_test_main.xml
@@ -46,18 +46,8 @@
                 android:layout_alignParentRight="true"
                 android:layout_alignParentTop="true"
                 android:layout_toRightOf="@id/install_admin_status"
+                android:layout_marginTop="10dip"
                 android:text="@string/da_install_admin_instructions" />
-
-            <Button
-                android:id="@+id/install_device_admin_button"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_below="@id/install_admin_instructions"
-                android:layout_marginLeft="20dip"
-                android:layout_marginRight="20dip"
-                android:layout_toRightOf="@id/install_admin_status"
-                android:text="@string/da_install_admin_button_text" />
         </RelativeLayout>
 
         <!-- Enable device admin -->
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index c43ac31..00638d9 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -77,7 +77,7 @@
     <string name="da_uninstall_test">Device Admin Uninstall Test</string>
     <string name="da_uninstall_test_info">This test checks that an active device administrator
         can be easily uninstalled from the application details screen in a way similar to other
-        apps.
+        apps. This test requires CtsEmptyDeviceAdmin.apk to be installed on the device.
     </string>
     <string name="da_tapjacking_test">Device Admin Tapjacking Test</string>
     <string name="da_tapjacking_test_info">This test checks that an activity cannot tapjack the
@@ -124,10 +124,10 @@
     <string name="da_lock_success">It appears the screen was locked successfully!</string>
     <string name="da_lock_error">It does not look like the screen was locked...</string>
 
-    <string name="da_install_admin_instructions">Please install the \'Test Device Admin\' app on the device.
-        If needed, grant \'Cts Verifier\' permission to install unknown apps, and return when install succeeds.
+    <string name="da_install_admin_instructions">
+        Please install the \'Test Device Admin\' app (packaged as CtsEmptyDeviceAdmin.apk) on the device.
     </string>
-    <string name="da_install_admin_button_text">Install admin</string>
+    <string name="da_admin_installed_status_text">\'Test Device Admin\' installed on the device.</string>
     <string name="da_enable_admin_instructions">Add \'Test Device Admin\' as an active administrator on the device.
         Tap the button below to review the device admin details and activate the administrator.
     </string>
diff --git a/apps/CtsVerifier/res/xml/filepaths_admin.xml b/apps/CtsVerifier/res/xml/filepaths_admin.xml
deleted file mode 100644
index 380431b..0000000
--- a/apps/CtsVerifier/res/xml/filepaths_admin.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<paths xmlns:android="http://schemas.android.com/apk/res/android">
-    <external-files-path path="apk/" name="apk" />
-</paths>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminUninstallTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminUninstallTestActivity.java
index 760a396..5dfe1f7 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminUninstallTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminUninstallTestActivity.java
@@ -17,28 +17,24 @@
 package com.android.cts.verifier.admin;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.support.v4.content.FileProvider;
-import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
 /**
  * Test that checks that active device admins can be easily uninstalled via the app details screen
  */
@@ -49,29 +45,34 @@
     private static final String ADMIN_PACKAGE_NAME = "com.android.cts.emptydeviceadmin";
     private static final String ADMIN_RECEIVER_CLASS_NAME =
             "com.android.cts.emptydeviceadmin.EmptyDeviceAdmin";
-    private static final String TEST_APK_ASSET_LOCATION = "apk/CtsEmptyDeviceAdmin.apk";
-    private static final String TEST_APK_FILES_LOCATION = "apk/CtsEmptyDeviceAdmin.apk";
     private static final String ADMIN_INSTALLED_BUNDLE_KEY = "admin_installed";
     private static final String ADMIN_ACTIVATED_BUNDLE_KEY = "admin_activated";
     private static final String ADMIN_REMOVED_BUNDLE_KEY = "admin_removed";
 
-    private static final int REQUEST_INSTALL_ADMIN = 0;
     private static final int REQUEST_ENABLE_ADMIN = 1;
     private static final int REQUEST_UNINSTALL_ADMIN = 2;
 
     private DevicePolicyManager mDevicePolicyManager;
 
-    private Button mInstallAdminButton;
     private ImageView mInstallStatus;
+    private TextView mInstallAdminText;
     private Button mAddDeviceAdminButton;
     private ImageView mEnableStatus;
     private Button mUninstallAdminButton;
     private ImageView mUninstallStatus;
-    private File mApkFile;
     private boolean mAdminInstalled;
     private boolean mAdminActivated;
     private boolean mAdminRemoved;
     private ComponentName mAdmin;
+    private final BroadcastReceiver mPackageAddedListener = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final Uri uri = intent.getData();
+            if (uri != null && ADMIN_PACKAGE_NAME.equals(uri.getSchemeSpecificPart())) {
+                onAdminPackageInstalled();
+            }
+        }
+    };
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -79,13 +80,9 @@
         setContentView(R.layout.da_uninstall_test_main);
         setInfoResources(R.string.da_uninstall_test, R.string.da_uninstall_test_info, -1);
         setPassFailButtonClickListeners();
-
         mAdmin = new ComponentName(ADMIN_PACKAGE_NAME, ADMIN_RECEIVER_CLASS_NAME);
         mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
 
-        mApkFile = new File(getExternalFilesDir(null), TEST_APK_FILES_LOCATION);
-        copyApkToFile(mApkFile);
-
         if (savedInstanceState != null) {
             mAdminInstalled = savedInstanceState.getBoolean(ADMIN_INSTALLED_BUNDLE_KEY, false);
             mAdminActivated = savedInstanceState.getBoolean(ADMIN_ACTIVATED_BUNDLE_KEY, false);
@@ -94,36 +91,27 @@
             mAdminInstalled = isPackageInstalled(ADMIN_PACKAGE_NAME);
             mAdminActivated = mDevicePolicyManager.isAdminActive(mAdmin);
         }
+        mInstallStatus = findViewById(R.id.install_admin_status);
+        mInstallAdminText = findViewById(R.id.install_admin_instructions);
+        if (!mAdminInstalled) {
+            final IntentFilter packageAddedFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+            packageAddedFilter.addDataScheme("package");
+            registerReceiver(mPackageAddedListener, packageAddedFilter);
+        }
 
-        mInstallStatus = (ImageView) findViewById(R.id.install_admin_status);
-        mInstallAdminButton = (Button) findViewById(R.id.install_device_admin_button);
-        mInstallAdminButton.setOnClickListener(this);
-
-        mEnableStatus = (ImageView) findViewById(R.id.enable_admin_status);
-        mAddDeviceAdminButton = (Button) findViewById(R.id.enable_device_admin_button);
+        mEnableStatus = findViewById(R.id.enable_admin_status);
+        mAddDeviceAdminButton = findViewById(R.id.enable_device_admin_button);
         mAddDeviceAdminButton.setOnClickListener(this);
 
-        mUninstallStatus = (ImageView) findViewById(R.id.uninstall_admin_status);
-        mUninstallAdminButton = (Button) findViewById(R.id.open_app_details_button);
+        mUninstallStatus = findViewById(R.id.uninstall_admin_status);
+        mUninstallAdminButton = findViewById(R.id.open_app_details_button);
         mUninstallAdminButton.setOnClickListener(this);
     }
 
-
-    private void copyApkToFile(File destFile) {
-        destFile.getParentFile().mkdirs();
-        try (FileOutputStream out = new FileOutputStream(destFile);
-             InputStream in = getAssets().open(TEST_APK_ASSET_LOCATION,
-                     AssetManager.ACCESS_BUFFER)) {
-            byte[] buffer = new byte[4096];
-            int bytesRead;
-            while ((bytesRead = in.read(buffer)) >= 0) {
-                out.write(buffer, 0, bytesRead);
-            }
-            out.flush();
-            Log.d(TAG, "successfully copied apk to " + destFile.getAbsolutePath());
-        } catch (IOException exc) {
-            Log.e(TAG, "Exception while copying device admin apk", exc);
-        }
+    private void onAdminPackageInstalled() {
+        mAdminInstalled = true;
+        updateWidgets();
+        unregisterReceiver(mPackageAddedListener);
     }
 
     private boolean isPackageInstalled(String packageName) {
@@ -138,14 +126,7 @@
 
     @Override
     public void onClick(View v) {
-        if (v == mInstallAdminButton) {
-            Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
-            intent.setData(DeviceAdminApkFileProvider.getUriForFile(this,
-                    DeviceAdminApkFileProvider.CONTENT_AUTHORITY, mApkFile));
-            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-            intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
-            startActivityForResult(intent, REQUEST_INSTALL_ADMIN);
-        } else if (v == mAddDeviceAdminButton) {
+        if (v == mAddDeviceAdminButton) {
             Intent securitySettingsIntent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
             securitySettingsIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdmin);
             startActivityForResult(securitySettingsIntent, REQUEST_ENABLE_ADMIN);
@@ -158,13 +139,10 @@
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_INSTALL_ADMIN) {
-            mAdminInstalled = resultCode == RESULT_OK;
-        } else if (requestCode == REQUEST_ENABLE_ADMIN) {
+        if (requestCode == REQUEST_ENABLE_ADMIN) {
             mAdminActivated = mDevicePolicyManager.isAdminActive(mAdmin);
         } else if (requestCode == REQUEST_UNINSTALL_ADMIN) {
-            mAdminRemoved = !mDevicePolicyManager.isAdminActive(mAdmin) && !isPackageInstalled(
-                    ADMIN_PACKAGE_NAME);
+            mAdminRemoved = !isPackageInstalled(ADMIN_PACKAGE_NAME);
         }
     }
 
@@ -182,11 +160,11 @@
     }
 
     private void updateWidgets() {
-        mInstallAdminButton.setEnabled(mApkFile.exists() && !mAdminInstalled);
         mInstallStatus.setImageResource(
                 mAdminInstalled ? R.drawable.fs_good : R.drawable.fs_indeterminate);
+        mInstallAdminText.setText(mAdminInstalled ? R.string.da_admin_installed_status_text
+                : R.string.da_install_admin_instructions);
         mInstallStatus.invalidate();
-
         mAddDeviceAdminButton.setEnabled(mAdminInstalled && !mAdminActivated);
         mEnableStatus.setImageResource(
                 mAdminActivated ? R.drawable.fs_good : R.drawable.fs_indeterminate);
@@ -199,8 +177,4 @@
 
         getPassButton().setEnabled(mAdminRemoved);
     }
-
-    public static class DeviceAdminApkFileProvider extends FileProvider {
-        static final String CONTENT_AUTHORITY = "com.android.cts.verifier.admin.fileprovider";
-    }
 }
diff --git a/apps/EmptyDeviceAdmin/AndroidManifest.xml b/apps/EmptyDeviceAdmin/AndroidManifest.xml
index 1b4cd0f..2ee9422 100644
--- a/apps/EmptyDeviceAdmin/AndroidManifest.xml
+++ b/apps/EmptyDeviceAdmin/AndroidManifest.xml
@@ -17,7 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.cts.emptydeviceadmin" >
 
-    <uses-sdk android:minSdkVersion="23"/>
+    <uses-sdk android:minSdkVersion="12"/>
 
     <application android:label="Test Device Admin">
         <receiver
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
index 62b7af9..e065ce8 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/CompatibilityTestSuite.java
@@ -18,7 +18,6 @@
 import com.android.compatibility.SuiteInfo;
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.compatibility.common.tradefed.testtype.ISubPlan;
-import com.android.compatibility.common.tradefed.testtype.ModuleRepo;
 import com.android.compatibility.common.tradefed.testtype.SubPlan;
 import com.android.compatibility.common.util.TestFilter;
 import com.android.tradefed.build.IBuildInfo;
@@ -250,7 +249,7 @@
             }
         }
         if (mModuleName != null) {
-            List<String> modules = ModuleRepo.getModuleNamesMatching(
+            List<String> modules = ModuleRepoSuite.getModuleNamesMatching(
                     mBuildHelper.getTestsDir(), mModuleName);
             if (modules.size() == 0) {
                 throw new IllegalArgumentException(
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/ModuleRepoSuite.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/ModuleRepoSuite.java
index 2e5d712..a889330 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/ModuleRepoSuite.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/suite/ModuleRepoSuite.java
@@ -217,6 +217,33 @@
         return true;
     }
 
+    /**
+     * @return the {@link List} of modules whose name contains the given pattern.
+     */
+    public static List<String> getModuleNamesMatching(File directory, String pattern) {
+        String[] names = directory.list(new FilenameFilter(){
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.contains(pattern) && name.endsWith(CONFIG_EXT);
+            }
+        });
+        List<String> modules = new ArrayList<String>(names.length);
+        for (String name : names) {
+            int index = name.indexOf(CONFIG_EXT);
+            if (index > 0) {
+                String module = name.substring(0, index);
+                if (module.equals(pattern)) {
+                    // Pattern represents a single module, just return a single-item list
+                    modules = new ArrayList<>(1);
+                    modules.add(module);
+                    return modules;
+                }
+                modules.add(module);
+            }
+        }
+        return modules;
+    }
+
     private void addFilters(Set<String> stringFilters,
             Map<String, List<TestFilter>> filters, Set<IAbi> abis) {
         for (String filterString : stringFilters) {
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsJobDurationTests.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsJobDurationTests.java
index ea2b8d4..fb90b2e 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsJobDurationTests.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/BatteryStatsJobDurationTests.java
@@ -39,7 +39,7 @@
     private static final ComponentName JOB_COMPONENT_NAME =
             new ComponentName("com.android.server.cts.device.batterystats",
                     SimpleJobService.class.getName());
-    public static final String TAG = "BatteryStatsJobDurationTests";
+    public static final String TAG = "BatteryStatsJobDurTests";
 
     private JobInfo createJobInfo(int id) {
         JobInfo.Builder builder = new JobInfo.Builder(id, JOB_COMPONENT_NAME);
@@ -52,10 +52,11 @@
         JobScheduler js = mContext.getSystemService(JobScheduler.class);
         assertTrue("JobScheduler service not available", js != null);
         final JobInfo job = createJobInfo(1);
-        long startTime = System.currentTimeMillis();
         for (int i = 0; i < 3; i++) {
             CountDownLatch latch = SimpleJobService.resetCountDownLatch();
+            Log.i(TAG, "Scheduling job.");
             js.schedule(job);
+            Log.i(TAG, "Waiting for job to finish.");
             if (!latch.await(5, TimeUnit.SECONDS)) {
                 Log.e(TAG, "Job didn't finish in 5 seconds");
                 fail("Job didn't finish in 5 seconds");
diff --git a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleJobService.java b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleJobService.java
index c1d259b..cd9fdaf 100644
--- a/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleJobService.java
+++ b/hostsidetests/incident/apps/batterystatsapp/src/com/android/server/cts/device/batterystats/SimpleJobService.java
@@ -52,6 +52,7 @@
             if (sLatch != null) {
                 sLatch.countDown();
             }
+            Log.i(TAG, "Finished job.");
         }
     };
 
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
index c31aec8..f7580e7 100755
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
@@ -242,7 +242,10 @@
                   android:exported="true"
                   android:theme="@style/TranslucentTheme"
         />
+        <!-- An animation test with an explicitly opaque theme, overriding device defaults, as the
+             animation background being tested is not used in translucent activities. -->
         <activity android:name=".AnimationTestActivity"
+                  android:theme="@style/OpaqueTheme"
                   android:exported="true"
         />
         <activity android:name=".VirtualDisplayActivity"
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/res/values/styles.xml b/hostsidetests/services/activityandwindowmanager/activitymanager/app/res/values/styles.xml
index 5068ea9..6e2a820 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/app/res/values/styles.xml
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/res/values/styles.xml
@@ -37,6 +37,11 @@
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowDisablePreview">true</item>
     </style>
+    <style name="OpaqueTheme">
+        <item name="android:windowIsTranslucent">false</item>
+        <item name="android:windowSwipeToDismiss">false</item>
+        <item name="android:windowIsFloating">false</item>
+    </style>
     <style name="NoPreview">
         <item name="android:windowDisablePreview">true</item>
     </style>
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
index 55b41c8..bdf46cf 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
@@ -1015,6 +1015,8 @@
 
     /** Test that reported display size corresponds to fullscreen after exiting PiP. */
     public void testDisplayMetricsPinUnpin() throws Exception {
+        if (!supportsPip()) return;
+
         String logSeparator = clearLogcat();
         launchActivity(TEST_ACTIVITY);
         final int defaultDisplayStackId = mAmWmState.getAmState().getFocusedStackId();
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/SplashscreenTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/SplashscreenTests.java
index 62704fb..ed7f383 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/SplashscreenTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/SplashscreenTests.java
@@ -31,30 +31,49 @@
         mAmWmState.waitForAppTransitionIdle(mDevice);
         mAmWmState.getWmState().getStableBounds();
         final BufferedImage image = takeScreenshot();
-        assertAllColor(image, mAmWmState.getWmState().getStableBounds(), Color.RED.getRGB());
+
+        // Use ratios to flexibly accomodate circular or not quite rectangular displays
+        // Note: Color.BLACK is the pixel color outside of the display region
+        assertColors(image, mAmWmState.getWmState().getStableBounds(),
+            Color.RED.getRGB(), 0.50f, Color.BLACK.getRGB(), 0.01f);
     }
 
-    private void assertAllColor(BufferedImage img, Rectangle bounds, int expectedColor) {
-        int correctPixels = 0;
+    private void assertColors(BufferedImage img, Rectangle bounds, int primaryColor,
+        float expectedPrimaryRatio, int secondaryColor, float acceptableWrongRatio) {
+
+        int primaryPixels = 0;
+        int secondaryPixels = 0;
         int wrongPixels = 0;
         for (int x = bounds.x; x < bounds.x + bounds.width; x++) {
             for (int y = bounds.y; y < bounds.y + bounds.height; y++) {
                 assertTrue(x < img.getWidth());
                 assertTrue(y < img.getHeight());
                 final int color = img.getRGB(x, y);
-                if (expectedColor == color) {
-                    correctPixels++;
+                if (primaryColor == color) {
+                    primaryPixels++;
+                } else if (secondaryColor == color) {
+                    secondaryPixels++;
                 } else {
                     wrongPixels++;
                 }
             }
         }
 
+        final int totalPixels = bounds.width * bounds.height;
+        final float primaryRatio = (float) primaryPixels / totalPixels;
+        if (primaryRatio < expectedPrimaryRatio) {
+            fail("Less than " + (expectedPrimaryRatio * 100.0f)
+                    + "% of pixels have non-primary color primaryPixels=" + primaryPixels
+                    + " secondaryPixels=" + secondaryPixels + " wrongPixels=" + wrongPixels);
+        }
+
         // Some pixels might be covered by screen shape decorations, like rounded corners.
-        final float ratio = (float) wrongPixels / (correctPixels + wrongPixels);
-        if (ratio > 0.01f) {
-            fail("More than 1% of pixels have wrong color correctPixels=" + correctPixels
-                    + " wrongPixels=" + wrongPixels);
+        // On circular displays, there is an antialiased edge.
+        final float wrongRatio = (float) wrongPixels / totalPixels;
+        if (wrongRatio > acceptableWrongRatio) {
+            fail("More than " + (acceptableWrongRatio * 100.0f)
+                    + "% of pixels have wrong color primaryPixels=" + primaryPixels
+                    + " secondaryPixels=" + secondaryPixels + " wrongPixels=" + wrongPixels);
         }
     }
 }
diff --git a/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java b/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
index 1fcb8b8..f5e68f6 100644
--- a/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
+++ b/tests/tests/location/src/android/location/cts/GnssPseudorangeVerificationTest.java
@@ -251,11 +251,11 @@
     int eventCount = events.size();
     Log.i(TAG, "Number of Gps Event received = " + eventCount);
     int gnssYearOfHardware = mTestLocationManager.getLocationManager().getGnssYearOfHardware();
-    if (eventCount == 0 && gnssYearOfHardware <= MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED) {
+    if (eventCount == 0 && gnssYearOfHardware < MIN_HARDWARE_YEAR_MEASUREMENTS_REQUIRED) {
       return;
     }
 
-    Log.i(TAG, "This is a device from 2017 or later.");
+    Log.i(TAG, "This is a device from 2016 or later.");
     assertTrue("GnssMeasurementEvent count: expected > 0, received = " + eventCount,
         eventCount > 0);
 
diff --git a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
index d5bd393..1b8c3c3 100644
--- a/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
+++ b/tests/tests/location/src/android/location/cts/TestGnssMeasurementListener.java
@@ -16,6 +16,7 @@
 package android.location.cts;
 
 import junit.framework.Assert;
+import android.location.GnssClock;
 import android.location.GnssMeasurement;
 import android.location.GnssMeasurementsEvent;
 import android.util.Log;
@@ -82,10 +83,16 @@
     public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) {
         // Only count measurement events with more than 4 actual Measurements in same constellation
         // with Cn0DbHz value greater than 18
-        if (event.getMeasurements().size() > 0) { 
+        if (event.getMeasurements().size() > 0) {
             Log.i(mTag, "GnssMeasurementsEvent size:" + event.getMeasurements().size());
             if (filterByEventSize) {
                 HashMap<Integer, Integer> constellationEventCount = new HashMap<>();
+                GnssClock gnssClock = event.getClock();
+                if (!gnssClock.hasFullBiasNanos()) {
+                    // If devices does not have FullBiasNanos yet, it will be difficult to check the quality, so await 
+                    // this flag as well.
+                    return;
+                }
                 for (GnssMeasurement gnssMeasurement : event.getMeasurements()){
                     int constellationType = gnssMeasurement.getConstellationType();
                     // if the measurement's signal level is too small ignore
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index 010d992..72838e5 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -264,13 +264,10 @@
             public int getHeight() {
                 return super.getHeight() + OFFSET;
             }
+
             @Override
-            public int getMaxHeight() {
-                return super.getHeight() * 2 + OFFSET;
-            }
-            @Override
-            public int getMaxWidth() {
-                return super.getWidth() * 2 + OFFSET;
+            public boolean isAbrEnabled() {
+                return true;
             }
         };
     }
@@ -281,13 +278,10 @@
             public int getWidth() {
                 return super.getWidth() + OFFSET;
             }
+
             @Override
-            public int getMaxHeight() {
-                return super.getHeight() * 2 + OFFSET;
-            }
-            @Override
-            public int getMaxWidth() {
-                return super.getWidth() * 2 + OFFSET;
+            public boolean isAbrEnabled() {
+                return true;
             }
         };
     }
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
index 0e92e3d..58f1607 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTestBase.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertNotNull;
 
 import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.MediaUtils;
 
 import android.annotation.TargetApi;
 import android.annotation.SuppressLint;
@@ -38,6 +39,7 @@
 import android.media.MediaCodec;
 import android.media.MediaCodec.BufferInfo;
 import android.media.MediaCodec.CodecException;
+import android.media.MediaCodecInfo.VideoCapabilities;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -480,10 +482,27 @@
             if (ApiLevelUtil.isBefore(Build.VERSION_CODES.KITKAT)) {
                 return;
             }
-            if (videoFormat.getMaxWidth() != VideoFormat.INT_UNSET
-                && videoFormat.getMaxHeight() != VideoFormat.INT_UNSET) {
-                mediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, videoFormat.getMaxWidth());
-                mediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, videoFormat.getMaxHeight());
+            // Set KEY_MAX_WIDTH and KEY_MAX_HEIGHT when isAbrEnabled() is set.
+            if (videoFormat.isAbrEnabled()) {
+                try {
+                    // Check for max resolution supported by the codec.
+                    final MediaCodec decoder = MediaUtils.getDecoder(mediaFormat);
+                    final VideoCapabilities videoCapabilities = MediaUtils.getVideoCapabilities(
+                            decoder.getName(), videoFormat.getMimeType());
+                    decoder.release();
+                    final int maxWidth = videoCapabilities.getSupportedWidths().getUpper();
+                    final int maxHeight =
+                            videoCapabilities.getSupportedHeightsFor(maxWidth).getUpper();
+                    if (maxWidth >= videoFormat.getWidth() && maxHeight >= videoFormat.getHeight()) {
+                        mediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, maxWidth);
+                        mediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, maxHeight);
+                        return;
+                    }
+                } catch (NullPointerException exception) { /* */ }
+                // Set max width/height to current size if can't get codec's max supported
+                // width/height or max is not greater than the current size.
+                mediaFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, videoFormat.getWidth());
+                mediaFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, videoFormat.getHeight());
             }
         }
 
@@ -1591,6 +1610,10 @@
         return getParsedName().getHeight();
     }
 
+    public boolean isAbrEnabled() {
+        return false;
+    }
+
     public String getOriginalSize() {
         if (width == INT_UNSET || height == INT_UNSET) {
             return getParsedName().getSize();
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 2a67b64..d18890f 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -18,6 +18,7 @@
 
 import android.media.cts.R;
 
+import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.media.MediaDataSource;
@@ -30,6 +31,7 @@
 
 import com.android.compatibility.common.util.MediaUtils;
 
+import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.media.MediaMetadataRetriever.OPTION_CLOSEST;
 import static android.media.MediaMetadataRetriever.OPTION_CLOSEST_SYNC;
 import static android.media.MediaMetadataRetriever.OPTION_NEXT_SYNC;
@@ -45,12 +47,14 @@
 
     protected Resources mResources;
     protected MediaMetadataRetriever mRetriever;
+    private PackageManager mPackageManager;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mResources = getContext().getResources();
         mRetriever = new MediaMetadataRetriever();
+        mPackageManager = getContext().getPackageManager();
     }
 
     @Override
@@ -293,6 +297,12 @@
 
     private void testGetFrameAtTime(int option, int[][] testCases) {
         int resId = R.raw.binary_counter_320x240_30fps_600frames;
+        if (!MediaUtils.hasCodecForResourceAndDomain(getContext(), resId, "video/")
+            && mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            MediaUtils.skipTest("no video codecs for resource on watch");
+            return;
+        }
+
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         Resources resources = getContext().getResources();
         AssetFileDescriptor afd = resources.openRawResourceFd(resId);
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
index bb8ca13..e817233 100755
--- a/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/adminpackageinstaller/AndroidManifest.xml
@@ -33,7 +33,7 @@
         </receiver>
 
         <activity android:name=".LauncherActivity">
-            <intent-filter>
+            <intent-filter android:priority="-999">
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.HOME" />
diff --git a/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java b/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
index 8a4b980..17f97fe 100644
--- a/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
+++ b/tests/tests/packageinstaller/adminpackageinstaller/src/android/packageinstaller/admin/cts/SessionCommitBroadcastTest.java
@@ -49,7 +49,7 @@
         mThisAppLauncher = new ComponentName(mContext, LauncherActivity.class);
     }
 
-    public void testBroadcastReceivedForDifferentLauncher() throws Exception {
+    public void testBroadcastNotReceivedForDifferentLauncher() throws Exception {
         if (!mHasFeature) {
             return;
         }
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index b97d109..c639251 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -323,6 +323,9 @@
     @MediumTest
     public void testProcSelfPagemapSane() throws ErrnoException, IOException {
         FileDescriptor pagemap = null;
+        int dumpable = Os.prctl(OsConstants.PR_GET_DUMPABLE, 0, 0, 0, 0);
+        Os.prctl(OsConstants.PR_SET_DUMPABLE, 1, 0, 0, 0);
+
         try {
             pagemap = Os.open("/proc/self/pagemap", OsConstants.O_RDONLY, 0);
 
@@ -339,6 +342,7 @@
         } finally {
             if (pagemap != null)
                 Os.close(pagemap);
+            Os.prctl(OsConstants.PR_SET_DUMPABLE, dumpable, 0, 0, 0);
         }
     }
 
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index 66b3399..92573d8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -18,7 +18,9 @@
 
 import android.graphics.Bitmap;
 import android.os.Message;
+import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.view.MotionEvent;
 import android.view.ViewGroup;
 import android.webkit.JsPromptResult;
 import android.webkit.JsResult;
@@ -203,6 +205,7 @@
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
         }
+
         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
         mOnUiThread.setWebChromeClient(webChromeClient);
 
@@ -213,6 +216,10 @@
         assertFalse(webChromeClient.hadOnJsBeforeUnload());
 
         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.JS_UNLOAD_URL));
+
+        // Send a user gesture, required for unload to execute since WebView version 60.
+        tapWebView();
+
         // unload should trigger when we try to navigate away
         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
 
@@ -308,6 +315,28 @@
         assertEquals(webChromeClient.getMessage(), "testOnJsPrompt");
     }
 
+    /**
+     * Taps in the the center of a webview.
+     */
+    private void tapWebView() {
+        int[] location = mOnUiThread.getLocationOnScreen();
+        int middleX = location[0] + mOnUiThread.getWebView().getWidth() / 2;
+        int middleY = location[1] + mOnUiThread.getWebView().getHeight() / 2;
+
+        long timeDown = SystemClock.uptimeMillis();
+        getInstrumentation().sendPointerSync(
+                MotionEvent.obtain(timeDown, timeDown, MotionEvent.ACTION_DOWN,
+                        middleX, middleY, 0));
+
+        long timeUp = SystemClock.uptimeMillis();
+        getInstrumentation().sendPointerSync(
+                MotionEvent.obtain(timeUp, timeUp, MotionEvent.ACTION_UP,
+                        middleX, middleY, 0));
+
+        // Wait for the system to process all events in the queue
+        getInstrumentation().waitForIdleSync();
+    }
+
     private class MockWebChromeClient extends WaitForProgressClient {
         private boolean mHadOnProgressChanged;
         private boolean mHadOnReceivedTitle;