Merge "Test more transforms and more socket types."
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 19f957a..0ba93cd 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1750,7 +1750,9 @@
         This test verifies keystore cryptographic keys can be bound to device lockscreen challenge or fingerprints (if available).
         These keys should only be available if there was a recent enough authentication. \n
 
-        1. Press "Set up" to open Security settings. Create a lockscreen password and if available, enroll a fingerprint under "Work profile security".\n
+        1. Press "Set up" to open Security settings. (If this device has a separate app for work
+        settings, ignore this button and open that app manually from the launcher.) Create a
+        lockscreen password and if available, enroll a fingerprint under "Work profile security".\n
         2. Go through the list of tests.\n
         3. Mark the overall test pass or fail.\n
         4. Once the set of tests are completed, remove the lockscreen challenge.
@@ -2147,20 +2149,26 @@
     <string name="provisioning_byod_disallow_apps_control_prepare_button">Prepare test</string>
     <string name="provisioning_byod_disabled_uninstall_button">Disabled uninstall button</string>
     <string name="provisioning_byod_disabled_uninstall_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing either \"Uninstall\" or \"Disable\" is not possible and triggers a support message when trying to do so.
-        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+        Please press the Go button to go to Settings > Apps.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
+        Choose a managed app. Check that performing either \"Uninstall\" or \"Disable\" is not possible and triggers a support message when trying to do so.
+        Then please press Back (or navigate back to this app using Recents) and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_force_stop_button">Disabled force stop button</string>
     <string name="provisioning_byod_disabled_force_stop_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing \"Force stop\" is not possible and triggers a support message when trying to do so.
-        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+        Please press the Go button to go to Settings > Apps.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
+        Choose a managed app. Check that performing \"Force stop\" is not possible and triggers a support message when trying to do so.
+        Then please press Back (or navigate back to this app using Recents) and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_app_storage_buttons">Disabled app storage buttons</string>
     <string name="provisioning_byod_disabled_app_storage_buttons_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed (badged) app. Select \"Storage\". Check that performing \"Clear Data\" and \"Clear Cache\" is not possible and triggers a support message when trying to do so.
+        Please press the Go button to go to Settings > Apps.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
+        Choose a managed (badged) app. Select \"Storage\". Check that performing \"Clear Data\" and \"Clear Cache\" is not possible and triggers a support message when trying to do so.
         Note: if an app has no data then tapping the clear data button has no effect anyway. Make sure you have selected
         the badged version of app with non-zero app data. Badged \"Settings\" may be a good candidate.
-        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+        Then please press Back (or navigate back to this app using Recents) and mark the test as \"Pass\" or \"Fail\".
     </string>
 
     <string name="provisioning_byod_work_status_icon">Work status icon is displayed</string>
@@ -2191,6 +2199,7 @@
     </string>
     <string name="provisioning_byod_profile_visible_instruction">
         Please press the Go button to open the Settings page.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
         Navigate to Accounts and confirm that:\n
         \n
         - Both Personal and Work categories exist.\n
@@ -2200,17 +2209,18 @@
         - There are two auto-sync options present, one for personal and one for work data (either on the screen or in the overflow menu).\n
         - De-selecting either option prompts a warning dialog.\n
         \n
-        Use the Back button to return to this page.
+        Use the Back button (or navigate back to this app using Recents) to return to this page.
     </string>
     <string name="provisioning_byod_admin_visible_instruction">
         Please press the Go button to open the Security page in Settings.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
         Navigate to Device admin apps and confirm that:\n
         \n
         - Device administrators outside of the work profile (if any) appear in the list, and the managed profile administrators are badged correctly.\n
         - A badged \"CTS Verifier\" exists, and is activated.\n
         - There is no option to deactivate the badged \"CTS Verifier\" version, only an option to \"Remove work profile\".\n
         \n
-        Use the Back button to return to this page.
+        Use the Back button (or navigate back to this app using Recents) to return to this page.
     </string>
     <string name="provisioning_byod_workapps_visible_instruction">
         Please press the Go button to start the launcher.
@@ -2224,33 +2234,36 @@
 
     <string name="provisioning_byod_app_settings">Profile-aware app settings</string>
     <string name="provisioning_byod_app_settings_instruction">
-        Please press the Go button to open Apps page in settings.\n
+        Please press the Go button to open Apps page in settings.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
         \n
         Verify that work profile exists in the dropdown list and selecting it will
         bring up apps setting in the work profile.\n
         \n
-        Then use the Back button to return to this test and mark accordingly.
+        Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
     </string>
 
     <string name="provisioning_byod_location_settings">Profile-aware location settings</string>
     <string name="provisioning_byod_location_settings_instruction">
-        Please press the Go button to open Location page in settings.\n
+        Please press the Go button to open Location page in settings.
+        (If this device has a separate app for work settings, ignore the Go button and navigate to that app manually).\n
         \n
         Verify that work profile entry exists in the page and it has a toggleable switch.\n
         Switch the main location switch at the top of the screen off. You should see the work profile location switch go disabled and into \'off\' state.\n
         Then switch the main location switch on again. You should see the work profile location switch go enabled and into its previous state.\n
         \n
-        Then use the Back button to return to this test and mark accordingly.
+        Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
     </string>
 
     <string name="provisioning_byod_wifi_data_usage_settings">Profile-aware data usage settings (Wi-Fi)</string>
     <string name="provisioning_byod_wifi_data_usage_settings_instruction">
-        Please press the Go button to open the Settings page.\n
+        Please press the Go button to open the Settings page.
+        (If this device has a separate app for work settings, ignore the Go button and navigate to that app manually).\n
         \n
         Navigate to \"Data usage\" page and then into the \"Wi-Fi data usage\" category.\n
         Confirm that \"All work apps\" section is present and that it is possible to see the data usage for work (badged) apps.\n
         \n
-        Then use the Back button to return to this test and mark accordingly.
+        Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
     </string>
 
     <string name="provisioning_byod_cellular_data_usage_settings">Profile-aware data usage settings (Mobile)</string>
@@ -2259,12 +2272,13 @@
         Please make sure you have added a SIM card with data plan to your phone, have enabled data over mobile and in case of dual SIM devices, have selected the right SIM for data connection.\n
         Please carry out operations that will use mobile data using both badged and unbadged apps (e.g. visit a page in a browser).\n
         \n
-        Please press the Go button to open the Settings page.\n
+        Please press the Go button to open the Settings page.
+        (If this device has a separate app for work settings, ignore the Go button and navigate to that app manually).\n
         \n
         Navigate to \"Data usage\" page and then into the \"Mobile data usage\" category.\n
         Confirm that \"All work apps\" section is present and that it is possible to see the data usage for work (badged) apps.\n
         \n
-        Then use the Back button to return to this test and mark accordingly.
+        Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
     </string>
 
     <string name="provisioning_byod_cred_settings">Profile-aware trusted credential settings</string>
@@ -2281,11 +2295,12 @@
     <string name="provisioning_byod_print_settings">Profile-aware printing settings</string>
     <string name="provisioning_byod_print_settings_instruction">
         Please press the Go button to open the Printing settings.
+        (If this device has a separate app for work settings, ignore the Go button and open that app manually from the launcher).\n
         \n
         Verify that work profile exists in the dropdown list and selecting it will
         bring up printing setting in the work profile.\n
         \n
-        Then use the Back button to return to this test and mark accordingly.
+        Then use the Back button (or navigate back to this app using Recents) to return to this test and mark accordingly.
     </string>
 
     <string name="provisioning_byod_cross_profile_intent_filters">Cross profile intent filters are set</string>
@@ -2362,7 +2377,8 @@
     <string name="provisioning_byod_turn_off_work_instructions">
         This test verifies the device behavior when work profile is turned off.\n
         Please exercise the following tests in sequence.\n
-        The button below can be used to open the Settings page where you can toggle work mode.
+        The button below can be used to open the Settings page where you can toggle work mode.\n
+        (If this device has a separate app for work settings, ignore the button and open that app manually from the launcher).\n
     </string>
     <string name="provisioning_byod_turn_off_work_prepare_button">Open Settings to toggle work mode</string>
 
@@ -2397,7 +2413,7 @@
     </string>
 
     <string name="provisioning_byod_turn_off_work_turned_on">Please turn work mode back on</string>
-    <string name="provisioning_byod_turn_off_work_turned_on_toast">Open settings to turn work mode back on, using the button above.</string>
+    <string name="provisioning_byod_turn_off_work_turned_on_toast">Open settings to turn work mode back on, either manually or using the button above.</string>
 
     <string name="provisioning_byod_turn_on_work_icon">Status bar icon when work mode is on</string>
     <string name="provisioning_byod_turn_on_work_icon_instruction">
@@ -2824,7 +2840,7 @@
     <string name="dummy_accessibility_service_label">Dummy accessibility service</string>
     <string name="policy_transparency_test_instructions">
         1. <xliff:g id="set_step" example="Set policy by turning the switch on">%1$s</xliff:g>\n
-        2. Open Settings app by clicking the "Open settings" button below.\n
+        2. Open Settings app by clicking the "Open settings" button below. (If this device has a separate app for work settings, ignore the button and open that app manually from the launcher)\n
         3. Verify that performing the following action will trigger a support dialog:\n
            <xliff:g id="user_action" example="Adding an account">%2$s</xliff:g>.\n
         4. Verify that the support dialog displays the short support message set earlier.\n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index 476eb80..123bdb4f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -87,12 +87,18 @@
                 new Intent("com.android.settings.ACCESSIBILITY_COLOR_SPACE_SETTINGS"),
                 new Intent("com.android.settings.TTS_SETTINGS"),
                 new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS),
-                new Intent(Settings.ACTION_SYNC_SETTINGS),
-                new Intent(Settings.ACTION_ADD_ACCOUNT),
                 new Intent(Intent.ACTION_GET_CONTENT).setType("*/*").addCategory(
                         Intent.CATEGORY_OPENABLE),
                 new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*").addCategory(
-                        Intent.CATEGORY_OPENABLE),
+                        Intent.CATEGORY_OPENABLE)
+            ));
+
+    // These are the intents which can either be handled directly in the managed profile,
+    // or be forwarded to the primary profile.
+    private static final ArrayList<Intent> forwardingOptionalIntentsFromManaged =
+            new ArrayList<>(Arrays.asList(
+                new Intent(Settings.ACTION_SYNC_SETTINGS),
+                new Intent(Settings.ACTION_ADD_ACCOUNT),
                 new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
                 new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
                 new Intent(Settings.ACTION_APPLICATION_SETTINGS)
@@ -227,7 +233,7 @@
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_LOCATION)) {
-            forwardedIntentsFromManaged.add(
+            forwardingOptionalIntentsFromManaged.add(
                     new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
         }
 
@@ -276,9 +282,11 @@
     public boolean checkCrossProfileIntentFilters(int flag) {
         boolean crossProfileIntentFiltersSet;
         if (flag == FLAG_INTENTS_FROM_PRIMARY) {
-            crossProfileIntentFiltersSet = checkForIntentsFromPrimary();
+            crossProfileIntentFiltersSet = checkIntentForwardingFromPrimary();
         } else {
-            crossProfileIntentFiltersSet = checkForIntentsFromManaged();
+            crossProfileIntentFiltersSet =
+                    checkIntentForwardingFromManaged() &&
+                            checkIntentsWithOptionalForwardingFromManagedAreHandled();
         }
         return crossProfileIntentFiltersSet;
     }
@@ -287,7 +295,7 @@
      * Checks if required cross profile intent filters are set for the intents fired from the
      * primary profile.
      */
-    private boolean checkForIntentsFromPrimary() {
+    private boolean checkIntentForwardingFromPrimary() {
         // Get the class name of the intentForwarderActivity in the primary profile by firing an
         // intent which we know will be forwarded from primary profile to managed profile.
         ActivityInfo forwarderActivityInfo =
@@ -297,16 +305,36 @@
         }
 
         // Check for intents which can be forwarded to the managed profile.
-        return checkForIntentsNotHandled(forwardedIntentsFromPrimary,
+        return checkIntentForwarding(forwardedIntentsFromPrimary,
                 forwarderActivityInfo, "from primary profile should be forwarded to the " +
                 "managed profile but is not.", true);
     }
 
     /**
+     * Checks that the required intents either have cross profile intent filters set up, or are
+     * handled directly in the managed profile.
+     */
+    private boolean checkIntentsWithOptionalForwardingFromManagedAreHandled() {
+        for (Intent intent : forwardingOptionalIntentsFromManaged) {
+            List<ResolveInfo> resolveInfoList =
+                    mContext.getPackageManager().queryIntentActivities(intent,
+                            PackageManager.MATCH_DEFAULT_ONLY);
+
+            if (resolveInfoList.isEmpty()) {
+                Log.e(TAG, intent + " should be handled in or forwarded from the managed " +
+                        "profile, but it is not.");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
      * Checks if required cross profile intent filters are set for the intents fired from the
      * managed profile.
      */
-    private boolean checkForIntentsFromManaged() {
+    private boolean checkIntentForwardingFromManaged() {
         // Get the class name of the intentForwarderActivity in the managed profile by firing an
         // intent which we know will be forwarded from managed profile to primary profile.
         ActivityInfo forwarderActivityInfo =
@@ -317,12 +345,12 @@
 
         boolean success = true;
         // Check for intents which can be forwarded to the primary profile.
-        success &= checkForIntentsNotHandled(forwardedIntentsFromManaged,
+        success &= checkIntentForwarding(forwardedIntentsFromManaged,
                 forwarderActivityInfo, " from managed profile should be forwarded to the " +
                 "primary profile but is not.", true);
 
         // Check for intents which cannot be forwarded to the primary profile.
-        success &= checkForIntentsNotHandled(notForwardedIntentsFromManaged,
+        success &= checkIntentForwarding(notForwardedIntentsFromManaged,
                 forwarderActivityInfo, "from managed profile should not be forwarded to the " +
                 "primary profile but it is.", false);
         return success;
@@ -367,7 +395,7 @@
      * Checks if the intents passed are correctly handled.
      * @return {@code false} if at least one intent is not handled correctly.
      */
-    private boolean checkForIntentsNotHandled(ArrayList<Intent> intentList,
+    private boolean checkIntentForwarding(ArrayList<Intent> intentList,
             ActivityInfo expectedForwarderActivityInfo, String errorMessage, boolean canResolve) {
         boolean success = true;
         for (Intent intent : intentList) {
diff --git a/build/device_info_package.mk b/build/device_info_package.mk
index d9d08e8..5c290b0 100644
--- a/build/device_info_package.mk
+++ b/build/device_info_package.mk
@@ -18,6 +18,7 @@
 
 DEVICE_INFO_PACKAGE := com.android.compatibility.common.deviceinfo
 DEVICE_INFO_INSTRUMENT := android.support.test.runner.AndroidJUnitRunner
+DEVICE_INFO_USES_LIBRARY := android.test.runner
 DEVICE_INFO_PERMISSIONS += android.permission.WRITE_EXTERNAL_STORAGE
 DEVICE_INFO_ACTIVITIES += \
   $(DEVICE_INFO_PACKAGE).ConfigurationDeviceInfo \
@@ -55,6 +56,7 @@
 manifest_xml := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/AndroidManifest.xml
 $(manifest_xml): PRIVATE_INFO_PERMISSIONS := $(foreach permission, $(DEVICE_INFO_PERMISSIONS),-r $(permission))
 $(manifest_xml): PRIVATE_INFO_ACTIVITIES := $(foreach activity,$(DEVICE_INFO_ACTIVITIES),-a $(activity))
+$(manifest_xml): PRIVATE_USES_LIBRARY := $(DEVICE_INFO_USES_LIBRARY)
 $(manifest_xml): PRIVATE_PACKAGE := $(DEVICE_INFO_PACKAGE)
 $(manifest_xml): PRIVATE_INSTRUMENT := $(DEVICE_INFO_INSTRUMENT)
 $(manifest_xml): PRIVATE_MIN_SDK := $(DEVICE_INFO_MIN_SDK)
@@ -67,6 +69,7 @@
 	$(hide) $(MANIFEST_GENERATOR) \
 						$(PRIVATE_INFO_PERMISSIONS) \
 						$(PRIVATE_INFO_ACTIVITIES) \
+						-l $(PRIVATE_USES_LIBRARY) \
 						-p $(PRIVATE_PACKAGE) \
 						-i $(PRIVATE_INSTRUMENT) \
 						-s $(PRIVATE_MIN_SDK) \
diff --git a/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java b/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
index 7241ada..6e48ca9 100644
--- a/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
+++ b/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
@@ -36,6 +36,7 @@
     private static final String APPLICATION = "application";
     private static final String INSTRUMENTATION = "instrumentation";
     private static final String ACTIVITY = "activity";
+    private static final String USES_LIBRARY = "uses-library";
 
     public static void main(String[] args) {
         String pkgName = null;
@@ -44,6 +45,7 @@
         String targetSdk = null;
         List<String> permissions = new ArrayList<>();
         List<String> activities = new ArrayList<>();
+        List<String> libraries = new ArrayList<>();
         String output = null;
 
         for (int i = 0; i < args.length - 1; i++) {
@@ -51,6 +53,8 @@
                 pkgName = args[++i];
             } else if (args[i].equals("-a")) {
                 activities.add(args[++i]);
+            } else if (args[i].equals("-l")) {
+                libraries.add(args[++i]);
             } else if (args[i].equals("-o")) {
                 output = args[++i];
             } else if (args[i].equals("-i")) {
@@ -77,7 +81,8 @@
         FileOutputStream out = null;
         try {
           out = new FileOutputStream(output);
-          generate(out, pkgName, instrumentName, minSdk, targetSdk, permissions, activities);
+          generate(out, pkgName, instrumentName, minSdk, targetSdk, permissions, activities,
+                libraries);
         } catch (Exception e) {
           System.err.println("Couldn't create manifest file");
         } finally {
@@ -92,7 +97,8 @@
     }
 
     /*package*/ static void generate(OutputStream out, String pkgName, String instrumentName,
-            String minSdk, String targetSdk, List<String> permissions, List<String> activities)
+            String minSdk, String targetSdk, List<String> permissions, List<String> activities,
+            List<String> libraries)
             throws Exception {
         final String ns = null;
         KXmlSerializer serializer = new KXmlSerializer();
@@ -114,6 +120,11 @@
             serializer.endTag(ns, USES_PERMISSION);
         }
         serializer.startTag(ns, APPLICATION);
+        for (String library : libraries) {
+            serializer.startTag(ns, USES_LIBRARY);
+            serializer.attribute(ns, "android:name", library);
+            serializer.endTag(ns, USES_LIBRARY);
+        }
         for (String activity : activities) {
             serializer.startTag(ns, ACTIVITY);
             serializer.attribute(ns, "android:name", activity);
diff --git a/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java b/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
index a0565e1..aed5926 100644
--- a/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
+++ b/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
@@ -38,6 +38,7 @@
         + "%s"
         + "  <application>\r\n"
         + "%s"
+        + "%s"
         + "  </application>\r\n"
         + "  <instrumentation android:name=\"test.package.TestInstrument\" "
         + "android:targetPackage=\"test.package\" />\r\n"
@@ -48,6 +49,8 @@
     private static final String ACTIVITY = "    <activity android:name=\"%s\" />\r\n";
     private static final String ACTIVITY_A = "test.package.ActivityA";
     private static final String ACTIVITY_B = "test.package.ActivityB";
+    private static final String USES_LIBRARY = "    <uses-library android:name=\"%s\" />\r\n";
+    private static final String LIBRARY = "test.runner.library";
 
     public void testManifest() throws Exception {
         List<String> permissions = new ArrayList<>();
@@ -56,6 +59,8 @@
         List<String> activities = new ArrayList<>();
         activities.add(ACTIVITY_A);
         activities.add(ACTIVITY_B);
+        List<String> libraries = new ArrayList<>();
+        libraries.add(LIBRARY);
         OutputStream output = new OutputStream() {
             private StringBuilder string = new StringBuilder();
             @Override
@@ -69,12 +74,13 @@
             }
         };
         ManifestGenerator.generate(output, PACKAGE, INSTRUMENT, MIN_SDK, TARGET_SDK,
-            permissions, activities);
+            permissions, activities, libraries);
         String permissionXml = String.format(PERMISSION, PERMISSION_A)
                 + String.format(PERMISSION, PERMISSION_B);
         String activityXml = String.format(ACTIVITY, ACTIVITY_A)
                 + String.format(ACTIVITY, ACTIVITY_B);
-        String expected = String.format(MANIFEST, permissionXml, activityXml);
+        String libraryXml = String.format(USES_LIBRARY, LIBRARY);
+        String expected = String.format(MANIFEST, permissionXml, libraryXml, activityXml);
         assertEquals("Wrong manifest output", expected, output.toString());
     }
 
diff --git a/hostsidetests/content/test-apps/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java b/hostsidetests/content/test-apps/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
index 785711b..5aa4709 100644
--- a/hostsidetests/content/test-apps/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
+++ b/hostsidetests/content/test-apps/CtsSyncAccountAccessOtherCertTests/src/com/android/cts/content/CtsSyncAccountAccessOtherCertTestCases.java
@@ -27,6 +27,7 @@
 import android.content.SyncResult;
 import android.content.cts.FlakyTestRule;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.os.Bundle;
@@ -36,7 +37,9 @@
 import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
+import android.util.Log;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -61,6 +64,7 @@
     private static final long SYNC_TIMEOUT_MILLIS = 20000; // 20 sec
     private static final long UI_TIMEOUT_MILLIS = 5000; // 5 sec
 
+    private static final String PERMISSION_REQUESTED = "Permission Requested";
     public static final String TOKEN_TYPE_REMOVE_ACCOUNTS = "TOKEN_TYPE_REMOVE_ACCOUNTS";
 
     @Rule
@@ -118,12 +122,17 @@
             assertFalse(latch.await(SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
 
             UiDevice uiDevice = getUiDevice();
+            if (isWatch()) {
+                UiObject2 notification = findPermissionNotificationInStream(uiDevice);
+                notification.click();
+            } else {
+                uiDevice.openNotification();
+                uiDevice.wait(Until.hasObject(By.text(PERMISSION_REQUESTED)),
+                        UI_TIMEOUT_MILLIS);
 
-            uiDevice.openNotification();
-            uiDevice.wait(Until.hasObject(By.text("Permission requested")),
-                    UI_TIMEOUT_MILLIS);
+                uiDevice.findObject(By.text(PERMISSION_REQUESTED)).click();
+            }
 
-            uiDevice.findObject(By.text("Permission requested")).click();
             uiDevice.wait(Until.hasObject(By.text("ALLOW")),
                     UI_TIMEOUT_MILLIS);
 
@@ -136,9 +145,44 @@
             // Ask the differently signed authenticator to drop all accounts
             accountManager.getAuthToken(addedAccount, TOKEN_TYPE_REMOVE_ACCOUNTS,
                     null, false, null, null);
+            activity.finish();
         }
     }
 
+    private UiObject2 findPermissionNotificationInStream(UiDevice uiDevice) {
+        uiDevice.pressHome();
+        swipeUp(uiDevice);
+        if (uiDevice.hasObject(By.text(PERMISSION_REQUESTED))) {
+          return uiDevice.findObject(By.text(PERMISSION_REQUESTED));
+        }
+        for (int i = 0; i < 100; i++) {
+          if (!swipeUp(uiDevice)) {
+            // We have reached the end of the stream and not found the target.
+            break;
+          }
+          if (uiDevice.hasObject(By.text(PERMISSION_REQUESTED))) {
+            return uiDevice.findObject(By.text(PERMISSION_REQUESTED));
+          }
+        }
+        return null;
+    }
+
+    private boolean swipeUp(UiDevice uiDevice) {
+        int width = uiDevice.getDisplayWidth();
+        int height = uiDevice.getDisplayHeight();
+        return uiDevice.swipe(
+            width / 2 /* startX */,
+            height - 1 /* startY */,
+            width / 2 /* endX */,
+            1 /* endY */,
+            50 /* numberOfSteps */);
+    }
+
+    private boolean isWatch() {
+        return (getContext().getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
+    }
+
     private Context getContext() {
         return InstrumentationRegistry.getInstrumentation().getContext();
     }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
index dcf0ce7..6b62e88 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
@@ -25,11 +25,16 @@
 import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 
+import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
 import java.net.HttpURLConnection;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
 import java.net.URL;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -48,8 +53,6 @@
             "google.pl"
     };
 
-    private static final int MAX_VISITING_WEBPAGES_ITERATIONS = 100; // >1500 events
-    // note: make sure URL_LIST has at least 10 urls in it to generate enough network traffic
     private static final String[] LOGGED_URLS_LIST = {
             "example.com",
             "example.net",
@@ -141,15 +144,14 @@
 
         // TODO: here test that facts about logging are shown in the UI
 
-        // visit websites in a loop to generate enough network traffic
-        int iterationsDone = 0;
-        while (mGenerateNetworkTraffic && iterationsDone < MAX_VISITING_WEBPAGES_ITERATIONS) {
-            for (final String url : LOGGED_URLS_LIST) {
-                connectToWebsite(url);
-            }
-            iterationsDone++;
+        // visit websites to verify their dns lookups are logged
+        for (final String url : LOGGED_URLS_LIST) {
+            connectToWebsite(url);
         }
 
+        // generate enough traffic to fill a batch.
+        int dummyReqNo = generateDummyTraffic();
+
         // if DeviceAdminReceiver#onNetworkLogsAvailable() hasn't been triggered yet, wait for up to
         // 3 minutes just in case
         mCountDownLatch.await(3, TimeUnit.MINUTES);
@@ -166,15 +168,20 @@
             fail("Failed to retrieve batch of network logs with batch token " + mCurrentBatchToken);
             return;
         }
-        verifyNetworkLogs(networkEvents, iterationsDone);
+
+        // For each of the real URLs we have two events: one DNS and one connect. Dummy requests
+        // don't require DNS queries.
+        int eventsExpected =
+                Math.min(FULL_LOG_BATCH_SIZE, 2 * LOGGED_URLS_LIST.length + dummyReqNo);
+        verifyNetworkLogs(networkEvents, eventsExpected);
     }
 
-    private void verifyNetworkLogs(List<NetworkEvent> networkEvents, int iterationsDone) {
+    private void verifyNetworkLogs(List<NetworkEvent> networkEvents, int eventsExpected) {
         assertTrue(networkEvents.size() == FULL_LOG_BATCH_SIZE);
         int ctsPackageNameCounter = 0;
-        // allow a small down margin for verification, to avoid flakyness
-        final int iterationsDoneWithMargin = iterationsDone - 5;
-        final int[] visitedFrequencies = new int[LOGGED_URLS_LIST.length];
+        // allow a small down margin for verification, to avoid flakiness
+        final int eventsExpectedWithMargin = eventsExpected - 50;
+        final boolean[] visited = new boolean[LOGGED_URLS_LIST.length];
 
         for (int i = 0; i < networkEvents.size(); i++) {
             final NetworkEvent currentEvent = networkEvents.get(i);
@@ -196,7 +203,7 @@
                     // count the frequencies of LOGGED_URLS_LIST's hostnames that were looked up
                     for (int j = 0; j < LOGGED_URLS_LIST.length; j++) {
                         if (dnsEvent.getHostname().contains(LOGGED_URLS_LIST[j])) {
-                            visitedFrequencies[j]++;
+                            visited[j] = true;
                             break;
                         }
                     }
@@ -223,25 +230,24 @@
             }
         }
 
-        // verify that each hostname from LOGGED_URLS_LIST was looked-up enough times
+        // verify that each hostname from LOGGED_URLS_LIST was looked-up
         for (int i = 0; i < 10; i++) {
-            // to avoid flakyness account for DNS caching and connection errors
-            assertTrue(visitedFrequencies[i] >= (iterationsDoneWithMargin / 2));
+            assertTrue(LOGGED_URLS_LIST[i] + " wasn't visited", visited[i]);
         }
         // verify that sufficient iterations done by the CTS app were logged
-        assertTrue(ctsPackageNameCounter >= LOGGED_URLS_LIST.length * iterationsDoneWithMargin);
+        assertTrue(ctsPackageNameCounter >= eventsExpectedWithMargin);
     }
 
-    private void connectToWebsite(String urlString) {
+    private void connectToWebsite(String server) {
         HttpURLConnection urlConnection = null;
         try {
-            final URL url = new URL("http://" + urlString);
+            final URL url = new URL("http://" + server);
             urlConnection = (HttpURLConnection) url.openConnection();
             urlConnection.setConnectTimeout(2000);
             urlConnection.setReadTimeout(2000);
             urlConnection.getResponseCode();
         } catch (IOException e) {
-            Log.w(TAG, "Failed to connect to " + urlString, e);
+            Log.w(TAG, "Failed to connect to " + server, e);
         } finally {
             if (urlConnection != null) {
                 urlConnection.disconnect();
@@ -249,6 +255,70 @@
         }
     }
 
+    /** Quickly generate loads of events by repeatedly connecting to a local server. */
+    private int generateDummyTraffic() throws IOException, InterruptedException {
+        ServerSocket serverSocket = new ServerSocket(0);
+        Thread serverThread = startDummyServer(serverSocket);
+
+        int reqNo = makeDummyRequests(serverSocket.getLocalPort());
+
+        serverSocket.close();
+        serverThread.join();
+
+        return reqNo;
+    }
+
+    private int makeDummyRequests(int port) {
+        int reqNo;
+        final String DUMMY_SERVER = "127.0.0.1:" + port + "";
+        for (reqNo = 0; reqNo < FULL_LOG_BATCH_SIZE && mGenerateNetworkTraffic; reqNo++) {
+            connectToWebsite(DUMMY_SERVER);
+            try {
+                // Just to prevent choking the server.
+                Thread.sleep(10);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }
+        return reqNo;
+    }
+
+    private Thread startDummyServer(ServerSocket serverSocket) throws InterruptedException {
+        Thread serverThread = new Thread(() -> {
+            while (true) {
+                try {
+                    Socket socket = serverSocket.accept();
+                    // Consume input.
+                    BufferedReader input =
+                            new BufferedReader(new InputStreamReader(socket.getInputStream()));
+                    String line;
+                    do {
+                        line = input.readLine();
+                    } while (line != null && !line.equals(""));
+                    // Return minimum valid response.
+                    PrintStream output = new PrintStream(socket.getOutputStream());
+                    output.println("HTTP/1.0 200 OK");
+                    output.println("Content-Length: 0");
+                    output.println();
+                    output.flush();
+                    output.close();
+                } catch (IOException e) {
+                    if (mGenerateNetworkTraffic) {
+                        Log.w(TAG, "Failed to serve connection", e);
+                    } else {
+                        break;
+                    }
+                }
+            }
+        });
+        serverThread.start();
+
+        // Allow the server to start accepting.
+        Thread.sleep(1_000);
+
+        return serverThread;
+    }
+
     private boolean isIpv4OrIpv6Address(InetAddress addr) {
         return ((addr instanceof Inet4Address) || (addr instanceof Inet6Address));
     }
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
index 05065aa..4222159 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
@@ -83,8 +83,8 @@
         if (!isHandheld()) {
             return;
         }
-        launchActivity("ShowWhenLockedActivity");
         gotoKeyguard();
+        launchActivity("ShowWhenLockedActivity");
         launchActivity("TestActivity");
         mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
         mAmWmState.computeState(mDevice, null);
diff --git a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
index d4ed6be..edcb201 100644
--- a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
@@ -605,7 +605,7 @@
 
     protected void sleepDevice() throws DeviceNotAvailableException {
         int retriesLeft = 5;
-        runCommandAndPrintOutput("input keyevent 26");
+        runCommandAndPrintOutput("input keyevent SLEEP");
         do {
             if (isDisplayOn()) {
                 log("***Waiting for display to turn off...");
@@ -627,7 +627,7 @@
     }
 
     protected void wakeUpDevice() throws DeviceNotAvailableException {
-        runCommandAndPrintOutput("input keyevent 224");
+        runCommandAndPrintOutput("input keyevent WAKEUP");
     }
 
     protected void unlockDevice() throws DeviceNotAvailableException {
@@ -652,9 +652,10 @@
         runCommandAndPrintOutput("input keyevent KEYCODE_ENTER");
     }
 
-    protected void gotoKeyguard() throws DeviceNotAvailableException {
+    protected void gotoKeyguard() throws Exception {
         sleepDevice();
         wakeUpDevice();
+        mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
     }
 
     protected void setLockCredential() throws DeviceNotAvailableException {
diff --git a/hostsidetests/theme/assets/26/xxhdpi.zip b/hostsidetests/theme/assets/26/xxhdpi.zip
index 6e018fa..55a943b 100644
--- a/hostsidetests/theme/assets/26/xxhdpi.zip
+++ b/hostsidetests/theme/assets/26/xxhdpi.zip
Binary files differ
diff --git a/libs/commonutil/src/com/android/cts/util/SecurityTest.java b/libs/commonutil/src/com/android/cts/util/SecurityTest.java
new file mode 100644
index 0000000..cc1d08f
--- /dev/null
+++ b/libs/commonutil/src/com/android/cts/util/SecurityTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+package com.android.cts.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks the type of test with purpose of evaluating security vulnerabilities.
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface SecurityTest {
+
+}
diff --git a/tests/tests/bionic/Android.build.copy.libs.mk b/tests/tests/bionic/Android.build.copy.libs.mk
index a5d2704..adce804 100644
--- a/tests/tests/bionic/Android.build.copy.libs.mk
+++ b/tests/tests/bionic/Android.build.copy.libs.mk
@@ -17,66 +17,72 @@
   dt_runpath_b_c_x/libtest_dt_runpath_c.so \
   dt_runpath_b_c_x/libtest_dt_runpath_x.so \
   inaccessible_libs/libtestshared.so \
+  inaccessible_libs/libtestshared.so \
+  ld_config_test_helper/ld_config_test_helper \
+  ld_config_test_helper_lib3.so \
+  ld_preload_test_helper/ld_preload_test_helper \
+  ld_preload_test_helper_lib1.so \
+  ld_preload_test_helper_lib2.so \
   libatest_simple_zip/libatest_simple_zip.so \
-  libcfi-test.so \
   libcfi-test-bad.so \
+  libcfi-test.so \
+  libdl_preempt_test_1.so \
+  libdl_preempt_test_2.so \
+  libdl_test_df_1_global.so \
+  libdlext_test.so \
   libdlext_test_different_soname.so \
   libdlext_test_fd/libdlext_test_fd.so \
   libdlext_test_norelro.so \
   libdlext_test_runpath_zip/libdlext_test_runpath_zip_zipaligned.zip \
-  libdlext_test.so \
   libdlext_test_zip/libdlext_test_zip.so \
   libdlext_test_zip/libdlext_test_zip_zipaligned.zip \
-  libdl_preempt_test_1.so \
-  libdl_preempt_test_2.so \
-  libdl_test_df_1_global.so \
   libsysv-hash-table-library.so \
   libtest_atexit.so \
+  libtest_check_order_dlsym.so \
   libtest_check_order_dlsym_1_left.so \
   libtest_check_order_dlsym_2_right.so \
   libtest_check_order_dlsym_3_c.so \
   libtest_check_order_dlsym_a.so \
   libtest_check_order_dlsym_b.so \
   libtest_check_order_dlsym_d.so \
-  libtest_check_order_dlsym.so \
+  libtest_check_order_reloc_root.so \
   libtest_check_order_reloc_root_1.so \
   libtest_check_order_reloc_root_2.so \
-  libtest_check_order_reloc_root.so \
+  libtest_check_order_reloc_siblings.so \
   libtest_check_order_reloc_siblings_1.so \
   libtest_check_order_reloc_siblings_2.so \
   libtest_check_order_reloc_siblings_3.so \
   libtest_check_order_reloc_siblings_a.so \
   libtest_check_order_reloc_siblings_b.so \
+  libtest_check_order_reloc_siblings_c.so \
   libtest_check_order_reloc_siblings_c_1.so \
   libtest_check_order_reloc_siblings_c_2.so \
-  libtest_check_order_reloc_siblings_c.so \
   libtest_check_order_reloc_siblings_d.so \
   libtest_check_order_reloc_siblings_e.so \
   libtest_check_order_reloc_siblings_f.so \
-  libtest_check_order_reloc_siblings.so \
   libtest_check_rtld_next_from_library.so \
   libtest_dlopen_df_1_global.so \
   libtest_dlopen_from_ctor.so \
   libtest_dlopen_from_ctor_main.so \
   libtest_dlopen_weak_undefined_func.so \
   libtest_dlsym_df_1_global.so \
+  libtest_dlsym_from_this.so \
   libtest_dlsym_from_this_child.so \
   libtest_dlsym_from_this_grandchild.so \
-  libtest_dlsym_from_this.so \
   libtest_dlsym_weak_func.so \
   libtest_dt_runpath_d.so \
   libtest_empty.so \
   libtest_init_fini_order_child.so \
   libtest_init_fini_order_grand_child.so \
-  libtest_init_fini_order_root2.so \
   libtest_init_fini_order_root.so \
+  libtest_init_fini_order_root2.so \
   libtest_nodelete_1.so \
   libtest_nodelete_2.so \
   libtest_nodelete_dt_flags_1.so \
   libtest_pthread_atfork.so \
+  libtest_relo_check_dt_needed_order.so \
   libtest_relo_check_dt_needed_order_1.so \
   libtest_relo_check_dt_needed_order_2.so \
-  libtest_relo_check_dt_needed_order.so \
   libtest_simple.so \
   libtest_two_parents_child.so \
   libtest_two_parents_parent1.so \
@@ -84,43 +90,38 @@
   libtest_versioned_lib.so \
   libtest_versioned_libv1.so \
   libtest_versioned_libv2.so \
-  libtest_versioned_otherlib_empty.so \
   libtest_versioned_otherlib.so \
+  libtest_versioned_otherlib_empty.so \
   libtest_versioned_uselibv1.so \
-  libtest_versioned_uselibv2_other.so \
   libtest_versioned_uselibv2.so \
+  libtest_versioned_uselibv2_other.so \
   libtest_versioned_uselibv3_other.so \
+  libtest_with_dependency.so \
+  libtest_with_dependency_loop.so \
   libtest_with_dependency_loop_a.so \
   libtest_with_dependency_loop_b.so \
   libtest_with_dependency_loop_b_tmp.so \
   libtest_with_dependency_loop_c.so \
-  libtest_with_dependency_loop.so \
-  libtest_with_dependency.so \
+  ns2/ld_config_test_helper_lib1.so \
+  ns2/ld_config_test_helper_lib2.so \
   prebuilt-elf-files/libtest_invalid-empty_shdr_table.so \
   prebuilt-elf-files/libtest_invalid-rw_load_segment.so \
+  prebuilt-elf-files/libtest_invalid-textrels.so \
+  prebuilt-elf-files/libtest_invalid-textrels2.so \
   prebuilt-elf-files/libtest_invalid-unaligned_shdr_offset.so \
   prebuilt-elf-files/libtest_invalid-zero_shdr_table_content.so \
   prebuilt-elf-files/libtest_invalid-zero_shdr_table_offset.so \
   prebuilt-elf-files/libtest_invalid-zero_shentsize.so \
   prebuilt-elf-files/libtest_invalid-zero_shstrndx.so \
-  prebuilt-elf-files/libtest_invalid-textrels.so \
-  prebuilt-elf-files/libtest_invalid-textrels2.so \
   preinit_getauxval_test_helper/preinit_getauxval_test_helper \
   preinit_syscall_test_helper/preinit_syscall_test_helper \
-  private_namespace_libs_external/libnstest_private_external.so \
   private_namespace_libs/libnstest_dlopened.so \
   private_namespace_libs/libnstest_private.so \
-  private_namespace_libs/libnstest_root_not_isolated.so \
   private_namespace_libs/libnstest_root.so \
+  private_namespace_libs/libnstest_root_not_isolated.so \
+  private_namespace_libs_external/libnstest_private_external.so \
   public_namespace_libs/libnstest_public.so \
   public_namespace_libs/libnstest_public_internal.so \
-  ld_preload_test_helper/ld_preload_test_helper \
-  ld_preload_test_helper_lib1.so \
-  ld_preload_test_helper_lib2.so \
-  ld_config_test_helper/ld_config_test_helper \
-  ns2/ld_config_test_helper_lib1.so \
-  ns2/ld_config_test_helper_lib2.so \
-  ld_config_test_helper_lib3.so \
 
 # These libraries are not built for mips.
 my_bionic_testlib_files_non_mips := \
diff --git a/tests/tests/jni/Android.mk b/tests/tests/jni/Android.mk
index 38111fc..6a6c33e 100644
--- a/tests/tests/jni/Android.mk
+++ b/tests/tests/jni/Android.mk
@@ -33,6 +33,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
 
 LOCAL_JNI_SHARED_LIBRARIES := \
+  libjni_test_dlclose \
   libjninamespacea1 \
   libjninamespacea2 \
   libjninamespaceb \
diff --git a/tests/tests/jni/libjnitest/Android.mk b/tests/tests/jni/libjnitest/Android.mk
index bf8c21a..f9ab5df 100644
--- a/tests/tests/jni/libjnitest/Android.mk
+++ b/tests/tests/jni/libjnitest/Android.mk
@@ -26,6 +26,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := \
+	android_jni_cts_BasicLoaderTest.cpp \
 	android_jni_cts_InstanceNonce.c \
 	android_jni_cts_JniCTest.c \
 	android_jni_cts_JniCppTest.cpp \
@@ -46,3 +47,15 @@
 LOCAL_CFLAGS += -Wno-format -Wno-gnu-designator
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libjni_test_dlclose
+
+LOCAL_SRC_FILES := taxicab_number.cpp
+
+LOCAL_SDK_VERSION := 23
+
+LOCAL_NDK_STL_VARIANT := c++_static
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_BasicLoaderTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_BasicLoaderTest.cpp
new file mode 100644
index 0000000..704cd4f
--- /dev/null
+++ b/tests/tests/jni/libjnitest/android_jni_cts_BasicLoaderTest.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * Tests accessibility of platform native libraries
+ */
+
+#include <dlfcn.h>
+#include <jni.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "nativehelper/JNIHelp.h"
+#include "nativehelper/ScopedLocalRef.h"
+#include "nativehelper/ScopedUtfChars.h"
+
+static constexpr const char* kTestLibName = "libjni_test_dlclose.so";
+
+static bool run_test(std::string* error_msg) {
+  void* handle = dlopen(kTestLibName, RTLD_NOW);
+  if (handle == nullptr) {
+    *error_msg = dlerror();
+    return false;
+  }
+
+  void* taxicab_number = dlsym(handle, "dlopen_testlib_taxicab_number");
+  if (taxicab_number == nullptr) {
+    *error_msg = dlerror();
+    return false;
+  }
+
+  dlclose(handle);
+
+  uintptr_t page_start = reinterpret_cast<uintptr_t>(taxicab_number) & ~(PAGE_SIZE - 1);
+  if (mprotect(reinterpret_cast<void*>(page_start), PAGE_SIZE, PROT_NONE) == 0) {
+    *error_msg = std::string("The library \"") +
+                 kTestLibName +
+                 "\" has not been unloaded on dlclose()";
+    return false;
+  }
+
+  if (errno != ENOMEM) {
+    *error_msg = std::string("Unexpected error on mprotect: ") + strerror(errno);
+    return false;
+  }
+
+  return true;
+}
+
+extern "C" JNIEXPORT jstring JNICALL Java_android_jni_cts_BasicLoaderTestHelper_nativeRunTests(
+        JNIEnv* env) {
+  std::string error_str;
+
+  if (!run_test(&error_str)) {
+    return env->NewStringUTF(error_str.c_str());
+  }
+
+  return nullptr;
+}
+
diff --git a/tests/tests/jni/libjnitest/taxicab_number.cpp b/tests/tests/jni/libjnitest/taxicab_number.cpp
new file mode 100644
index 0000000..3226955
--- /dev/null
+++ b/tests/tests/jni/libjnitest/taxicab_number.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+uint32_t dlopen_testlib_taxicab_number = 1729;
+
+extern "C" bool dlopen_testlib_simple_func() {
+  return true;
+}
diff --git a/tests/tests/jni/src/android/jni/cts/BasicLoaderTestHelper.java b/tests/tests/jni/src/android/jni/cts/BasicLoaderTestHelper.java
new file mode 100644
index 0000000..389dc16
--- /dev/null
+++ b/tests/tests/jni/src/android/jni/cts/BasicLoaderTestHelper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.jni.cts;
+
+class BasicLoaderTestHelper {
+    static {
+        System.loadLibrary("jnitest");
+    }
+
+    static native String nativeRunTests();
+}
diff --git a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
index d2e90c6..b122457 100644
--- a/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
+++ b/tests/tests/jni/src/android/jni/cts/JniStaticTest.java
@@ -49,6 +49,13 @@
         }
     }
 
+    public void test_loader_basic() throws Exception {
+        String error = BasicLoaderTestHelper.nativeRunTests();
+        if (error != null) {
+            fail(error);
+        }
+    }
+
     /**
      * Test that accessing classes true JNI works as expected. b/19382130
      */
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index 2bf24b6..4e4acbe 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -104,8 +104,10 @@
 
     public void testSetOnVolumeKeyLongPressListener() throws Exception {
         Context context = getInstrumentation().getTargetContext();
-        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
-            // Skip this test on TV platform because the PhoneWindowManager dispatches volume key
+        if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK) ||
+            context.getResources().getBoolean(
+                       com.android.internal.R.bool.config_handleVolumeKeysInWindowManager)) {
+            // Skip this test, because the PhoneWindowManager dispatches volume key
             // events directly to the audio service to change the system volume.
             return;
         }
diff --git a/tests/tests/media/src/android/media/cts/VolumeShaperTest.java b/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
index b4ea2b6..30f07e2 100644
--- a/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
+++ b/tests/tests/media/src/android/media/cts/VolumeShaperTest.java
@@ -1130,7 +1130,7 @@
                             0.f, volumeShaper.getVolume(), VOLUME_TOLERANCE);
 
                     player.start();
-                    Thread.sleep(WARMUP_TIME_MS);
+                    Thread.sleep(WARMUP_TIME_MS * 2);
 
                     Log.d(TAG, testName + " applying " + (pause != 0 ? "pause" : "stop"));
                     if (pause == 1) {
diff --git a/tests/tests/nativemedia/aaudio/src/utils.cpp b/tests/tests/nativemedia/aaudio/src/utils.cpp
index 8b9f60d..b039f4e 100644
--- a/tests/tests/nativemedia/aaudio/src/utils.cpp
+++ b/tests/tests/nativemedia/aaudio/src/utils.cpp
@@ -52,6 +52,14 @@
 }
 
 
+// These periods are quite generous. They are not designed to put
+// any restrictions on the implementation, but only to ensure sanity.
+// Use int64_t because 96000 * 30000 is close to int32_t limits.
+const std::map<aaudio_performance_mode_t, int64_t> StreamBuilderHelper::sMaxFramesPerBurstMs =
+{ { AAUDIO_PERFORMANCE_MODE_NONE, 128 },
+  { AAUDIO_PERFORMANCE_MODE_POWER_SAVING, 30 * 1000 },
+  { AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, 40 } };
+
 StreamBuilderHelper::StreamBuilderHelper(
         aaudio_direction_t direction, int32_t sampleRate,
         int32_t channelCount, aaudio_format_t dataFormat,
@@ -66,6 +74,8 @@
 }
 
 void StreamBuilderHelper::initBuilder() {
+    ASSERT_EQ(1U, sMaxFramesPerBurstMs.count(mRequested.perfMode));
+
     // Use an AAudioStreamBuilder to define the stream.
     aaudio_result_t result = AAudio_createStreamBuilder(&mBuilder);
     ASSERT_EQ(AAUDIO_OK, result);
@@ -128,7 +138,9 @@
 
     mFramesPerBurst = AAudioStream_getFramesPerBurst(mStream);
     ASSERT_GE(mFramesPerBurst, 16);
-    ASSERT_LE(mFramesPerBurst, 3072); // on some devices, it can be 2052
+    const int32_t maxFramesPerBurst =
+            mActual.sampleRate * sMaxFramesPerBurstMs.at(mActual.perfMode) / MILLIS_PER_SECOND;
+    ASSERT_LE(mFramesPerBurst, maxFramesPerBurst);
 
     int32_t actualBufferSize = AAudioStream_getBufferSizeInFrames(mStream);
     ASSERT_GT(actualBufferSize, 0);
diff --git a/tests/tests/nativemedia/aaudio/src/utils.h b/tests/tests/nativemedia/aaudio/src/utils.h
index fbb3e76..44c3c69 100644
--- a/tests/tests/nativemedia/aaudio/src/utils.h
+++ b/tests/tests/nativemedia/aaudio/src/utils.h
@@ -16,6 +16,8 @@
 #ifndef CTS_MEDIA_TEST_AAUDIO_UTILS_H
 #define CTS_MEDIA_TEST_AAUDIO_UTILS_H
 
+#include <map>
+
 #include <aaudio/AAudio.h>
 
 int64_t getNanoseconds(clockid_t clockId = CLOCK_MONOTONIC);
@@ -68,6 +70,7 @@
     void streamCommand(
             StreamCommand cmd, aaudio_stream_state_t fromState, aaudio_stream_state_t toState);
 
+    static const std::map<aaudio_performance_mode_t, int64_t> sMaxFramesPerBurstMs;
     const aaudio_direction_t mDirection;
     const Parameters mRequested;
     Parameters mActual;
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 79ee799..1ae4ddd 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -56,6 +56,7 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Scanner;
 import java.util.Set;
 
 /**
@@ -271,18 +272,58 @@
         assertFileOwnedByGroup(f, "net_bw_stats");
     }
 
-    @MediumTest
-    public void testProcSelfOomAdjSane() {
-        File f = new File("/proc/self/oom_adj");
-        assertFalse(f.canWrite());
-        assertFalse(f.canExecute());
+    private static int readInt(File f) throws FileNotFoundException {
+        try (Scanner s = new Scanner(f)) {
+            return s.nextInt();
+        }
+    }
+
+    private static boolean writeInt(File f, int value) throws IOException {
+        try (FileOutputStream os = new FileOutputStream(f)) {
+            try {
+                os.write(Integer.toString(value).getBytes());
+                return true;
+            } catch (IOException e) {
+                return false;
+            }
+        }
     }
 
     @MediumTest
-    public void testProcSelfOomScoreAdjSane() {
-        File f = new File("/proc/self/oom_score_adj");
-        assertFalse(f.canWrite());
+    public void testProcSelfOomAdjSane() throws IOException {
+        final int OOM_DISABLE = -17;
+
+        File f = new File("/proc/self/oom_adj");
+        assertTrue(f.canRead());
         assertFalse(f.canExecute());
+
+        int oom_adj = readInt(f);
+        assertNotSame("unprivileged processes should not be unkillable", OOM_DISABLE, oom_adj);
+        if (f.canWrite())
+            assertFalse("unprivileged processes should not be able to reduce their oom_adj value",
+                    writeInt(f, oom_adj - 1));
+    }
+
+    @MediumTest
+    public void testProcSelfOomScoreAdjSane() throws IOException {
+        final int OOM_SCORE_ADJ_MIN = -1000;
+
+        File f = new File("/proc/self/oom_score_adj");
+        assertTrue(f.canRead());
+        assertFalse(f.canExecute());
+
+        int oom_score_adj = readInt(f);
+        assertNotSame("unprivileged processes should not be unkillable", OOM_SCORE_ADJ_MIN, oom_score_adj);
+        if (f.canWrite()) {
+            assertFalse(
+                    "unprivileged processes should not be able to reduce their oom_score_adj value",
+                    writeInt(f, oom_score_adj - 1));
+            assertTrue(
+                    "unprivileged processes should be able to increase their oom_score_adj value",
+                    writeInt(f, oom_score_adj + 1));
+            assertTrue("unprivileged processes should be able to restore their oom_score_adj value",
+                    writeInt(f, oom_score_adj));
+        }
     }
 
     private static List<Pair<Long, Long>> mappedPageRanges() throws IOException {
@@ -801,7 +842,8 @@
                 new File("/sys/fs/selinux/relabel"),
                 new File("/sys/fs/selinux/create"),
                 new File("/sys/fs/selinux/access"),
-                new File("/sys/fs/selinux/context")
+                new File("/sys/fs/selinux/context"),
+                new File("/sys/fs/selinux/validatetrans")
             ));
 
     @LargeTest
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index 45145a4..a50329a 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -30,7 +30,10 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"/>
 
+    <permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"
+                android:protectionLevel="signature"/>
     <application>
         <provider android:name="android.telephony.cts.MmsPduProvider"
                   android:authorities="telephonyctstest"
@@ -128,10 +131,29 @@
 
         <uses-library android:name="android.test.runner" />
 
+
+        <!-- This is the receiver defined by the MBMS api. -->
+        <receiver
+            android:name="android.telephony.mbms.MbmsDownloadReceiver"
+            android:permission="android.telephony.cts.embmstestapp.CTS_DOWNLOAD_PERMISSION"
+            android:enabled="true"
+            android:exported="true">
+        </receiver>
+
+        <provider
+            android:name="android.telephony.mbms.MbmsTempFileProvider"
+            android:authorities="android.telephony.mbms.cts"
+            android:exported="false"
+            android:grantUriPermissions="true">
+        </provider>
+
         <meta-data android:name="mbms-streaming-service-override"
                    android:value="android.telephony.cts.embmstestapp/.CtsStreamingService"/>
         <meta-data android:name="mbms-download-service-override"
                    android:value="android.telephony.cts.embmstestapp/.CtsDownloadService"/>
+        <meta-data
+            android:name="mbms-file-provider-authority"
+            android:value="android.telephony.mbms.cts"/>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml b/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml
index c1ced44..0ea1be2 100644
--- a/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml
+++ b/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml
@@ -16,7 +16,11 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.telephony.cts.embmstestapp">
+  <permission android:name="android.telephony.cts.embmstestapp.CTS_DOWNLOAD_PERMISSION"
+              android.protectionLevel="signature"/>
+
   <uses-permission android:name="android.telephony.cts.embms.permission.SEND_EMBMS_INTENTS"/>
+  <uses-permission android:name="android.telephony.cts.embmstestapp.CTS_DOWNLOAD_PERMISSION"/>
 
   <application android:label="EmbmsCtsMiddleware">
     <service android:name="android.telephony.cts.embmstestapp.CtsStreamingService"
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl b/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
index be194eb..833ac74 100644
--- a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
+++ b/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
@@ -17,6 +17,8 @@
 package android.telephony.cts.embmstestapp;
 
 import android.os.Bundle;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.FileInfo;
 
 interface ICtsDownloadMiddlewareControl {
     // Resets the state of the CTS middleware
@@ -29,4 +31,12 @@
     void forceErrorCode(int error);
     // Fire the error callback on the download session
     void fireErrorOnSession(int errorCode, String message);
+    // Fire the download state callback methods
+    void fireOnProgressUpdated(in DownloadRequest request, in FileInfo fileInfo,
+            int currentDownloadSize, int fullDownloadSize,
+            int currentDecodedSize, int fullDecodedSize);
+    void fireOnStateUpdated(in DownloadRequest request, in FileInfo fileInfo, int state);
+
+    // calling download() does nothing, this is to actually start the file-download flow.
+    void actuallyStartDownloadFlow();
 }
\ No newline at end of file
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
index 500da02..01777c6 100644
--- a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
+++ b/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
@@ -16,23 +16,34 @@
 
 package android.telephony.cts.embmstestapp;
 
+import android.app.Activity;
 import android.app.Service;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.telephony.MbmsDownloadSession;
 import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.DownloadStateCallback;
+import android.telephony.mbms.FileInfo;
 import android.telephony.mbms.FileServiceInfo;
 import android.telephony.mbms.MbmsDownloadSessionCallback;
 import android.telephony.mbms.MbmsErrors;
+import android.telephony.mbms.UriPathPair;
 import android.telephony.mbms.vendor.MbmsDownloadServiceBase;
+import android.telephony.mbms.vendor.VendorUtils;
 import android.util.Log;
 
+import java.io.IOException;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -56,19 +67,37 @@
     public static final String METHOD_REQUEST_UPDATE_FILE_SERVICES =
             "requestUpdateFileServices";
     public static final String METHOD_SET_TEMP_FILE_ROOT = "setTempFileRootDirectory";
+    public static final String METHOD_RESET_DOWNLOAD_KNOWLEDGE = "resetDownloadKnowledge";
+    public static final String METHOD_GET_DOWNLOAD_STATUS = "getDownloadStatus";
+    public static final String METHOD_CANCEL_DOWNLOAD = "cancelDownload";
     public static final String METHOD_CLOSE = "close";
+    // Not a method call, but it's a form of communication to the middleware so it's included
+    // here for convenience.
+    public static final String METHOD_DOWNLOAD_RESULT_ACK = "downloadResultAck";
 
     public static final String ARGUMENT_SUBSCRIPTION_ID = "subscriptionId";
     public static final String ARGUMENT_SERVICE_CLASSES = "serviceClasses";
     public static final String ARGUMENT_ROOT_DIRECTORY_PATH = "rootDirectoryPath";
+    public static final String ARGUMENT_DOWNLOAD_REQUEST = "downloadRequest";
+    public static final String ARGUMENT_FILE_INFO = "fileInfo";
+    public static final String ARGUMENT_RESULT_CODE = "resultCode";
 
     public static final String CONTROL_INTERFACE_ACTION =
             "android.telephony.cts.embmstestapp.ACTION_CONTROL_MIDDLEWARE";
     public static final ComponentName CONTROL_INTERFACE_COMPONENT =
             ComponentName.unflattenFromString(
                     "android.telephony.cts.embmstestapp/.CtsDownloadService");
+    public static final ComponentName CTS_TEST_RECEIVER_COMPONENT =
+            ComponentName.unflattenFromString(
+                    "android.telephony.cts/android.telephony.mbms.MbmsDownloadReceiver");
 
+    public static final Uri DOWNLOAD_SOURCE_URI = Uri.parse("http://www.example.com/file_download");
     public static final FileServiceInfo FILE_SERVICE_INFO;
+    public static final FileInfo FILE_INFO = new FileInfo(
+            DOWNLOAD_SOURCE_URI.buildUpon().appendPath("file1.txt").build(),
+            "text/plain");
+    public static final byte[] SAMPLE_FILE_DATA = "this is some sample file data".getBytes();
+
     static {
         String id = "FileServiceId";
         Map<Locale, String> localeDict = new HashMap<Locale, String>() {{
@@ -81,15 +110,18 @@
         }};
         FILE_SERVICE_INFO = new FileServiceInfo(localeDict, "class1", locales,
                 id, new Date(2017, 8, 21, 18, 20, 29),
-                new Date(2017, 8, 21, 18, 23, 9), Collections.emptyList());
+                new Date(2017, 8, 21, 18, 23, 9), Collections.singletonList(FILE_INFO));
     }
 
     private MbmsDownloadSessionCallback mAppCallback;
+    private DownloadStateCallback mDownloadStateCallback;
 
     private HandlerThread mHandlerThread;
     private Handler mHandler;
     private List<Bundle> mReceivedCalls = new LinkedList<>();
     private int mErrorCodeOverride = MbmsErrors.SUCCESS;
+    private List<DownloadRequest> mReceivedRequests = new LinkedList<>();
+    private String mTempFileRootDirPath = null;
 
     private final MbmsDownloadServiceBase mDownloadServiceImpl = new MbmsDownloadServiceBase() {
         @Override
@@ -150,20 +182,26 @@
         }
 
         @Override
+        public int download(DownloadRequest downloadRequest) {
+            mReceivedRequests.add(downloadRequest);
+            return MbmsErrors.SUCCESS;
+        }
+
+        @Override
         public int setTempFileRootDirectory(int subscriptionId, String rootDirectoryPath) {
             Bundle b = new Bundle();
             b.putString(METHOD_NAME, METHOD_SET_TEMP_FILE_ROOT);
             b.putInt(ARGUMENT_SUBSCRIPTION_ID, subscriptionId);
             b.putString(ARGUMENT_ROOT_DIRECTORY_PATH, rootDirectoryPath);
             mReceivedCalls.add(b);
-
+            mTempFileRootDirPath = rootDirectoryPath;
             return 0;
         }
 
         @Override
         public int registerStateCallback(DownloadRequest downloadRequest,
                 DownloadStateCallback listener) throws RemoteException {
-            // TODO
+            mDownloadStateCallback = listener;
             return MbmsErrors.SUCCESS;
         }
 
@@ -173,8 +211,47 @@
             b.putString(METHOD_NAME, METHOD_CLOSE);
             b.putInt(ARGUMENT_SUBSCRIPTION_ID, subscriptionId);
             mReceivedCalls.add(b);
+        }
 
-            // TODO
+        @Override
+        public int getDownloadStatus(DownloadRequest downloadRequest, FileInfo fileInfo) {
+            Bundle b = new Bundle();
+            b.putString(METHOD_NAME, METHOD_GET_DOWNLOAD_STATUS);
+            b.putParcelable(ARGUMENT_DOWNLOAD_REQUEST, downloadRequest);
+            b.putParcelable(ARGUMENT_FILE_INFO, fileInfo);
+            mReceivedCalls.add(b);
+            return MbmsDownloadSession.STATUS_ACTIVELY_DOWNLOADING;
+        }
+
+        @Override
+        public int cancelDownload(DownloadRequest request) {
+            Bundle b = new Bundle();
+            b.putString(METHOD_NAME, METHOD_CANCEL_DOWNLOAD);
+            b.putParcelable(ARGUMENT_DOWNLOAD_REQUEST, request);
+            mReceivedCalls.add(b);
+            mReceivedRequests.remove(request);
+            return MbmsErrors.SUCCESS;
+        }
+
+        @Override
+        public List<DownloadRequest> listPendingDownloads(int subscriptionId) {
+            return mReceivedRequests;
+        }
+
+        @Override
+        public int unregisterStateCallback(DownloadRequest downloadRequest,
+                DownloadStateCallback callback) {
+            mDownloadStateCallback = null;
+            return MbmsErrors.SUCCESS;
+        }
+
+        @Override
+        public int resetDownloadKnowledge(DownloadRequest downloadRequest) {
+            Bundle b = new Bundle();
+            b.putString(METHOD_NAME, METHOD_RESET_DOWNLOAD_KNOWLEDGE);
+            b.putParcelable(ARGUMENT_DOWNLOAD_REQUEST, downloadRequest);
+            mReceivedCalls.add(b);
+            return MbmsErrors.SUCCESS;
         }
 
         @Override
@@ -190,6 +267,9 @@
             mHandler.removeCallbacksAndMessages(null);
             mAppCallback = null;
             mErrorCodeOverride = MbmsErrors.SUCCESS;
+            mReceivedRequests.clear();
+            mDownloadStateCallback = null;
+            mTempFileRootDirPath = null;
         }
 
         @Override
@@ -206,6 +286,100 @@
         public void fireErrorOnSession(int errorCode, String message) {
             mHandler.post(() -> mAppCallback.onError(errorCode, message));
         }
+
+        @Override
+        public void fireOnProgressUpdated(DownloadRequest request, FileInfo fileInfo,
+                int currentDownloadSize, int fullDownloadSize,
+                int currentDecodedSize, int fullDecodedSize) {
+            if (mDownloadStateCallback == null) {
+                return;
+            }
+            mHandler.post(() -> mDownloadStateCallback.onProgressUpdated(request, fileInfo,
+                    currentDownloadSize, fullDownloadSize, currentDecodedSize, fullDecodedSize));
+        }
+
+        @Override
+        public void fireOnStateUpdated(DownloadRequest request, FileInfo fileInfo, int state) {
+            if (mDownloadStateCallback == null) {
+                return;
+            }
+            mHandler.post(() -> mDownloadStateCallback.onStateUpdated(request, fileInfo, state));
+        }
+
+        @Override
+        public void actuallyStartDownloadFlow() {
+            DownloadRequest request = mReceivedRequests.get(0);
+            // Compose the FILE_DESCRIPTOR_REQUEST_INTENT to get some FDs to write to
+            Intent requestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+            requestIntent.putExtra(VendorUtils.EXTRA_SERVICE_ID, request.getFileServiceId());
+            requestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 1);
+            requestIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, mTempFileRootDirPath);
+            requestIntent.setComponent(CTS_TEST_RECEIVER_COMPONENT);
+
+            // Send as an ordered broadcast, using a BroadcastReceiver to capture the result
+            // containing UriPathPairs.
+            logd("Sending fd-request broadcast");
+            sendOrderedBroadcast(requestIntent,
+                    null, // receiverPermission
+                    new BroadcastReceiver() {
+                        @Override
+                        public void onReceive(Context context, Intent intent) {
+                            logd("Got file-descriptors");
+                            Bundle extras = getResultExtras(false);
+                            UriPathPair tempFile = (UriPathPair) extras.getParcelableArrayList(
+                                    VendorUtils.EXTRA_FREE_URI_LIST).get(0);
+                            int result = MbmsDownloadSession.RESULT_SUCCESSFUL;
+                            try {
+                                ParcelFileDescriptor tempFileFd =
+                                        getContentResolver().openFileDescriptor(
+                                                tempFile.getContentUri(), "rw");
+                                OutputStream destinationStream =
+                                        new ParcelFileDescriptor.AutoCloseOutputStream(tempFileFd);
+
+                                destinationStream.write(SAMPLE_FILE_DATA);
+                                destinationStream.flush();
+                            } catch (IOException e) {
+                                result = MbmsDownloadSession.RESULT_CANCELLED;
+                            }
+
+                            Intent downloadResultIntent =
+                                    new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+                            downloadResultIntent.putExtra(
+                                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST, request);
+                            downloadResultIntent.putExtra(VendorUtils.EXTRA_FINAL_URI,
+                                    tempFile.getFilePathUri());
+                            downloadResultIntent.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO,
+                                    FILE_INFO);
+                            downloadResultIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT,
+                                    mTempFileRootDirPath);
+                            downloadResultIntent.putExtra(
+                                    MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, result);
+                            downloadResultIntent.setComponent(CTS_TEST_RECEIVER_COMPONENT);
+
+                            logd("Sending broadcast to app: " + downloadResultIntent.toString());
+                            sendOrderedBroadcast(downloadResultIntent,
+                                    null, // receiverPermission
+                                    new BroadcastReceiver() {
+                                        @Override
+                                        public void onReceive(Context context, Intent intent) {
+                                            Bundle b = new Bundle();
+                                            b.putString(METHOD_NAME, METHOD_DOWNLOAD_RESULT_ACK);
+                                            b.putInt(ARGUMENT_RESULT_CODE, getResultCode());
+                                            mReceivedCalls.add(b);
+                                        }
+                                    },
+                                    null, // scheduler
+                                    Activity.RESULT_OK,
+                                    null, // initialData
+                                    null /* initialExtras */);
+                        }
+                    },
+                    mHandler, // scheduler
+                    Activity.RESULT_OK,
+                    null, // initialData
+                    null /* initialExtras */);
+
+        }
     };
 
     @Override
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
new file mode 100644
index 0000000..5089381
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 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
+ */
+
+package android.telephony.embms.cts;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.cts.embmstestapp.CtsDownloadService;
+import android.telephony.mbms.MbmsDownloadReceiver;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+
+public class MbmsDownloadFlowTest extends MbmsDownloadTestBase {
+    private File tempFileRootDir;
+    private String tempFileRootDirPath;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
+        tempFileRootDir.mkdir();
+        tempFileRootDirPath = tempFileRootDir.getCanonicalPath();
+        mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        recursiveDelete(tempFileRootDir);
+        tempFileRootDir = null;
+        super.tearDown();
+    }
+
+    public void testFileDownloadFlow() throws Exception {
+        MbmsDownloadReceiverTest.AppIntentCapture captor =
+                new MbmsDownloadReceiverTest.AppIntentCapture(mContext, mCallbackHandler);
+        mDownloadSession.download(MbmsDownloadReceiverTest.TEST_DOWNLOAD_REQUEST);
+        mMiddlewareControl.actuallyStartDownloadFlow();
+        Intent downloadDoneIntent = captor.getIntent();
+
+        assertEquals(MbmsDownloadReceiverTest.APP_INTENT_ACTION, downloadDoneIntent.getAction());
+        assertEquals(MbmsDownloadSession.RESULT_SUCCESSFUL,
+                downloadDoneIntent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, -1));
+        assertEquals(MbmsDownloadReceiverTest.TEST_DOWNLOAD_REQUEST,
+                downloadDoneIntent.getParcelableExtra(
+                        MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST));
+        assertEquals(CtsDownloadService.FILE_INFO,
+                downloadDoneIntent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO));
+        Uri fileUri = downloadDoneIntent.getParcelableExtra(
+                MbmsDownloadSession.EXTRA_MBMS_COMPLETED_FILE_URI);
+        InputStream is = mContext.getContentResolver().openInputStream(fileUri);
+        byte[] contents = new byte[CtsDownloadService.SAMPLE_FILE_DATA.length];
+        is.read(contents);
+        for (int i = 0; i < contents.length; i++) {
+            assertEquals(contents[i], CtsDownloadService.SAMPLE_FILE_DATA[i]);
+        }
+
+        List<Bundle> downloadResultAck =
+                getMiddlewareCalls(CtsDownloadService.METHOD_DOWNLOAD_RESULT_ACK);
+        assertEquals(1, downloadResultAck.size());
+        assertEquals(MbmsDownloadReceiver.RESULT_OK,
+                downloadResultAck.get(0).getInt(CtsDownloadService.ARGUMENT_RESULT_CODE, -1));
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
new file mode 100644
index 0000000..2495af3
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 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
+ */
+
+package android.telephony.embms.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.telephony.MbmsDownloadSession;
+import android.telephony.cts.embmstestapp.CtsDownloadService;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.MbmsDownloadReceiver;
+import android.telephony.mbms.UriPathPair;
+import android.telephony.mbms.vendor.VendorUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+public class MbmsDownloadReceiverTest extends MbmsDownloadTestBase {
+    private static final String CTS_BROADCAST_PERMISSION =
+            "android.telephony.embms.cts.permission.TEST_BROADCAST";
+    private static final String TEST_SERVICE_ID = "service_id";
+
+    public static final String APP_INTENT_ACTION =
+            "android.telephony.embms.cts.ACTION_TEST_DOWNLOAD_COMPLETE";
+    public static final DownloadRequest TEST_DOWNLOAD_REQUEST = DOWNLOAD_REQUEST_TEMPLATE
+            .setAppIntent(new Intent(APP_INTENT_ACTION))
+            .build();
+
+    public static class AppIntentCapture {
+        private final BlockingQueue<Intent> mReceivedIntent = new LinkedBlockingQueue<>();
+        private final BroadcastReceiver mAppIntentReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                mReceivedIntent.add(intent);
+            }
+        };
+        private Context mContext;
+
+        public AppIntentCapture(Context context, Handler handler) {
+            mContext = context;
+            IntentFilter filter = new IntentFilter(APP_INTENT_ACTION);
+            mContext.registerReceiver(mAppIntentReceiver, filter, null, handler);
+        }
+
+        public Intent getIntent() {
+            try {
+                Intent result = mReceivedIntent.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+                mContext.unregisterReceiver(mAppIntentReceiver);
+                return result;
+            } catch (InterruptedException e) {
+                fail("test was interrupted");
+                return null;
+            }
+        }
+    }
+
+    private MbmsDownloadReceiver mReceiver;
+    private File tempFileRootDir;
+    private String tempFileRootDirPath;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mReceiver = new MbmsDownloadReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+        filter.addAction(VendorUtils.ACTION_CLEANUP);
+        filter.addAction(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        mContext.registerReceiver(mReceiver, filter);
+        tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
+        tempFileRootDir.mkdir();
+        tempFileRootDirPath = tempFileRootDir.getCanonicalPath();
+        mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        recursiveDelete(tempFileRootDir);
+        tempFileRootDir = null;
+        super.tearDown();
+    }
+
+    public void testMalformedIntents() throws Exception {
+        Intent downloadCompleteIntent = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+        sendBroadcastAndValidate(downloadCompleteIntent,
+                MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
+
+        Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        sendBroadcastAndValidate(fdRequestIntent,
+                MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
+
+        Intent cleanupIntent = new Intent(VendorUtils.ACTION_CLEANUP);
+        sendBroadcastAndValidate(cleanupIntent,
+                MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
+    }
+
+    public void testBadTempFileDirectory() throws Exception {
+        Intent cleanupIntent = new Intent(VendorUtils.ACTION_CLEANUP);
+        populateIntentWithCommonFields(cleanupIntent);
+        cleanupIntent.putParcelableArrayListExtra(VendorUtils.EXTRA_TEMP_FILES_IN_USE,
+                new ArrayList<>(0));
+        cleanupIntent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, "this is not a directory path");
+        sendBroadcastAndValidate(cleanupIntent,
+                MbmsDownloadReceiver.RESULT_BAD_TEMP_FILE_ROOT);
+    }
+
+    public void testDownloadFailureIntent() throws Exception {
+        Intent intentForReceiverTest = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+        populateIntentWithCommonFields(intentForReceiverTest);
+        intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
+                MbmsDownloadSession.RESULT_CANCELLED);
+        intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST,
+                TEST_DOWNLOAD_REQUEST);
+
+        AppIntentCapture intentCaptor = new AppIntentCapture(mContext, mCallbackHandler);
+
+        sendBroadcastAndValidate(intentForReceiverTest, MbmsDownloadReceiver.RESULT_OK);
+        Intent receivedIntent = intentCaptor.getIntent();
+
+        assertEquals(MbmsDownloadSession.RESULT_CANCELLED,
+                receivedIntent.getIntExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT, -1));
+
+        assertEquals(TEST_DOWNLOAD_REQUEST,
+                receivedIntent.getParcelableExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST));
+    }
+
+    public void testBadDownloadToken() {
+        // Set up a perfectly valid download completion intent, and expect it to fail because the
+        // download token hasn't been written.
+        Intent intentForReceiverTest = new Intent(VendorUtils.ACTION_DOWNLOAD_RESULT_INTERNAL);
+        populateIntentWithCommonFields(intentForReceiverTest);
+        intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_RESULT,
+                MbmsDownloadSession.RESULT_SUCCESSFUL);
+        intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_DOWNLOAD_REQUEST,
+                TEST_DOWNLOAD_REQUEST);
+        intentForReceiverTest.putExtra(MbmsDownloadSession.EXTRA_MBMS_FILE_INFO,
+                CtsDownloadService.FILE_INFO);
+        intentForReceiverTest.putExtra(VendorUtils.EXTRA_FINAL_URI,
+                Uri.fromFile(new File(new File(tempFileRootDir, TEST_SERVICE_ID), "file1")));
+
+        sendBroadcastAndValidate(intentForReceiverTest,
+                MbmsDownloadReceiver.RESULT_MALFORMED_INTENT);
+    }
+
+    public void testRequestNoFileDescriptors() throws Exception {
+        Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        populateIntentWithCommonFields(fdRequestIntent);
+
+        Bundle b = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
+        assertTrue(b == null || b.isEmpty());
+    }
+
+    public void testRequestNewFileDescriptors() throws Exception {
+        Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        populateIntentWithCommonFields(fdRequestIntent);
+        fdRequestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 5);
+
+        Bundle result = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
+        List<UriPathPair> freeUris = result.getParcelableArrayList(VendorUtils.EXTRA_FREE_URI_LIST);
+        assertNotNull(freeUris);
+        assertEquals(5, freeUris.size());
+        for (UriPathPair pathPair : freeUris) {
+            assertEquals(ContentResolver.SCHEME_CONTENT, pathPair.getContentUri().getScheme());
+            assertEquals(ContentResolver.SCHEME_FILE, pathPair.getFilePathUri().getScheme());
+        }
+    }
+
+    public void testRequestRefreshedFileDescriptors() throws Exception {
+        // Set up a few temp files that we can request again
+        Intent fdRequestIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        populateIntentWithCommonFields(fdRequestIntent);
+        fdRequestIntent.putExtra(VendorUtils.EXTRA_FD_COUNT, 2);
+
+        Bundle result = sendBroadcastAndValidate(fdRequestIntent, MbmsDownloadReceiver.RESULT_OK);
+        List<UriPathPair> freeUris = result.getParcelableArrayList(VendorUtils.EXTRA_FREE_URI_LIST);
+
+        Intent fdRefreshIntent = new Intent(VendorUtils.ACTION_FILE_DESCRIPTOR_REQUEST);
+        populateIntentWithCommonFields(fdRefreshIntent);
+        fdRefreshIntent.putParcelableArrayListExtra(VendorUtils.EXTRA_PAUSED_LIST,
+                new ArrayList<>(freeUris.stream().map(UriPathPair::getFilePathUri)
+                        .collect(Collectors.toList())));
+        Bundle result2 = sendBroadcastAndValidate(fdRefreshIntent, MbmsDownloadReceiver.RESULT_OK);
+        List<UriPathPair> refreshUris =
+                result2.getParcelableArrayList(VendorUtils.EXTRA_PAUSED_URI_LIST);
+        assertEquals(freeUris.size(), refreshUris.size());
+        for (UriPathPair pathPair : refreshUris) {
+            assertTrue(freeUris.stream()
+                    .anyMatch((originalPair) ->
+                            originalPair.getFilePathUri().equals(pathPair.getFilePathUri())));
+        }
+    }
+
+    private Bundle sendBroadcastAndValidate(Intent intent, int expectedCode) {
+        BlockingQueue<Bundle> receivedExtras = new LinkedBlockingQueue<>();
+        BlockingQueue<Integer> receivedCode = new LinkedBlockingQueue<>();
+        mContext.sendOrderedBroadcast(intent, CTS_BROADCAST_PERMISSION,
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        receivedExtras.add(getResultExtras(true));
+                        receivedCode.add(getResultCode());
+                    }
+                }, mCallbackHandler, -1, null, null);
+
+        try {
+            assertEquals(expectedCode,
+                    (int) receivedCode.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS));
+            return receivedExtras.poll(ASYNC_TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("Test interrupted");
+            return null;
+        }
+    }
+
+    private boolean bundleEquals(Bundle a, Bundle b) {
+        if (a == null && b == null) {
+            return true;
+        }
+        if (a == null || b == null) {
+            return false;
+        }
+        for (String aKey : a.keySet()) {
+            if (!Objects.equals(a.get(aKey), b.get(aKey))) {
+                return false;
+            }
+        }
+
+        for (String bKey : b.keySet()) {
+            if (!Objects.equals(b.get(bKey), a.get(bKey))) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private void populateIntentWithCommonFields(Intent intent) {
+        intent.putExtra(VendorUtils.EXTRA_SERVICE_ID, TEST_SERVICE_ID);
+        intent.putExtra(VendorUtils.EXTRA_TEMP_FILE_ROOT, tempFileRootDirPath);
+    }
+
+}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
index e741638..6bd35c3 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
@@ -16,9 +16,12 @@
 
 package android.telephony.embms.cts;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.telephony.MbmsDownloadSession;
 import android.telephony.cts.embmstestapp.CtsDownloadService;
+import android.telephony.cts.embmstestapp.CtsStreamingService;
+import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.FileServiceInfo;
 import android.telephony.mbms.MbmsErrors;
 
@@ -88,6 +91,107 @@
         assertEquals(1, setTempRootCalls.size());
         assertEquals(tempFileRootDirectory.getCanonicalPath(),
                 setTempRootCalls.get(0).getString(CtsDownloadService.ARGUMENT_ROOT_DIRECTORY_PATH));
+        tempFileRootDirectory.delete();
+    }
+
+    public void testSetInvalidTempFileRoot() throws Exception {
+        File tempFileRootDirectory = new File(mContext.getFilesDir(), "NNN-DoesNotExist");
+        tempFileRootDirectory.delete();
+
+        try {
+            mDownloadSession.setTempFileRootDirectory(tempFileRootDirectory);
+            fail("Should not be able to set temp file root to non-existent directory");
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+
+        tempFileRootDirectory = new File(mContext.getFilesDir(), "this-is-a-file.dat");
+        tempFileRootDirectory.createNewFile();
+
+        try {
+            mDownloadSession.setTempFileRootDirectory(tempFileRootDirectory);
+            fail("Should not be able to set temp file root to a file");
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+
+        try {
+            mDownloadSession.setTempFileRootDirectory(mContext.getFilesDir());
+            fail("Should not be able to set temp file root to the files dir");
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+
+        try {
+            mDownloadSession.setTempFileRootDirectory(mContext.getCacheDir());
+            fail("Should not be able to set temp file root to the cache dir");
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+
+        try {
+            mDownloadSession.setTempFileRootDirectory(mContext.getDataDir());
+            fail("Should not be able to set temp file root to the data dir");
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+
+        tempFileRootDirectory.delete();
+    }
+
+    public void testResetDownloadKnowledge() throws Exception {
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.resetDownloadKnowledge(request);
+
+        List<Bundle> resetDownloadKnowledgeCalls =
+                getMiddlewareCalls(CtsDownloadService.METHOD_RESET_DOWNLOAD_KNOWLEDGE);
+        assertEquals(1, resetDownloadKnowledgeCalls.size());
+        assertEquals(request, resetDownloadKnowledgeCalls.get(0).getParcelable(
+                CtsDownloadService.ARGUMENT_DOWNLOAD_REQUEST));
+    }
+
+    public void testGetDownloadStatus() throws Exception {
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.getDownloadStatus(request, CtsDownloadService.FILE_INFO);
+
+        List<Bundle> getDownloadStatusCalls =
+                getMiddlewareCalls(CtsDownloadService.METHOD_GET_DOWNLOAD_STATUS);
+        assertEquals(1, getDownloadStatusCalls.size());
+        assertEquals(request, getDownloadStatusCalls.get(0).getParcelable(
+                CtsDownloadService.ARGUMENT_DOWNLOAD_REQUEST));
+        assertEquals(CtsDownloadService.FILE_INFO, getDownloadStatusCalls.get(0).getParcelable(
+                CtsDownloadService.ARGUMENT_FILE_INFO));
+    }
+
+    public void testCancelDownload() throws Exception {
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.cancelDownload(request);
+
+        List<Bundle> cancelDownloadCalls =
+                getMiddlewareCalls(CtsDownloadService.METHOD_CANCEL_DOWNLOAD);
+        assertEquals(1, cancelDownloadCalls.size());
+        assertEquals(request, cancelDownloadCalls.get(0).getParcelable(
+                CtsDownloadService.ARGUMENT_DOWNLOAD_REQUEST));
+    }
+
+    public void testListPendingDownloads() throws Exception {
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.setAppIntent(new Intent()).build();
+        mDownloadSession.download(request);
+
+        List<DownloadRequest> downloads = mDownloadSession.listPendingDownloads();
+        assertEquals(1, downloads.size());
+        assertEquals(request, downloads.get(0));
+    }
+
+    public void testDownloadRequestOpacity() throws Exception {
+        Intent intent = new Intent("sample_intent_action");
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.setAppIntent(intent).build();
+        DownloadRequest newRequest = new DownloadRequest.Builder(request.getSourceUri())
+                .setServiceId(request.getFileServiceId())
+                .setSubscriptionId(request.getSubscriptionId())
+                .setOpaqueData(request.getOpaqueData())
+                .build();
+        assertEquals(request, newRequest);
     }
 
     public void testErrorDelivery() throws Exception {
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java
new file mode 100644
index 0000000..a5cc2d0
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadStateCallbackTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 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
+ */
+
+package android.telephony.embms.cts;
+
+import android.telephony.MbmsDownloadSession;
+import android.telephony.cts.embmstestapp.CtsDownloadService;
+import android.telephony.mbms.DownloadRequest;
+import android.telephony.mbms.DownloadStateCallback;
+import android.telephony.mbms.FileInfo;
+
+import com.android.internal.os.SomeArgs;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class MbmsDownloadStateCallbackTest extends MbmsDownloadTestBase {
+    private static final long SHORT_TIMEOUT = 500;
+
+    private class TestDSCallback extends DownloadStateCallback {
+        private final BlockingQueue<SomeArgs> mProgressUpdatedCalls = new LinkedBlockingQueue<>();
+        private final BlockingQueue<SomeArgs> mStateUpdatedCalls = new LinkedBlockingQueue<>();
+
+        public TestDSCallback(int filterFlags) {
+            super(filterFlags);
+        }
+
+        @Override
+        public void onProgressUpdated(DownloadRequest request, FileInfo fileInfo, int
+                currentDownloadSize, int fullDownloadSize, int currentDecodedSize, int
+                fullDecodedSize) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = request;
+            args.arg2 = fileInfo;
+            args.arg3 = currentDownloadSize;
+            args.arg4 = fullDownloadSize;
+            args.arg5 = currentDecodedSize;
+            args.arg6 = fullDecodedSize;
+            mProgressUpdatedCalls.add(args);
+        }
+
+        @Override
+        public void onStateUpdated(DownloadRequest request, FileInfo fileInfo,
+                @MbmsDownloadSession.DownloadStatus int state) {
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = request;
+            args.arg2 = fileInfo;
+            args.arg3 = state;
+            mStateUpdatedCalls.add(args);
+        }
+
+        public SomeArgs waitOnProgressUpdated(long timeout) {
+            try {
+                return mProgressUpdatedCalls.poll(timeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return null;
+            }
+        }
+
+        public SomeArgs waitOnStateUpdated(long timeout) {
+            try {
+                return mStateUpdatedCalls.poll(timeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                return null;
+            }
+        }
+    }
+
+    public void testFullCallback() throws Exception {
+        int sampleInt = 10;
+        TestDSCallback callback = new TestDSCallback(DownloadStateCallback.ALL_UPDATES);
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.registerStateCallback(request, callback, mCallbackHandler);
+        mMiddlewareControl.fireOnProgressUpdated(request, CtsDownloadService.FILE_INFO,
+                sampleInt, sampleInt, sampleInt, sampleInt);
+        SomeArgs progressArgs = callback.waitOnProgressUpdated(ASYNC_TIMEOUT);
+        assertEquals(request, progressArgs.arg1);
+        assertEquals(CtsDownloadService.FILE_INFO, progressArgs.arg2);
+        assertEquals(sampleInt, progressArgs.arg3);
+        assertEquals(sampleInt, progressArgs.arg4);
+        assertEquals(sampleInt, progressArgs.arg5);
+        assertEquals(sampleInt, progressArgs.arg6);
+
+        mMiddlewareControl.fireOnStateUpdated(request, CtsDownloadService.FILE_INFO, sampleInt);
+        SomeArgs stateArgs = callback.waitOnStateUpdated(ASYNC_TIMEOUT);
+        assertEquals(request, stateArgs.arg1);
+        assertEquals(CtsDownloadService.FILE_INFO, stateArgs.arg2);
+        assertEquals(sampleInt, stateArgs.arg3);
+    }
+
+    public void testDeregistration() throws Exception {
+        TestDSCallback callback = new TestDSCallback(DownloadStateCallback.ALL_UPDATES);
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.registerStateCallback(request, callback, mCallbackHandler);
+        mDownloadSession.unregisterStateCallback(request, callback);
+
+        mMiddlewareControl.fireOnStateUpdated(null, null, 0);
+        assertNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
+        mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
+        assertNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
+    }
+
+    public void testCallbackFiltering1() throws Exception {
+        TestDSCallback callback = new TestDSCallback(DownloadStateCallback.PROGRESS_UPDATES);
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.registerStateCallback(request, callback, mCallbackHandler);
+
+        mMiddlewareControl.fireOnStateUpdated(null, null, 0);
+        assertNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
+        mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
+        assertNotNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
+    }
+
+    public void testCallbackFiltering2() throws Exception {
+        TestDSCallback callback = new TestDSCallback(DownloadStateCallback.STATE_UPDATES);
+        DownloadRequest request = DOWNLOAD_REQUEST_TEMPLATE.build();
+        mDownloadSession.registerStateCallback(request, callback, mCallbackHandler);
+
+        mMiddlewareControl.fireOnStateUpdated(null, null, 0);
+        assertNotNull(callback.waitOnStateUpdated(SHORT_TIMEOUT));
+        mMiddlewareControl.fireOnProgressUpdated(null, null, 0, 0, 0, 0);
+        assertNull(callback.waitOnProgressUpdated(SHORT_TIMEOUT));
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
index ec70ea8..3f490ad 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
@@ -29,12 +29,14 @@
 import android.telephony.MbmsDownloadSession;
 import android.telephony.cts.embmstestapp.CtsDownloadService;
 import android.telephony.cts.embmstestapp.ICtsDownloadMiddlewareControl;
+import android.telephony.mbms.DownloadRequest;
 import android.telephony.mbms.FileServiceInfo;
 import android.telephony.mbms.MbmsDownloadSessionCallback;
 import android.test.InstrumentationTestCase;
 
 import com.android.internal.os.SomeArgs;
 
+import java.io.File;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
@@ -102,6 +104,10 @@
         }
     }
 
+    static final DownloadRequest.Builder DOWNLOAD_REQUEST_TEMPLATE =
+            new DownloadRequest.Builder(CtsDownloadService.DOWNLOAD_SOURCE_URI)
+                    .setServiceInfo(CtsDownloadService.FILE_SERVICE_INFO);
+
     Context mContext;
     HandlerThread mHandlerThread;
     Handler mCallbackHandler;
@@ -165,4 +171,13 @@
                 .filter((elem) -> elem.getString(CtsDownloadService.METHOD_NAME).equals(methodName))
                 .collect(Collectors.toList());
     }
+
+    protected static void recursiveDelete(File f) {
+        if (f.isDirectory()) {
+            for (File f1 : f.listFiles()) {
+                recursiveDelete(f1);
+            }
+        }
+        f.delete();
+    }
 }
\ No newline at end of file
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
index 4991aac..1acd70a 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ColorFilterAlphaTest.java
@@ -89,7 +89,7 @@
                 0xFFC21A1A, 0xFFC93333, 0xFFD04D4D, 0xFFD66666, 0xFFBB0000 } },
     };
 
-    @Parameterized.Parameters(name = "{0}")
+    @Parameterized.Parameters
     public static List<XfermodeTest.Config> configs() {
         return XfermodeTest.configs(MODES_AND_EXPECTED_COLORS);
     }
diff --git a/tests/tests/widget/res/layout-watch/listviewfixed_layout.xml b/tests/tests/widget/res/layout-watch/listviewfixed_layout.xml
new file mode 100644
index 0000000..53b8c25
--- /dev/null
+++ b/tests/tests/widget/res/layout-watch/listviewfixed_layout.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ListView
+        android:id="@+id/listview_default"
+        android:layout_width="200dp"
+        android:layout_height="200dp"
+        android:divider="@null"
+        android:dividerHeight="0px"
+        android:background="#80FF0000"/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index c4a4070..e57c8358 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -145,7 +145,7 @@
 
     private boolean isWatch() {
         return (mContext.getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
     }
 
     @Test
diff --git a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
index 3fb141e..2a7e899 100644
--- a/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/NumberPickerTest.java
@@ -295,7 +295,7 @@
 
     private boolean isWatch() {
         return (mActivity.getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
     }
 
     @Test
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 2c6635a..88c1a7a 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -7489,7 +7489,7 @@
 
     private boolean isWatch() {
         return (mActivity.getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
     }
 
     @Test
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
index c65da05..a1c28d0 100644
--- a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
@@ -303,7 +303,7 @@
 
     private boolean isWatch() {
         return (mActivity.getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_TYPE_WATCH) == Configuration.UI_MODE_TYPE_WATCH;
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
     }
 
     @Test
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 3829398..f3c5418 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -112,9 +112,9 @@
     <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.ListeningPortsTest" />
 
     <!-- b/63115400 -->
-    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.SELinuxHostTest#testAospFileContexts" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityHostTestCases android.security.cts.SELinuxHostTest#testAospFileContexts" />
     <!-- b/64221494 -->
-    <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.SELinuxHostTest#testAospPropertyContexts" />
+    <option name="compatibility:exclude-filter" value="CtsSecurityHostTestCases android.security.cts.SELinuxHostTest#testAospPropertyContexts" />
     <!-- b/63378294 b/64382381 -->
     <option name="compatibility:exclude-filter" value="CtsSecurityTestCases android.security.cts.SELinuxNeverallowRulesTest#testNeverallowRules440" />
 
diff --git a/tools/cts-tradefed/res/config/cts-reference-aosp.xml b/tools/cts-tradefed/res/config/cts-reference-aosp.xml
index 74755b6..75d27f8 100644
--- a/tools/cts-tradefed/res/config/cts-reference-aosp.xml
+++ b/tools/cts-tradefed/res/config/cts-reference-aosp.xml
@@ -92,6 +92,13 @@
     <option name="compatibility:exclude-filter" value="CtsVideoTestCases android.video.cts.VideoEncoderDecoderTest#testVp8Other0Qual1920x1080" />
 
     <!--
+        exclude below three CtsAppTestCases testcases failing on AOSP system.img
+    -->
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActionBarTest#testOpenOptionsMenu" />
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActionBarTest#testOptionsMenuKey" />
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActivityKeyboardShortcutsTest#testRequestShowKeyboardShortcuts" />
+
+    <!--
         Exclude Verity tese cases, because we need to disable Verity to test with GSI
     -->
     <option name="compatibility:exclude-filter" value="CtsKeystoreTestCases android.keystore.cts.KeyAttestationTest#testEcAttestation" />
@@ -151,4 +158,15 @@
     <option name="compatibility:exclude-filter" value="CtsCarrierApiTestCases android.carrierapi.cts.CarrierApiTest#testHasCarrierPrivileges" />
     <option name="compatibility:exclude-filter" value="CtsCarrierApiTestCases android.carrierapi.cts.CarrierApiTest#testSendDialerSpecialCode" />
 
+    <!-- b/68190722: Remove testcases that require RRO which is planned for Pi -->
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActionBarTest#testOpenOptionsMenu" />
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActionBarTest#testOptionsMenuKey" />
+    <option name="compatibility:exclude-filter" value="CtsAppTestCases android.app.cts.ActivityKeyboardShortcutsTest#testRequestShowKeyboardShortcuts" />
+
+    <!-- b/69072351: Internal bug in the "Freeform" feature of ActivityManager -->
+    <option name="compatibility:exclude-filter" value="CtsServicesHostTestCases android.server.cts.ActivityManagerFreeformStackTests#testFreeformWindowManagementSupport" />
+
+    <!-- b/69131975: Exclude android.jni.cts.JniStaticTest#test_linker_namespaces -->
+    <option name="compatibility:exclude-filter" value="CtsJniTestCases android.jni.cts.JniStaticTest#test_linker_namespaces" />
+
 </configuration>