Merge changes from topic "148087431" into pie-cts-dev

* changes:
  Revert "DO NOT MERGE Verify that remote exceptions will not cause object leaks"
  Revert "DO NOT MERGE Verify Parcel object list does not get double freed after a setDataSize"
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 6895c5f..217ee24 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="9.0_r11">
+      android:versionName="9.0_r12">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
 
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index f0f0b7e..7b3f626 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1142,6 +1142,7 @@
     <string name="ci_intents_label">Intents Test</string>
     <string name="ci_intents_direction_label">clockwise</string>
     <string name="ci_instruction_heading_label">Instructions:</string>
+    <string name="ci_directory_creation_error">CTS Verifier debug directory could not be created, please try again</string>
     <string name="ci_instruction_text_photo_label">READ BEFORE STARTING TEST</string>
     <string name="ci_instruction_text_passfail_label">Choose \"Pass\" if the right intent is fired after taking a photo from the camera app. Otherwise, choose \"Fail\".</string>
     <string name="ci_instruction_text_app_picture_label">\n
diff --git a/apps/CtsVerifier/res/xml/filepaths.xml b/apps/CtsVerifier/res/xml/filepaths.xml
index 2d555a2..9993951 100644
--- a/apps/CtsVerifier/res/xml/filepaths.xml
+++ b/apps/CtsVerifier/res/xml/filepaths.xml
@@ -1,3 +1,4 @@
 <paths xmlns:android="http://schemas.android.com/apk/res/android">
     <files-path path="images/" name="images" />
+    <files-path path="debug" name="debug/" />
 </paths>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
index 3132219..9378596 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
@@ -31,6 +31,8 @@
     private static final int LAUNCH_TEST_REQUEST_CODE = 9001;
 
     protected TestListAdapter mAdapter;
+    // Start time of test item.
+    protected long mStartTime;
 
     protected void setTestListAdapter(TestListAdapter adapter) {
         mAdapter = adapter;
@@ -74,6 +76,8 @@
     protected void handleLaunchTestResult(int resultCode, Intent data) {
         if (resultCode == RESULT_OK) {
             TestResult testResult = TestResult.fromActivityResult(resultCode, data);
+            testResult.getHistoryCollection().add(
+                testResult.getName(), mStartTime, System.currentTimeMillis());
             mAdapter.setTestResult(testResult);
         }
     }
@@ -82,6 +86,7 @@
     @Override
     protected final void onListItemClick(ListView listView, View view, int position, long id) {
         super.onListItemClick(listView, view, position, id);
+        mStartTime = System.currentTimeMillis();
         handleItemClick(listView, view, position, id);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
index aa6eaba..bed5a77 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
@@ -224,7 +224,7 @@
         // Bundle result in an intent to feed into handleLaunchTestResult
         Intent resultIntent = new Intent();
         TestResult.addResultData(resultIntent, result, test.testName, /* testDetails */ null,
-                /* reportLog */ null);
+                /* reportLog */ null, null);
         handleLaunchTestResult(RESULT_OK, resultIntent);
         getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
     }
@@ -233,7 +233,7 @@
         // Bundle result in an intent to feed into handleLaunchTestResult
         Intent resultIntent = new Intent();
         TestResult.addResultData(resultIntent, result, testName, /* testDetails */ null,
-                /* reportLog */ null);
+                /* reportLog */ null, null);
         handleLaunchTestResult(RESULT_OK, resultIntent);
         getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 4a8004a..7776d27 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -36,6 +36,10 @@
 import android.widget.ImageButton;
 import android.widget.Toast;
 
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
 /**
  * {@link Activity}s to handle clicks to the pass and fail buttons of the pass fail buttons layout.
  *
@@ -99,14 +103,21 @@
 
         /** @return A {@link ReportLog} that is used to record test metric data. */
         ReportLog getReportLog();
+
+        /**
+         * @return A {@link TestResultHistoryCollection} that is used to record test execution time.
+         */
+        TestResultHistoryCollection getHistoryCollection();
     }
 
     public static class Activity extends android.app.Activity implements PassFailActivity {
         private WakeLock mWakeLock;
         private final ReportLog reportLog;
+        private final TestResultHistoryCollection mHistoryCollection;
 
         public Activity() {
            this.reportLog = new CtsVerifierReportLog();
+           this.mHistoryCollection = new TestResultHistoryCollection();
         }
 
         @Override
@@ -160,19 +171,25 @@
         @Override
         public void setTestResultAndFinish(boolean passed) {
             PassFailButtons.setTestResultAndFinishHelper(
-                    this, getTestId(), getTestDetails(), passed, getReportLog());
+                    this, getTestId(), getTestDetails(), passed, getReportLog(),
+                    getHistoryCollection());
         }
 
         @Override
         public ReportLog getReportLog() { return reportLog; }
+
+        @Override
+        public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; }
     }
 
     public static class ListActivity extends android.app.ListActivity implements PassFailActivity {
 
         private final ReportLog reportLog;
+        private final TestResultHistoryCollection mHistoryCollection;
 
         public ListActivity() {
             this.reportLog = new CtsVerifierReportLog();
+            this.mHistoryCollection = new TestResultHistoryCollection();
         }
 
         @Override
@@ -208,11 +225,15 @@
         @Override
         public void setTestResultAndFinish(boolean passed) {
             PassFailButtons.setTestResultAndFinishHelper(
-                    this, getTestId(), getTestDetails(), passed, getReportLog());
+                    this, getTestId(), getTestDetails(), passed, getReportLog(),
+                    getHistoryCollection());
         }
 
         @Override
         public ReportLog getReportLog() { return reportLog; }
+
+        @Override
+        public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; }
     }
 
     public static class TestListActivity extends AbstractTestListActivity
@@ -257,12 +278,27 @@
         @Override
         public void setTestResultAndFinish(boolean passed) {
             PassFailButtons.setTestResultAndFinishHelper(
-                    this, getTestId(), getTestDetails(), passed, getReportLog());
+                    this, getTestId(), getTestDetails(), passed, getReportLog(),
+                    getHistoryCollection());
         }
 
         @Override
         public ReportLog getReportLog() { return reportLog; }
 
+        /**
+         * Get existing test history to aggregate.
+         */
+        @Override
+        public TestResultHistoryCollection getHistoryCollection() {
+            List<TestResultHistoryCollection> histories =
+                IntStream.range(0, mAdapter.getCount())
+                .mapToObj(mAdapter::getHistoryCollection)
+                .collect(Collectors.toList());
+            TestResultHistoryCollection historyCollection = new TestResultHistoryCollection();
+            historyCollection.merge(getTestId(), histories);
+            return historyCollection;
+        }
+
         public void updatePassButton() {
             getPassButton().setEnabled(mAdapter.allTestsPassed());
         }
@@ -274,7 +310,7 @@
             @Override
             public void onClick(View target) {
                 setTestResultAndFinish(activity, activity.getTestId(), activity.getTestDetails(),
-                        activity.getReportLog(), target);
+                        activity.getReportLog(), activity.getHistoryCollection(), target);
             }
         };
 
@@ -399,7 +435,8 @@
 
     /** Set the test result corresponding to the button clicked and finish the activity. */
     protected static void setTestResultAndFinish(android.app.Activity activity, String testId,
-            String testDetails, ReportLog reportLog, View target) {
+            String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection,
+            View target) {
         boolean passed;
         if (target.getId() == R.id.pass_button) {
             passed = true;
@@ -409,16 +446,17 @@
             throw new IllegalArgumentException("Unknown id: " + target.getId());
         }
 
-        setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog);
+        setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog, historyCollection);
     }
 
     /** Set the test result and finish the activity. */
     protected static void setTestResultAndFinishHelper(android.app.Activity activity, String testId,
-            String testDetails, boolean passed, ReportLog reportLog) {
+            String testDetails, boolean passed, ReportLog reportLog,
+            TestResultHistoryCollection historyCollection) {
         if (passed) {
-            TestResult.setPassedResult(activity, testId, testDetails, reportLog);
+            TestResult.setPassedResult(activity, testId, testDetails, reportLog, historyCollection);
         } else {
-            TestResult.setFailedResult(activity, testId, testDetails, reportLog);
+            TestResult.setFailedResult(activity, testId, testDetails, reportLog, historyCollection);
         }
 
         activity.finish();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index d9ea84f..17efb22 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -17,6 +17,7 @@
 package com.android.cts.verifier;
 
 import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.TestResultHistory;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -74,6 +75,9 @@
     /** Map from test name to {@link ReportLog}. */
     private final Map<String, ReportLog> mReportLogs = new HashMap<String, ReportLog>();
 
+    /** Map from test name to {@link TestResultHistory}. */
+    private final Map<String, TestResultHistoryCollection> mHistories = new HashMap<>();
+
     private final LayoutInflater mLayoutInflater;
 
     /** {@link ListView} row that is either a test category header or a test. */
@@ -192,8 +196,14 @@
     }
 
     public void setTestResult(TestResult testResult) {
-        new SetTestResultTask(testResult.getName(), testResult.getResult(),
-                testResult.getDetails(), testResult.getReportLog()).execute();
+        String name = testResult.getName();
+
+        // Append existing history
+        TestResultHistoryCollection histories = testResult.getHistoryCollection();
+        histories.merge(null, mHistories.get(name));
+
+        new SetTestResultTask(name, testResult.getResult(),
+                testResult.getDetails(), testResult.getReportLog(), histories).execute();
     }
 
     class RefreshTestResultsTask extends AsyncTask<Void, Void, RefreshResult> {
@@ -214,6 +224,8 @@
             mTestDetails.putAll(result.mDetails);
             mReportLogs.clear();
             mReportLogs.putAll(result.mReportLogs);
+            mHistories.clear();
+            mHistories.putAll(result.mHistories);
             notifyDataSetChanged();
         }
     }
@@ -223,16 +235,19 @@
         Map<String, Integer> mResults;
         Map<String, String> mDetails;
         Map<String, ReportLog> mReportLogs;
+        Map<String, TestResultHistoryCollection> mHistories;
 
         RefreshResult(
                 List<TestListItem> items,
                 Map<String, Integer> results,
                 Map<String, String> details,
-                Map<String, ReportLog> reportLogs) {
+                Map<String, ReportLog> reportLogs,
+                Map<String, TestResultHistoryCollection> histories) {
             mItems = items;
             mResults = results;
             mDetails = details;
             mReportLogs = reportLogs;
+            mHistories = histories;
         }
     }
 
@@ -244,12 +259,14 @@
         TestResultsProvider.COLUMN_TEST_RESULT,
         TestResultsProvider.COLUMN_TEST_DETAILS,
         TestResultsProvider.COLUMN_TEST_METRICS,
+        TestResultsProvider.COLUMN_TEST_RESULT_HISTORY,
     };
 
     RefreshResult getRefreshResults(List<TestListItem> items) {
         Map<String, Integer> results = new HashMap<String, Integer>();
         Map<String, String> details = new HashMap<String, String>();
         Map<String, ReportLog> reportLogs = new HashMap<String, ReportLog>();
+        Map<String, TestResultHistoryCollection> histories = new HashMap<>();
         ContentResolver resolver = mContext.getContentResolver();
         Cursor cursor = null;
         try {
@@ -261,9 +278,12 @@
                     int testResult = cursor.getInt(2);
                     String testDetails = cursor.getString(3);
                     ReportLog reportLog = (ReportLog) deserialize(cursor.getBlob(4));
+                    TestResultHistoryCollection historyCollection =
+                        (TestResultHistoryCollection) deserialize(cursor.getBlob(5));
                     results.put(testName, testResult);
                     details.put(testName, testDetails);
                     reportLogs.put(testName, reportLog);
+                    histories.put(testName, historyCollection);
                 } while (cursor.moveToNext());
             }
         } finally {
@@ -271,7 +291,7 @@
                 cursor.close();
             }
         }
-        return new RefreshResult(items, results, details, reportLogs);
+        return new RefreshResult(items, results, details, reportLogs, histories);
     }
 
     class ClearTestResultsTask extends AsyncTask<Void, Void, Void> {
@@ -287,27 +307,28 @@
     class SetTestResultTask extends AsyncTask<Void, Void, Void> {
 
         private final String mTestName;
-
         private final int mResult;
-
         private final String mDetails;
-
         private final ReportLog mReportLog;
+        private final TestResultHistoryCollection mHistoryCollection;
 
         SetTestResultTask(
                 String testName,
                 int result,
                 String details,
-                ReportLog reportLog) {
+                ReportLog reportLog,
+                TestResultHistoryCollection historyCollection) {
             mTestName = testName;
             mResult = result;
             mDetails = details;
             mReportLog = reportLog;
+            mHistoryCollection = historyCollection;
         }
 
         @Override
         protected Void doInBackground(Void... params) {
-            TestResultsProvider.setTestResult(mContext, mTestName, mResult, mDetails, mReportLog);
+            TestResultsProvider.setTestResult(
+                mContext, mTestName, mResult, mDetails, mReportLog, mHistoryCollection);
             return null;
         }
     }
@@ -382,6 +403,19 @@
                 : null;
     }
 
+    /**
+     * Get test result histories.
+     *
+     * @param position The position of test.
+     * @return A {@link TestResultHistoryCollection} object containing test result histories of tests.
+     */
+    public TestResultHistoryCollection getHistoryCollection(int position) {
+        TestListItem item = getItem(position);
+        return mHistories.containsKey(item.testName)
+            ? mHistories.get(item.testName)
+            : null;
+    }
+
     public boolean allTestsPassed() {
         for (TestListItem item : mRows) {
             if (item.isTest() && (!mTestResults.containsKey(item.testName)
@@ -451,7 +485,7 @@
         }
     }
 
-    private static Object deserialize(byte[] bytes) {
+    public static Object deserialize(byte[] bytes) {
         if (bytes == null || bytes.length == 0) {
             return null;
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
index 07208dd..9f867d5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
@@ -17,6 +17,7 @@
 package com.android.cts.verifier;
 
 import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.TestResultHistory;
 
 import android.app.Activity;
 import android.content.Intent;
@@ -38,11 +39,13 @@
     private static final String TEST_RESULT = "result";
     private static final String TEST_DETAILS = "details";
     private static final String TEST_METRICS = "metrics";
+    private static final String TEST_HISTORY_COLLECTION = "historyCollection";
 
     private final String mName;
     private final int mResult;
     private final String mDetails;
     private final ReportLog mReportLog;
+    private final TestResultHistoryCollection mHistoryCollection;
 
     /** Sets the test activity's result to pass. */
     public static void setPassedResult(Activity activity, String testId, String testDetails) {
@@ -53,7 +56,14 @@
     public static void setPassedResult(Activity activity, String testId, String testDetails,
             ReportLog reportLog) {
         activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_PASSED, testId,
-                testDetails, reportLog));
+            testDetails, reportLog, null /*history*/));
+    }
+
+    /** Sets the test activity's result to pass including a test report log result and history. */
+    public static void setPassedResult(Activity activity, String testId, String testDetails,
+            ReportLog reportLog, TestResultHistoryCollection historyCollection) {
+        activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_PASSED, testId,
+                testDetails, reportLog, historyCollection));
     }
 
     /** Sets the test activity's result to failed. */
@@ -65,22 +75,30 @@
     public static void setFailedResult(Activity activity, String testId, String testDetails,
             ReportLog reportLog) {
         activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_FAILED, testId,
-                testDetails, reportLog));
+                testDetails, reportLog, null /*history*/));
+    }
+
+    /** Sets the test activity's result to failed including a test report log result and history. */
+    public static void setFailedResult(Activity activity, String testId, String testDetails,
+            ReportLog reportLog, TestResultHistoryCollection historyCollection) {
+        activity.setResult(Activity.RESULT_OK, createResult(activity, TEST_RESULT_FAILED, testId,
+            testDetails, reportLog, historyCollection));
     }
 
     public static Intent createResult(Activity activity, int testResult, String testName,
-            String testDetails, ReportLog reportLog) {
+            String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) {
         Intent data = new Intent(activity, activity.getClass());
-        addResultData(data, testResult, testName, testDetails, reportLog);
+        addResultData(data, testResult, testName, testDetails, reportLog, historyCollection);
         return data;
     }
 
     public static void addResultData(Intent intent, int testResult, String testName,
-            String testDetails, ReportLog reportLog) {
+            String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) {
         intent.putExtra(TEST_NAME, testName);
         intent.putExtra(TEST_RESULT, testResult);
         intent.putExtra(TEST_DETAILS, testDetails);
         intent.putExtra(TEST_METRICS, reportLog);
+        intent.putExtra(TEST_HISTORY_COLLECTION, historyCollection);
     }
 
     /**
@@ -92,15 +110,20 @@
         int result = data.getIntExtra(TEST_RESULT, TEST_RESULT_NOT_EXECUTED);
         String details = data.getStringExtra(TEST_DETAILS);
         ReportLog reportLog = (ReportLog) data.getSerializableExtra(TEST_METRICS);
-        return new TestResult(name, result, details, reportLog);
+        TestResultHistoryCollection historyCollection =
+            (TestResultHistoryCollection) data.getSerializableExtra(TEST_HISTORY_COLLECTION);
+        return new TestResult(name, result, details, reportLog, historyCollection);
     }
 
     private TestResult(
-            String name, int result, String details, ReportLog reportLog) {
+            String name, int result, String details, ReportLog reportLog,
+            TestResultHistoryCollection historyCollection) {
         this.mName = name;
         this.mResult = result;
         this.mDetails = details;
         this.mReportLog = reportLog;
+        this.mHistoryCollection =
+            historyCollection == null ? new TestResultHistoryCollection() : historyCollection;
     }
 
     /** Return the name of the test like "com.android.cts.verifier.foo.FooTest" */
@@ -122,4 +145,9 @@
     public ReportLog getReportLog() {
         return mReportLog;
     }
+
+    /** @return the {@link TestResultHistoryCollection} containing test history */
+    public TestResultHistoryCollection getHistoryCollection() {
+        return mHistoryCollection;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java
new file mode 100644
index 0000000..0e7160c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java
@@ -0,0 +1,81 @@
+package com.android.cts.verifier;
+
+import com.android.compatibility.common.util.TestResultHistory;
+
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class TestResultHistoryCollection implements Serializable {
+
+    private final Set<TestResultHistory> mHistoryCollection = new HashSet<>();
+
+    /**
+     * Covert object to set.
+     *
+     * @return A set of test result history.
+     */
+    public Set<TestResultHistory> asSet() {
+        return mHistoryCollection;
+    }
+
+    /**
+     * Add a test result history with test name, start time and end time.
+     *
+     * @param test a string of test name.
+     * @param start start time of a test.
+     * @param end end time of a test.
+     */
+    public void add(String test, long start, long end) {
+        Set<Map.Entry> duration = new HashSet<>();
+        duration.add(new AbstractMap.SimpleEntry<>(start, end));
+        mHistoryCollection.add(new TestResultHistory(test, duration));
+    }
+
+    /**
+     * Add test result histories for tests containing test name and a set of execution time.
+     *
+     * @param test test name.
+     * @param durations set of start and end time.
+     */
+    public void addAll(String test, Set<Map.Entry> durations) {
+        TestResultHistory history = new TestResultHistory(test, durations);
+        boolean match = false;
+        for (TestResultHistory resultHistory: mHistoryCollection) {
+            if (resultHistory.getTestName().equals(test)) {
+                resultHistory.getDurations().addAll(durations);
+                match = true;
+                break;
+            }
+        }
+        if (match == false) {
+            mHistoryCollection.add(history);
+        }
+    }
+
+    /**
+     * Merge test with its sub-tests result histories.
+     *
+     * @param prefix optional test name prefix to apply.
+     * @param resultHistoryCollection a set of test result histories.
+     */
+    public void merge(String prefix, TestResultHistoryCollection resultHistoryCollection) {
+       if (resultHistoryCollection != null) {
+            resultHistoryCollection.asSet().forEach(t-> addAll(
+                prefix != null ? prefix + ":" + t.getTestName() : t.getTestName(), t.getDurations()));
+       }
+    }
+
+    /**
+     * Merge test with its sub-tests result histories.
+     *
+     * @param prefix optional test name prefix to apply.
+     * @param resultHistories a list of test result history collection.
+     */
+    public void merge(String prefix, List<TestResultHistoryCollection> resultHistories) {
+        resultHistories.forEach(resultHistoryCollection -> merge(prefix, resultHistoryCollection));
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
index 64c04eb..bdf32fa 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
@@ -78,6 +78,9 @@
     /** ReportLog containing the test result metrics. */
     static final String COLUMN_TEST_METRICS = "testmetrics";
 
+    /** TestResultHistory containing the test run histories. */
+    static final String COLUMN_TEST_RESULT_HISTORY = "testresulthistory";
+
     private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
     private static final int RESULTS_ALL = 1;
     private static final int RESULTS_ID = 2;
@@ -120,7 +123,8 @@
                     + COLUMN_TEST_RESULT + " INTEGER,"
                     + COLUMN_TEST_INFO_SEEN + " INTEGER DEFAULT 0,"
                     + COLUMN_TEST_DETAILS + " TEXT,"
-                    + COLUMN_TEST_METRICS + " BLOB);");
+                    + COLUMN_TEST_METRICS + " BLOB,"
+                    + COLUMN_TEST_RESULT_HISTORY + " BLOB);");
         }
 
         @Override
@@ -226,12 +230,13 @@
     }
 
     static void setTestResult(Context context, String testName, int testResult,
-            String testDetails, ReportLog reportLog) {
+            String testDetails, ReportLog reportLog, TestResultHistoryCollection historyCollection) {
         ContentValues values = new ContentValues(2);
         values.put(TestResultsProvider.COLUMN_TEST_RESULT, testResult);
         values.put(TestResultsProvider.COLUMN_TEST_NAME, testName);
         values.put(TestResultsProvider.COLUMN_TEST_DETAILS, testDetails);
         values.put(TestResultsProvider.COLUMN_TEST_METRICS, serialize(reportLog));
+        values.put(TestResultsProvider.COLUMN_TEST_RESULT_HISTORY, serialize(historyCollection));
 
         final Uri uri = getResultContentUri(context);
         ContentResolver resolver = context.getContentResolver();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
index 8893e0d..d9d63c2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
@@ -29,6 +29,7 @@
 import com.android.compatibility.common.util.ITestResult;
 import com.android.compatibility.common.util.MetricsXmlSerializer;
 import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.TestResultHistory;
 import com.android.compatibility.common.util.TestStatus;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 
@@ -38,9 +39,16 @@
 import java.io.IOException;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 /**
  * Helper class for creating an {@code InvocationResult} for CTS result generation.
@@ -135,6 +143,27 @@
                 if (reportLog != null) {
                     currentTestResult.setReportLog(reportLog);
                 }
+
+                TestResultHistoryCollection historyCollection = mAdapter.getHistoryCollection(i);
+                if (historyCollection != null) {
+                    // Get non-terminal prefixes.
+                    Set<String> prefixes = new HashSet<>();
+                    for (TestResultHistory history: historyCollection.asSet()) {
+                        Arrays.stream(history.getTestName().split(":")).reduce(
+                            (total, current) -> { prefixes.add(total);
+                            return total + ":" + current;
+                        });
+                    }
+
+                    // Filter out non-leaf test histories.
+                    List<TestResultHistory> leafTestHistories = new ArrayList<TestResultHistory>();
+                    for (TestResultHistory history: historyCollection.asSet()) {
+                        if (!prefixes.contains(history.getTestName())) {
+                            leafTestHistories.add(history);
+                        }
+                    }
+                    currentTestResult.setTestResultHistories(leafTestHistories);
+                }
             }
         }
         moduleResult.setDone(true);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
index 161cceb..7c0e475 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.Camera;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -34,13 +35,21 @@
 import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.core.content.FileProvider;
 
 import com.android.cts.verifier.camera.intents.CameraContentJobService;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestResult;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.TreeSet;
+import java.util.Date;
+import java.text.SimpleDateFormat;
 
 /**
  * Tests for manual verification of uri trigger being fired.
@@ -80,6 +89,8 @@
     private ImageButton mPassButton;
     private ImageButton mFailButton;
     private Button mStartTestButton;
+    private File mDebugFolder = null;
+    private File mImageTarget = null;
 
     private int mState = STATE_OFF;
 
@@ -271,27 +282,66 @@
     @Override
     protected void onActivityResult(
         int requestCode, int resultCode, Intent data) {
-        if (requestCode == 1337 + getStageIndex()) {
+        int stageIndex = getStageIndex();
+        if (requestCode == 1337 + stageIndex) {
             Log.v(TAG, "Activity we launched was finished");
             mActivityResult = true;
 
             if (mState != STATE_FAILED
                 && getStageIndex() == STAGE_INTENT_PICTURE) {
-                mPassButton.setEnabled(true);
-                mFailButton.setEnabled(false);
-
-                mState = STATE_SUCCESSFUL;
-                /* successful, unless we get the URI trigger back
-                 at some point later on */
+                handleIntentPictureResult();
             }
         }
     }
 
+    private void handleIntentPictureResult() {
+        if (mImageTarget == null) {
+            Log.d(TAG, "Image target was not set");
+            return;
+        }
+        try {
+            if (!mImageTarget.exists() || mImageTarget.length() == 0) {
+                Log.d(TAG, "Image target does not exist or it is empty");
+                mState = STATE_FAILED;
+                return;
+            }
+
+            try {
+                final ExifInterface exif = new ExifInterface(new FileInputStream(mImageTarget));
+                if (!checkExifAttribute(exif, ExifInterface.TAG_MAKE)
+                    || !checkExifAttribute(exif, ExifInterface.TAG_MODEL)
+                    || !checkExifAttribute(exif, ExifInterface.TAG_DATETIME)) {
+                    Log.d(TAG, "The required tag does not appear in the exif");
+                    mState = STATE_FAILED;
+                    return;
+                }
+                mState = STATE_SUCCESSFUL;
+                setPassButton(true);
+            } catch (IOException ex) {
+                Log.e(TAG, "Failed to verify Exif", ex);
+                mState = STATE_FAILED;
+                return;
+            }
+        } finally {
+            mImageTarget.delete();
+        }
+    }
+
+    private boolean checkExifAttribute(ExifInterface exif, String tag) {
+        final String res = exif.getAttribute(tag);
+        return res != null && res.length() > 0;
+    }
+
     @Override
     public String getTestDetails() {
         return mReportBuilder.toString();
     }
 
+    private void setPassButton(Boolean pass) {
+        mPassButton.setEnabled(pass);
+        mFailButton.setEnabled(!pass);
+    }
+
     private class WaitForTriggerTask extends AsyncTask<Void, Void, Boolean> {
         protected Boolean doInBackground(Void... param) {
             try {
@@ -387,7 +437,33 @@
 
             if (intentStr != null) {
                 cameraIntent = new Intent(intentStr);
-                startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                switch (stageIndex) {
+                    case STAGE_INTENT_PICTURE:
+                        mDebugFolder = new File(this.getFilesDir(), "debug");
+                        mDebugFolder.mkdirs();
+                        if (!mDebugFolder.exists()) {
+                            Toast.makeText(this, R.string.ci_directory_creation_error,
+                                    Toast.LENGTH_SHORT).show();
+                            Log.v(TAG, "Could not create directory");
+                            return;
+                        }
+
+                        File targetFile;
+                        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+                        mImageTarget = new File(mDebugFolder, timeStamp + "capture.jpg");
+                        targetFile = mImageTarget;
+                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this,
+                              "com.android.cts.verifier.managedprovisioning.fileprovider",
+                              targetFile));
+                        startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                        break;
+                    case STAGE_INTENT_VIDEO:
+                        startActivityForResult(cameraIntent, 1337 + getStageIndex());
+                        break;
+                    default:
+                        Log.wtf(TAG, "Unexpected stage index to send intent");
+                        return;
+                }
             }
 
             mStartTestButton.setEnabled(false);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 67f82d0..71dce24 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -679,6 +679,8 @@
 
     private void queryProfileOwner(boolean showToast) {
         try {
+            // Set execution start time for counting test execution time.
+            mStartTime = System.currentTimeMillis();
             Intent intent = new Intent(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
             startActivityForResult(intent, REQUEST_PROFILE_OWNER_STATUS);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index ff4f540..0cc57a8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -478,6 +478,8 @@
     }
 
     private Intent createCreateManagedUserIntent() {
+        // Set execution start time for counting test execution time.
+        mStartTime = System.currentTimeMillis();
         return new Intent(this, CommandReceiverActivity.class)
                 .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
                         CommandReceiverActivity.COMMAND_CREATE_MANAGED_USER);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java
index a49985d..2f1c21e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/RecentsRedactionActivity.java
@@ -67,7 +67,7 @@
                 throw new IllegalArgumentException("Unknown id: " + target.getId());
         }
         Intent resultIntent = TestResult.createResult(RecentsRedactionActivity.this, resultCode,
-                getTestId(), getTestDetails(), getReportLog());
+                getTestId(), getTestDetails(), getReportLog(), getHistoryCollection());
 
         new ByodFlowTestHelper(this).sendResultToPrimary(resultIntent);
         finish();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java
index c0a1626..ef2d798 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java
@@ -65,10 +65,15 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        // Set execution start time when start this activity for counting test execution time.
+        mStartTime = System.currentTimeMillis();
         mPrepareTestButton.setText(R.string.provisioning_byod_turn_off_work_prepare_button);
         mPrepareTestButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
+                // Set execution start time when users start to turn/off work profile for counting
+                // test execution time.
+                mStartTime = System.currentTimeMillis();
                 try {
                     startActivity(new Intent(Settings.ACTION_SYNC_SETTINGS));
                 } catch (ActivityNotFoundException e) {
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index 16f7610..8b1e28c 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -15,19 +15,22 @@
  */
 package com.android.compatibility.common.deviceinfo;
 
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.os.Bundle;
-
-import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import android.content.pm.PermissionInfo;
 import com.android.compatibility.common.util.DeviceInfoStore;
 
+import java.io.IOException;
+import java.util.*;
+
 /**
  * PackageDeviceInfo collector.
  */
 public class PackageDeviceInfo extends DeviceInfo {
 
     private static final String PACKAGE = "package";
+
     private static final String NAME = "name";
     private static final String VERSION_NAME = "version_name";
     private static final String SYSTEM_PRIV = "system_priv";
@@ -35,24 +38,97 @@
     private static final String MIN_SDK = "min_sdk";
     private static final String TARGET_SDK = "target_sdk";
 
+    private static final String REQUESTED_PERMISSIONS = "requested_permissions";
+    private static final String PERMISSION_NAME = "name";
+    private static final String PERMISSION_FLAGS = "flags";
+    private static final String PERMISSION_GROUP = "permission_group";
+    private static final String PERMISSION_PROTECTION = "protection_level";
+    private static final String PERMISSION_PROTECTION_FLAGS = "protection_level_flags";
+
+    private static final int SYS_UID_MAX = 10000;
+    private static final String HAS_SYSTEM_UID = "has_system_uid";
+
+    private static final String SHARES_INSTALL_PERMISSION = "shares_install_packages_permission";
+    private static final String INSTALL_PACKAGES_PERMISSION = "android.permission.INSTALL_PACKAGES";
+
     @Override
     protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
-        PackageManager pm = getContext().getPackageManager();
+        final PackageManager pm = getContext().getPackageManager();
+
+        final List<PackageInfo> allPackages = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS);
+
         store.startArray(PACKAGE);
-        for (PackageInfo pkg : pm.getInstalledPackages(0)) {
+        for (PackageInfo pkg : allPackages) {
             store.startGroup();
+
             store.addResult(NAME, pkg.packageName);
             store.addResult(VERSION_NAME, pkg.versionName);
 
-            if (pkg.applicationInfo != null) {
-                String dir = pkg.applicationInfo.sourceDir;
+            store.startArray(REQUESTED_PERMISSIONS);
+            if (pkg.requestedPermissions != null && pkg.requestedPermissions.length > 0) {
+                for (String permission : pkg.requestedPermissions) {
+                    try {
+                        final PermissionInfo pi = pm.getPermissionInfo(permission, 0);
+
+                        store.startGroup();
+                        store.addResult(PERMISSION_NAME, permission);
+                        store.addResult(PERMISSION_FLAGS, pi.flags);
+                        store.addResult(PERMISSION_GROUP, pi.group);
+                        store.addResult(PERMISSION_PROTECTION, pi.getProtection());
+                        store.addResult(PERMISSION_PROTECTION_FLAGS, pi.getProtectionFlags());
+                        store.endGroup();
+                    } catch (PackageManager.NameNotFoundException e) {
+                        // ignore unrecognized permission and continue
+                    }
+                }
+            }
+            store.endArray();
+
+            final ApplicationInfo appInfo = pkg.applicationInfo;
+            if (appInfo != null) {
+                String dir = appInfo.sourceDir;
                 store.addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
 
-                store.addResult(MIN_SDK, pkg.applicationInfo.minSdkVersion);
-                store.addResult(TARGET_SDK, pkg.applicationInfo.targetSdkVersion);
+                store.addResult(MIN_SDK, appInfo.minSdkVersion);
+                store.addResult(TARGET_SDK, appInfo.targetSdkVersion);
+
+                store.addResult(HAS_SYSTEM_UID, appInfo.uid < SYS_UID_MAX);
+
+                final boolean canInstall = sharesUidWithPackageHolding(pm, appInfo.uid, INSTALL_PACKAGES_PERMISSION);
+                store.addResult(SHARES_INSTALL_PERMISSION, canInstall);
             }
+
             store.endGroup();
         }
-        store.endArray(); // Package
+        store.endArray(); // "package"
+    }
+    private static boolean sharesUidWithPackageHolding(PackageManager pm, int uid, String permission) {
+        final String[] sharesUidWith = pm.getPackagesForUid(uid);
+
+        if (sharesUidWith == null) {
+            return false;
+        }
+
+        // Approx 20 permissions per package for rough estimate of sizing
+        final List<String> sharedPermissions = new ArrayList<>(sharesUidWith.length * 20);
+        for (String pkg :sharesUidWith){
+            try {
+                final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS);
+
+                if (info.requestedPermissions == null) {
+                    continue;
+                }
+
+                for (String p : info.requestedPermissions) {
+                    if (p != null) {
+                        sharedPermissions.add(p);
+                    }
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                // ignore, continue
+            }
+        }
+
+        return sharedPermissions.contains(permission);
     }
 }
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java
index bf5dc39..2dd54e6 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/BroadcastTestBase.java
@@ -18,11 +18,15 @@
 
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.database.ContentObserver;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 
@@ -120,4 +124,36 @@
             }
         }
     }
+
+    protected CountDownLatch registerForChanges(Uri uri) throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ContentResolver resolver = mActivity.getContentResolver();
+        mActivity.runOnUiThread(() -> {
+            resolver.registerContentObserver(uri, true,
+                    new ContentObserver(new Handler()) {
+                        @Override
+                        public void onChange(boolean selfChange) {
+                            latch.countDown();
+                            resolver.unregisterContentObserver(this);
+                        }
+                    });
+        });
+        return latch;
+    }
+
+    protected boolean startTestAndWaitForChange(BroadcastUtils.TestcaseType testCaseType, Uri uri,
+            String pkg, String cls)
+            throws Exception {
+        Log.i(TAG, "Begin Testing: " + testCaseType);
+        registerBroadcastReceiver(testCaseType);
+        CountDownLatch latch = registerForChanges(uri);
+        mActivity.startTest(testCaseType.toString(), pkg, cls);
+        if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)
+                || !latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to change in " + TIMEOUT_MS + "msec");
+            return false;
+        }
+        return true;
+    }
+
 }
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
new file mode 100644
index 0000000..bbfa2db
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/RequiredServiceRule.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 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.compatibility.common.util;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that does not run a test case if the device does not have a given service.
+ */
+public class RequiredServiceRule implements TestRule {
+    private static final String TAG = "RequiredServiceRule";
+
+    private final String mService;
+    private final boolean mHasService;
+
+    /**
+     * Creates a rule for the given service.
+     */
+    public RequiredServiceRule(@NonNull String service) {
+        mService = service;
+        mHasService = hasService(service);
+    }
+
+    @Override
+    public Statement apply(@NonNull Statement base, @NonNull Description description) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                if (!mHasService) {
+                    Log.d(TAG, "skipping "
+                            + description.getClassName() + "#" + description.getMethodName()
+                            + " because device does not have service '" + mService + "'");
+                    return;
+                }
+                base.evaluate();
+            }
+        };
+    }
+
+    /**
+     * Checks if the device has the given service.
+     */
+    public static boolean hasService(@NonNull String service) {
+        // TODO: ideally should call SystemServiceManager directly, but we would need to open
+        // some @Testing APIs for that.
+        String command = "service check " + service;
+        try {
+            String commandOutput = SystemUtil.runShellCommand(
+                    InstrumentationRegistry.getInstrumentation(), command);
+            return !commandOutput.contains("not found");
+        } catch (Exception e) {
+            Log.w(TAG, "Exception running '" + command + "': " + e);
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "RequiredServiceRule[" + mService + "]";
+    }
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index ae6849c..f27ab55 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -93,13 +93,15 @@
             }
 
             mReceivedProfileProvisionedIntent =
-                    managedProfileProvisionedReceiver.awaitForBroadcast();
+                    managedProfileProvisionedReceiver.awaitForBroadcast(
+                            TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
             if (mReceivedProfileProvisionedIntent == null) {
                 Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
 
-            if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+            if (managedProfileAddedReceiver.awaitForBroadcast(
+                    TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
                 Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index 05edf1a..59f3ebf 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -93,13 +93,15 @@
             }
 
             mReceivedProfileProvisionedIntent =
-                    managedProfileProvisionedReceiver.awaitForBroadcast();
+                    managedProfileProvisionedReceiver.awaitForBroadcast(
+                            TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
             if (mReceivedProfileProvisionedIntent == null) {
                 Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
 
-            if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+            if (managedProfileAddedReceiver.awaitForBroadcast(
+                    TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
                 Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
index 6188303..6be6612 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTestCase.java
@@ -147,7 +147,8 @@
 
     protected boolean supportedHardwareForScopedDirectoryAccess() {
         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
-        if (pm.hasSystemFeature("android.hardware.type.watch")
+        if (pm.hasSystemFeature("android.hardware.type.television")
+                || pm.hasSystemFeature("android.hardware.type.watch")
                 || pm.hasSystemFeature("android.hardware.type.automotive")) {
             return false;
         }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index 99b310e..74706c9 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -324,7 +324,7 @@
 
     private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
         assertTrue("Cert installer did not respond in time.",
-                mAvailableResultSemaphore.tryAcquire(10, TimeUnit.SECONDS));
+                mAvailableResultSemaphore.tryAcquire(60, TimeUnit.SECONDS));
         synchronized (this) {
             if (expectSuccess) {
                 assertTrue(testName + " failed unexpectedly.", mReceivedResult);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 0280bdf..86af199 100755
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -59,7 +59,7 @@
     private static final String SERIAL_EXTRA = "serialExtra";
     private static final String PROFILE_OWNER_EXTRA = "profileOwnerExtra";
     private static final String SETUP_COMPLETE_EXTRA = "setupCompleteExtra";
-    private static final int BROADCAST_TIMEOUT = 15_000;
+    private static final int BROADCAST_TIMEOUT = 60_000;
     private static final int USER_SWITCH_DELAY = 10_000;
 
     private static final String AFFILIATION_ID = "affiliation.id";
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
index 8f1f88e..9ddc92f 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
@@ -176,7 +176,8 @@
                         UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE);
             }
             // Wait for the restriction to apply
-            assertTrue("Restriction not applied after 5 seconds", latch.await(5, TimeUnit.SECONDS));
+            assertTrue("Restriction not applied after 60 seconds",
+                    latch.await(60, TimeUnit.SECONDS));
         } finally {
             mContext.unregisterReceiver(receiver);
         }
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java
index f39dbbe..65c952f 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferDeviceOwnerIncomingTest.java
@@ -38,7 +38,7 @@
         assertEquals(Collections.singletonList("test.package"),
                 mDevicePolicyManager.getKeepUninstalledPackages(mIncomingComponentName));
         assertEquals(123, mDevicePolicyManager.getPasswordMinimumLength(mIncomingComponentName));
-        assertSystemPoliciesEqual(SystemUpdatePolicy.createWindowedInstallPolicy(123, 456),
+        assertSystemPoliciesEqual(SystemUpdatePolicy.createPostponeInstallPolicy(),
                 mDevicePolicyManager.getSystemUpdatePolicy());
         assertThrows(SecurityException.class, () -> {
             mDevicePolicyManager.getParentProfileInstance(mIncomingComponentName);
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java
index b42b2bd..ce8736f 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerOutgoingApp/src/com/android/cts/transferowner/TransferDeviceOwnerOutgoingTest.java
@@ -47,7 +47,7 @@
         mDevicePolicyManager.setKeepUninstalledPackages(mOutgoingComponentName,
                 Collections.singletonList("test.package"));
         mDevicePolicyManager.setSystemUpdatePolicy(mOutgoingComponentName,
-                SystemUpdatePolicy.createWindowedInstallPolicy(123, 456));
+                SystemUpdatePolicy.createPostponeInstallPolicy());
 
         PersistableBundle b = new PersistableBundle();
         mDevicePolicyManager.transferOwnership(mOutgoingComponentName, INCOMING_COMPONENT_NAME, b);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index edc2ff6..1135318 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -620,6 +620,11 @@
             return;
         }
 
+        if (!hasService("wallpaper")) {
+            CLog.d("testSetWallpaper_disallowed(): device does not support wallpapers");
+            return;
+        }
+
         installAppAsUser(CUSTOMIZATION_APP_APK, mUserId);
         try {
             changeUserRestrictionOrFail(DISALLOW_SET_WALLPAPER, true, mUserId);
@@ -636,6 +641,10 @@
         if (!mHasFeature) {
             return;
         }
+        if (!hasService("wallpaper")) {
+            CLog.d("testDisallowSetWallpaper_allowed(): device does not support wallpapers");
+            return;
+        }
         executeDeviceTestMethod(".CustomizationRestrictionsTest",
                 "testDisallowSetWallpaper_allowed");
     }
@@ -1144,4 +1153,19 @@
         getDevice().executeShellCommand(
                 restricted ? RESTRICT_BACKGROUND_ON_CMD : RESTRICT_BACKGROUND_OFF_CMD);
     }
+
+    // TODO: copied from RequiredServiceRule, which is on compatibility-device-util
+    // (and we use compatibility-host-util)
+    public boolean hasService(String service) {
+        // TODO: ideally should call SystemServiceManager directly, but we would need to open
+        // some @Testing APIs for that.
+        String command = "service check " + service;
+        try {
+            String commandOutput = getDevice().executeShellCommand(command);
+            return !commandOutput.contains("not found");
+        } catch (Exception e) {
+            CLog.w("Exception running '" + command + "': " + e);
+            return false;
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 83e8de2..09c7a4c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -623,7 +623,8 @@
         if (!mHasFeature) {
             return;
         }
-        executeDeviceOwnerTest("SystemUpdatePolicyTest");
+        // Disabled due to 145932189
+        // executeDeviceOwnerTest("SystemUpdatePolicyTest");
     }
 
     public void testWifiConfigLockdown() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index b81afd2..d551872 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -85,7 +85,7 @@
 
     private static final String PROFILE_CREDENTIAL = "1234";
     // This should be sufficiently larger than ProfileTimeoutTestHelper.TIMEOUT_MS
-    private static final int PROFILE_TIMEOUT_DELAY_MS = 10_000;
+    private static final int PROFILE_TIMEOUT_DELAY_MS = 60_000;
 
     //The maximum time to wait for user to be unlocked.
     private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
old mode 100644
new mode 100755
diff --git a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
index 65fd3ff..1bbc601 100644
--- a/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
+++ b/hostsidetests/incident/apps/graphicsstatsapp/src/com/android/server/cts/device/graphicsstats/DrawFramesActivity.java
@@ -123,6 +123,7 @@
     }
 
     private void scheduleDraw() {
+        mColorView.invalidate();
         mChoreographer.postFrameCallback((long timestamp) -> {
             setupFrame();
             jankIf(FRAME_JANK_ANIMATION);
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index 23e2d6c..23355a6 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -78,7 +78,7 @@
     /** ID of the config, which evaluates to -1572883457. */
     public static final long CONFIG_ID = "cts_config".hashCode();
 
-    protected static final int WAIT_TIME_SHORT = 500;
+    protected static final int WAIT_TIME_SHORT = 1000;
     protected static final int WAIT_TIME_LONG = 2_000;
 
     protected static final long SCREEN_STATE_CHANGE_TIMEOUT = 4000;
diff --git a/hostsidetests/theme/app/Android.mk b/hostsidetests/theme/app/Android.mk
index 1d5a6f0..90999f8 100644
--- a/hostsidetests/theme/app/Android.mk
+++ b/hostsidetests/theme/app/Android.mk
@@ -38,6 +38,6 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
 
-LOCAL_SDK_VERSION := 23
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml
index 0f3c1de..a351a01 100755
--- a/hostsidetests/theme/app/AndroidManifest.xml
+++ b/hostsidetests/theme/app/AndroidManifest.xml
@@ -18,8 +18,6 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.theme.app">
 
-    <uses-sdk android:minSdkVersion="17" />
-
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
diff --git a/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java b/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java
index 844c578..e007129 100644
--- a/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/LayoutModifier.java
@@ -23,12 +23,19 @@
  */
 public interface LayoutModifier {
 
-    /** Actions to take before inflating the view. */
-    void prepare();
+    /**
+     * Modifies the view before it has been added to a parent. Useful for avoiding animations in
+     * response to setter calls.
+     *
+     * @param view the view inflated by the test activity
+     */
+    void modifyViewBeforeAdd(View view);
 
     /**
-     * @param view inflated by the test activity
-     * @return the same view or another view that will be snapshotted by the test
+     * Modifies the view after it has been added to a parent. Useful for running animations in
+     * response to setter calls.
+     *
+     * @param view the view inflated by the test activity
      */
-    View modifyView(View view);
+    void modifyViewAfterAdd(View view);
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
index 6e0731d..3707bb1 100644
--- a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
+++ b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
@@ -16,26 +16,47 @@
 
 package android.theme.app;
 
-import android.test.ActivityInstrumentationTestCase2;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Instrumentation;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.File;
 
 /**
- * Activity test case used to instrument generation of reference images.
+ * Test used to instrument generation of reference images.
  */
-public class ReferenceImagesTest extends ActivityInstrumentationTestCase2<GenerateImagesActivity> {
+@RunWith(AndroidJUnit4.class)
+public class ReferenceImagesTest {
+    private Instrumentation mInstrumentation;
+    private GenerateImagesActivity mActivity;
 
-    /** Overall test timeout is 30 minutes. Should only take about 5. */
+    // Overall test timeout is 30 minutes. Should only take about 5.
     private static final int TEST_RESULT_TIMEOUT = 30 * 60 * 1000;
 
-    public ReferenceImagesTest() {
-        super(GenerateImagesActivity.class);
+    @Rule
+    public ActivityTestRule<GenerateImagesActivity> mActivityRule =
+        new ActivityTestRule<>(GenerateImagesActivity.class);
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mInstrumentation.setInTouchMode(true);
+
+        mActivity = mActivityRule.getActivity();
     }
 
+    @Test
     public void testGenerateReferenceImages() throws Exception {
-        setActivityInitialTouchMode(true);
-
-        final GenerateImagesActivity activity = getActivity();
+        final GenerateImagesActivity activity = mActivity;
         assertTrue("Activity failed to complete within " + TEST_RESULT_TIMEOUT + " ms",
                 activity.waitForCompletion(TEST_RESULT_TIMEOUT));
         assertTrue(activity.getFinishReason(), activity.isFinishSuccess());
diff --git a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
index 9469a0c..2e3b97a 100644
--- a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
@@ -16,7 +16,9 @@
 
 package android.theme.app;
 
+import android.animation.ValueAnimator;
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Build;
@@ -28,6 +30,7 @@
 import android.theme.app.modifiers.ViewCheckedModifier;
 import android.theme.app.modifiers.ViewPressedModifier;
 import android.util.Log;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager.LayoutParams;
 import android.widget.DatePicker;
@@ -76,15 +79,20 @@
         mOutputDir = new File(outputDir);
         mTheme = THEMES[themeIndex];
 
-        setTheme(mTheme.id);
+        // Disable animations.
+        ValueAnimator.setDurationScale(0);
 
         // Force text scaling to 1.0 regardless of system default.
         Configuration config = new Configuration();
         config.fontScale = 1.0f;
-        getResources().updateConfiguration(config, null);
-        setContentView(R.layout.theme_test);
 
-        mViewGroup = (ReferenceViewGroup) findViewById(R.id.reference_view_group);
+        Context inflationContext = createConfigurationContext(config);
+        inflationContext.setTheme(mTheme.id);
+
+        LayoutInflater layoutInflater = LayoutInflater.from(inflationContext);
+        setContentView(layoutInflater.inflate(R.layout.theme_test, null));
+
+        mViewGroup = findViewById(R.id.reference_view_group);
 
         getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
                 | LayoutParams.FLAG_TURN_SCREEN_ON
@@ -139,24 +147,26 @@
         mViewGroup.removeAllViews();
 
         final Layout layout = LAYOUTS[mLayoutIndex++];
+        final LayoutModifier modifier = layout.modifier;
         final String layoutName = String.format("%s_%s", mTheme.name, layout.name);
-        final View view = getLayoutInflater().inflate(layout.id, mViewGroup, false);
-        if (layout.modifier != null) {
-            layout.modifier.modifyView(view);
+        final LayoutInflater layoutInflater = LayoutInflater.from(mViewGroup.getContext());
+        final View view = layoutInflater.inflate(layout.id, mViewGroup, false);
+        if (modifier != null) {
+            modifier.modifyViewBeforeAdd(view);
         }
+        view.setFocusable(false);
 
         mViewGroup.addView(view);
-        view.setFocusable(false);
+
+        if (modifier != null) {
+            modifier.modifyViewAfterAdd(view);
+        }
 
         Log.v(TAG, "Rendering layout " + layoutName
                 + " (" + mLayoutIndex + "/" + LAYOUTS.length + ")");
 
-        final Runnable generateBitmapRunnable = new Runnable() {
-            @Override
-            public void run() {
-                new BitmapTask(view, layoutName).execute();
-            }
-        };
+        final Runnable generateBitmapRunnable = () ->
+            new BitmapTask(view, layoutName, modifier).execute();
 
         if (view instanceof DatePicker && mTheme.spec == Theme.HOLO) {
             // The Holo-styled DatePicker uses a CalendarView that has a
@@ -168,8 +178,12 @@
     }
 
     private class BitmapTask extends GenerateBitmapTask {
-        public BitmapTask(View view, String name) {
+        private final LayoutModifier mLayoutModifier;
+
+        public BitmapTask(View view, String name, LayoutModifier modifier) {
             super(view, mOutputDir, name);
+
+            mLayoutModifier = modifier;
         }
 
         @Override
@@ -205,6 +219,7 @@
     }
 
     // List of themes to verify.
+    @SuppressWarnings("deprecation")
     static final Theme[] THEMES = {
             // Holo
             new Theme(Theme.HOLO, android.R.style.Theme_Holo,
@@ -397,15 +412,17 @@
             new Layout(R.layout.radiobutton, "radiobutton"),
             new Layout(R.layout.radiogroup_horizontal, "radiogroup_horizontal"),
             new Layout(R.layout.radiogroup_vertical, "radiogroup_vertical"),
-            new Layout(R.layout.ratingbar_0, "ratingbar_0"),
-            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
-            new Layout(R.layout.ratingbar_5, "ratingbar_5"),
-            new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
-                    new ViewPressedModifier()),
-            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
-                    new ViewPressedModifier()),
-            new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
-                    new ViewPressedModifier()),
+            // Temporarily remove tests for the RatingBar widget. It has indeterminate rendering
+            // behavior on 360dpi devices, but we don't know why yet.
+            //new Layout(R.layout.ratingbar_0, "ratingbar_0"),
+            //new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
+            //new Layout(R.layout.ratingbar_5, "ratingbar_5"),
+            //new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
+            //        new ViewPressedModifier()),
+            //new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
+            //        new ViewPressedModifier()),
+            //new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
+            //        new ViewPressedModifier()),
             new Layout(R.layout.searchview, "searchview_query",
                     new SearchViewModifier(SearchViewModifier.QUERY)),
             new Layout(R.layout.searchview, "searchview_query_hint",
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java
index 5c945ef..e9dca7a 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/AbstractLayoutModifier.java
@@ -17,13 +17,18 @@
 package android.theme.app.modifiers;
 
 import android.theme.app.LayoutModifier;
+import android.view.View;
 
 /**
- * {@link LayoutModifier} that does nothing in {@link #prepare()}.
+ * {@link LayoutModifier} that does nothing.
  */
 abstract class AbstractLayoutModifier implements LayoutModifier {
 
     @Override
-    public void prepare() {
+    public void modifyViewBeforeAdd(View view) {
+    }
+
+    @Override
+    public void modifyViewAfterAdd(View view) {
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java
index 26ccd67..f155fcb 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/DatePickerModifier.java
@@ -26,9 +26,8 @@
 public class DatePickerModifier extends AbstractLayoutModifier {
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewAfterAdd(View view) {
         DatePicker tp = (DatePicker) view;
         tp.updateDate(2011, 4, 20);
-        return view;
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java
index 9849a64..dcd8c89 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ProgressBarModifier.java
@@ -16,6 +16,7 @@
 
 package android.theme.app.modifiers;
 
+import android.animation.ValueAnimator;
 import android.view.View;
 import android.view.animation.Interpolator;
 import android.widget.ProgressBar;
@@ -23,10 +24,9 @@
 public class ProgressBarModifier extends AbstractLayoutModifier {
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewBeforeAdd(View view) {
         ProgressBar pb = (ProgressBar) view;
         pb.setInterpolator(new ZeroInterpolator());
-        return pb;
     }
 
     private static class ZeroInterpolator implements Interpolator {
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java
index 75dd20a..de341ce 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/SearchViewModifier.java
@@ -34,7 +34,7 @@
     }
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewBeforeAdd(View view) {
         SearchView searchView = (SearchView) view;
         Context context = view.getContext();
 
@@ -52,6 +52,5 @@
         }
 
         searchView.setIconifiedByDefault(false);
-        return searchView;
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java
index b2ed4ef..8e06ad8 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/TimePickerModifier.java
@@ -22,11 +22,10 @@
 public class TimePickerModifier extends AbstractLayoutModifier {
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewBeforeAdd(View view) {
         TimePicker timePicker = (TimePicker) view;
         timePicker.setIs24HourView(true);
         timePicker.setCurrentHour(13);
         timePicker.setCurrentMinute(37);
-        return view;
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java
index f55f057..7810219 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewCheckedModifier.java
@@ -22,8 +22,7 @@
 public class ViewCheckedModifier extends AbstractLayoutModifier {
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewBeforeAdd(View view) {
         ((CheckBox) view).setChecked(true);
-        return view;
     }
 }
diff --git a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java
index a94962d..78b329c 100644
--- a/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java
+++ b/hostsidetests/theme/app/src/android/theme/app/modifiers/ViewPressedModifier.java
@@ -21,8 +21,7 @@
 public class ViewPressedModifier extends AbstractLayoutModifier {
 
     @Override
-    public View modifyView(View view) {
+    public void modifyViewBeforeAdd(View view) {
         view.setPressed(true);
-        return view;
     }
 }
diff --git a/tests/app/src/android/app/cts/WallpaperManagerTest.java b/tests/app/src/android/app/cts/WallpaperManagerTest.java
index a2a0e449..0f49281 100644
--- a/tests/app/src/android/app/cts/WallpaperManagerTest.java
+++ b/tests/app/src/android/app/cts/WallpaperManagerTest.java
@@ -16,6 +16,7 @@
 
 package android.app.cts;
 
+import static org.junit.Assume.assumeTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.nullable;
@@ -74,6 +75,7 @@
         MockitoAnnotations.initMocks(this);
         mContext = InstrumentationRegistry.getTargetContext();
         mWallpaperManager = WallpaperManager.getInstance(mContext);
+        assumeTrue("Device does not support wallpapers", mWallpaperManager.isWallpaperSupported());
         final HandlerThread handlerThread = new HandlerThread("TestCallbacks");
         handlerThread.start();
         mHandler = new Handler(handlerThread.getLooper());
@@ -466,4 +468,4 @@
         public void onColorsChanged(WallpaperColors colors, int which) {
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
index 83ceabd..b286695 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/DisplaySizeTest.java
@@ -111,10 +111,10 @@
         private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
 
         void setUnsupportedDensity() {
-            // Set device to 0.85 zoom. It doesn't matter that we're zooming out
+            // Set device to 6x zoom. It doesn't matter that we're zooming in
             // since the feature verifies that we're in a non-default density.
             final int stableDensity = getStableDensity();
-            final int targetDensity = (int) (stableDensity * 0.85);
+            final int targetDensity = (int) (stableDensity * 6);
             setDensity(targetDensity);
         }
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java
index b43b06d..157a83a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTestActivity.java
@@ -25,6 +25,7 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.view.Gravity;
 import android.view.Window;
 import android.view.WindowManager.LayoutParams;
@@ -56,7 +57,7 @@
     static final String TEST_WITH_MARGINS = "WithMargins";
 
     private AlertDialog mDialog;
-    int mSize;
+    int mSize = 200;
 
     @Override
     protected void onStop() {
@@ -72,7 +73,9 @@
 
     private void setupTest(Intent intent) {
         final String testCase = intent.getStringExtra(EXTRA_TEST_CASE);
-        mSize = getSize();
+        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            mSize = getSize();
+        }
         switch (testCase) {
             case TEST_MATCH_PARENT:
                 testMatchParent();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index 00eb590..7fd635e 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -35,6 +35,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.content.ComponentName;
+import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.platform.test.annotations.AppModeFull;
 import android.server.am.WaitForValidActivityState;
@@ -74,7 +75,10 @@
             super.setUp();
         } catch (Exception ex) {
         }
-        mSize = getSize();
+        PackageManager packageManager = InstrumentationRegistry.getContext().getPackageManager();
+        if (!packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            mSize = getSize();
+        }
     }
     
     @Override
diff --git a/tests/tests/app.usage/res/xml/network_security_config.xml b/tests/tests/app.usage/res/xml/network_security_config.xml
index 341cc7b..12ed658 100644
--- a/tests/tests/app.usage/res/xml/network_security_config.xml
+++ b/tests/tests/app.usage/res/xml/network_security_config.xml
@@ -15,6 +15,6 @@
 -->
 <network-security-config>
     <domain-config cleartextTrafficPermitted="true">
-        <domain includeSubdomains="true">www.265.com</domain>
+        <domain includeSubdomains="true">www.developer.android.com</domain>
     </domain-config>
 </network-security-config>
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
index fe8cd6e..f1711f4 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
@@ -71,7 +71,12 @@
     private static final long MINUTE = 1000 * 60;
     private static final int TIMEOUT_MILLIS = 15000;
 
-    private static final String CHECK_CONNECTIVITY_URL = "http://www.265.com/";
+    // The URL needs to return >61KB of data, since the tagged bytes are compared to total bytes
+    // and they need to be within +/-10% of each other. There is a ~6.1KB constant difference
+    // between the total and the tagged byte counts.
+    // This URL in particular was chosen, as it is accessible from inside PRoC, and is not blocked
+    // by our partners' firewalls.
+    private static final String CHECK_CONNECTIVITY_URL = "https://developer.android.com/guide";
     private static final String CHECK_CALLBACK_URL = CHECK_CONNECTIVITY_URL;
 
     private static final int NETWORK_TAG = 0xf00d;
diff --git a/tests/tests/car/src/android/car/cts/PermissionTest.java b/tests/tests/car/src/android/car/cts/PermissionTest.java
new file mode 100644
index 0000000..1ab0a8a
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/PermissionTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 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.car.cts;
+
+import static android.car.Car.PERMISSION_CAR_TEST_SERVICE;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.platform.test.annotations.RequiresDevice;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.FeatureUtil;
+
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RequiresDevice
+@RunWith(AndroidJUnit4.class)
+public class PermissionTest {
+    @Before
+    public void setUp() {
+        assumeTrue(FeatureUtil.isAutomotive());
+    }
+
+    @Test
+    public void testNoCarTestServicePermission() {
+        // This test is valid only in user build.
+        assumeTrue(Build.TYPE.equals("user"));
+
+        PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        List<PackageInfo> holders = pm.getPackagesHoldingPermissions(new String[] {
+                PERMISSION_CAR_TEST_SERVICE
+        }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
+
+        assertTrue("No pre-installed packages can have PERMISSION_CAR_TEST_SERVICE: " + holders,
+                holders.size() == 0);
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index a01e9e0..b2b5753 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -18,6 +18,7 @@
 
 import android.content.cts.R;
 
+import android.app.WallpaperManager;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -265,6 +266,8 @@
     }
 
     public void testAccessWallpaper() throws IOException, InterruptedException {
+        if (!isWallpaperSupported()) return;
+
         // set Wallpaper by contextWrapper#setWallpaper(Bitmap)
         Bitmap bitmap = Bitmap.createBitmap(20, 30, Bitmap.Config.RGB_565);
         // Test getWallpaper
@@ -499,6 +502,8 @@
     }
 
     public void testGetWallpaperDesiredMinimumHeightAndWidth() {
+        if (!isWallpaperSupported()) return;
+
         int height = mContextWrapper.getWallpaperDesiredMinimumHeight();
         int width = mContextWrapper.getWallpaperDesiredMinimumWidth();
 
@@ -832,6 +837,10 @@
         }
     }
 
+    private boolean isWallpaperSupported() {
+        return WallpaperManager.getInstance(mContext).isWallpaperSupported();
+    }
+
     private static final class MockContextWrapper extends ContextWrapper {
         public MockContextWrapper(Context base) {
             super(base);
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java
index 97b0b8f..4479a5d 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java
@@ -18,6 +18,7 @@
 
 
 import android.content.Context;
+import android.content.ContentValues;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteCursor;
 import android.database.sqlite.SQLiteCursorDriver;
@@ -28,12 +29,15 @@
 import android.os.OperationCanceledException;
 import android.test.AndroidTestCase;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Semaphore;
 
 public class SQLiteQueryBuilderTest extends AndroidTestCase {
     private SQLiteDatabase mDatabase;
+    private SQLiteQueryBuilder mStrictBuilder;
+
     private final String TEST_TABLE_NAME = "test";
     private final String EMPLOYEE_TABLE_NAME = "employee";
     private static final String DATABASE_FILE = "database_test.db";
@@ -45,6 +49,9 @@
         getContext().deleteDatabase(DATABASE_FILE);
         mDatabase = getContext().openOrCreateDatabase(DATABASE_FILE, Context.MODE_PRIVATE, null);
         assertNotNull(mDatabase);
+
+        createEmployeeTable();
+        createStrictQueryBuilder();
     }
 
     @Override
@@ -202,8 +209,6 @@
     }
 
     public void testQuery() {
-        createEmployeeTable();
-
         SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
         sqliteQueryBuilder.setTables("Employee");
         Cursor cursor = sqliteQueryBuilder.query(mDatabase,
@@ -276,8 +281,6 @@
     }
 
     public void testCancelableQuery_WhenNotCanceled_ReturnsResultSet() {
-        createEmployeeTable();
-
         CancellationSignal cancellationSignal = new CancellationSignal();
         SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
         sqliteQueryBuilder.setTables("Employee");
@@ -289,8 +292,6 @@
     }
 
     public void testCancelableQuery_WhenCanceledBeforeQuery_ThrowsImmediately() {
-        createEmployeeTable();
-
         CancellationSignal cancellationSignal = new CancellationSignal();
         SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
         sqliteQueryBuilder.setTables("Employee");
@@ -307,8 +308,6 @@
     }
 
     public void testCancelableQuery_WhenCanceledAfterQuery_ThrowsWhenExecuted() {
-        createEmployeeTable();
-
         CancellationSignal cancellationSignal = new CancellationSignal();
         SQLiteQueryBuilder sqliteQueryBuilder = new SQLiteQueryBuilder();
         sqliteQueryBuilder.setTables("Employee");
@@ -327,8 +326,6 @@
     }
 
     public void testCancelableQuery_WhenCanceledDueToContention_StopsWaitingAndThrows() {
-        createEmployeeTable();
-
         for (int i = 0; i < 5; i++) {
             final CancellationSignal cancellationSignal = new CancellationSignal();
             final Semaphore barrier1 = new Semaphore(0);
@@ -460,6 +457,152 @@
         fail("Could not prove that the query actually canceled midway during execution.");
     }
 
+    public void testStrictQuery() throws Exception {
+        final SQLiteQueryBuilder qb = mStrictBuilder;
+
+        // Should normally only be able to see one row
+        try (Cursor c = qb.query(mDatabase, null, null, null, null, null, null)) {
+            assertEquals(1, c.getCount());
+        }
+
+        // Trying sneaky queries should fail; even if they somehow succeed, we
+        // shouldn't get to see any other data.
+        try (Cursor c = qb.query(mDatabase, null, "1=1", null, null, null, null)) {
+            assertEquals(1, c.getCount());
+        } catch (Exception tolerated) {
+        }
+        try (Cursor c = qb.query(mDatabase, null, "1=1 --", null, null, null, null)) {
+            assertEquals(1, c.getCount());
+        } catch (Exception tolerated) {
+        }
+        try (Cursor c = qb.query(mDatabase, null, "1=1) OR (1=1", null, null, null, null)) {
+            assertEquals(1, c.getCount());
+        } catch (Exception tolerated) {
+        }
+        try (Cursor c = qb.query(mDatabase, null, "1=1)) OR ((1=1", null, null, null, null)) {
+            assertEquals(1, c.getCount());
+        } catch (Exception tolerated) {
+        }
+    }
+
+    private static final String[] COLUMNS_VALID = new String[] {
+            "_id",
+    };
+
+    private static final String[] COLUMNS_INVALID = new String[] {
+            "salary",
+            "MAX(salary)",
+            "undefined",
+            "(secret_column IN secret_table)",
+            "(SELECT secret_column FROM secret_table)",
+    };
+
+    public void testStrictQueryProjection() throws Exception {
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryValid(
+                    new String[] { column }, null, null, null, null, null, null);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    new String[] { column }, null, null, null, null, null, null);
+        }
+    }
+
+    public void testStrictQueryWhere() throws Exception {
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryValid(
+                    null, column + ">0", null, null, null, null, null);
+            assertStrictQueryValid(
+                    null, "_id>" + column, null, null, null, null, null);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    null, column + ">0", null, null, null, null, null);
+            assertStrictQueryInvalid(
+                    null, "_id>" + column, null, null, null, null, null);
+        }
+    }
+
+    public void testStrictQueryGroupBy() {
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryValid(
+                    null, null, null, column, null, null, null);
+            assertStrictQueryValid(
+                    null, null, null, "_id," + column, null, null, null);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    null, null, null, column, null, null, null);
+            assertStrictQueryInvalid(
+                    null, null, null, "_id," + column, null, null, null);
+        }
+    }
+
+    public void testStrictQueryHaving() {
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryValid(
+                    null, null, null, "_id", column, null, null);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    null, null, null, "_id", column, null, null);
+        }
+    }
+
+    public void testStrictQueryOrderBy() {
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryValid(
+                    null, null, null, null, null, column, null);
+            assertStrictQueryValid(
+                    null, null, null, null, null, column + " ASC", null);
+            assertStrictQueryValid(
+                    null, null, null, null, null, "_id COLLATE NOCASE ASC," + column, null);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    null, null, null, null, null, column, null);
+            assertStrictQueryInvalid(
+                    null, null, null, null, null, column + " ASC", null);
+            assertStrictQueryInvalid(
+                    null, null, null, null, null, "_id COLLATE NOCASE ASC," + column, null);
+        }
+    }
+
+    public void testStrictQueryLimit() {
+        assertStrictQueryValid(
+                null, null, null, null, null, null, "32");
+        assertStrictQueryValid(
+                null, null, null, null, null, null, "0,32");
+        assertStrictQueryValid(
+                null, null, null, null, null, null, "32 OFFSET 0");
+
+        for (String column : COLUMNS_VALID) {
+            assertStrictQueryInvalid(
+                    null, null, null, null, null, null, column);
+        }
+        for (String column : COLUMNS_INVALID) {
+            assertStrictQueryInvalid(
+                    null, null, null, null, null, null, column);
+        }
+    }
+
+    private void assertStrictQueryValid(String[] projectionIn, String selection,
+            String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) {
+        try (Cursor c = mStrictBuilder.query(mDatabase, projectionIn, selection, selectionArgs,
+                groupBy, having, sortOrder, limit, null)) {
+        }
+    }
+
+    private void assertStrictQueryInvalid(String[] projectionIn, String selection,
+            String[] selectionArgs, String groupBy, String having, String sortOrder, String limit) {
+        try (Cursor c = mStrictBuilder.query(mDatabase, projectionIn, selection, selectionArgs,
+                groupBy, having, sortOrder, limit, null)) {
+            fail(Arrays.asList(projectionIn, selection, selectionArgs,
+                    groupBy, having, sortOrder, limit).toString());
+        } catch (Exception expected) {
+        }
+    }
+
     private void createEmployeeTable() {
         mDatabase.execSQL("CREATE TABLE employee (_id INTEGER PRIMARY KEY, " +
                 "name TEXT, month INTEGER, salary INTEGER);");
@@ -476,4 +619,17 @@
         mDatabase.execSQL("INSERT INTO employee (name, month, salary) " +
                 "VALUES ('Jim', '3', '3500');");
     }
+
+    private void createStrictQueryBuilder() {
+        mStrictBuilder = new SQLiteQueryBuilder();
+        mStrictBuilder.setTables("employee");
+        mStrictBuilder.setStrict(true);
+        mStrictBuilder.appendWhere("month=2");
+
+        final Map<String, String> projectionMap = new HashMap<>();
+        projectionMap.put("_id", "_id");
+        projectionMap.put("name", "name");
+        projectionMap.put("month", "month");
+        mStrictBuilder.setProjectionMap(projectionMap);
+    }
 }
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 8ba89a2..4e71dc0 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1043,6 +1043,14 @@
         GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, GL_DEPTH24_STENCIL8
     };
     GLuint& fbo = mFramebuffers[mWhich];
+    GLbitfield clear_bits[] = {
+        GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT,
+        GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
+    };
+
+    glClearColor(0.f, 0.f, 0.f, 0.f);
+    glClearDepthf(1.0f);
+    glClearStencil(0);
     glGenFramebuffers(1, &fbo);
     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
     for (int i = 0; i < 4; ++i) {
@@ -1069,7 +1077,8 @@
                 glGenRenderbuffers(1, &renderbuffer);
                 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
                 ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
-                if (GetParam().stride & kGlFormat) {
+                bool isGlFormat = GetParam().stride & kGlFormat;
+                if (isGlFormat) {
                     glRenderbufferStorage(GL_RENDERBUFFER, GetParam().format, width, height);
                 } else {
                     glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
@@ -1077,6 +1086,8 @@
                 }
                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
                                           GL_RENDERBUFFER, renderbuffer);
+                if (isGlFormat)
+                    glClear(clear_bits[i]);
                 break;
             }
             case kRenderbuffer: {
@@ -1087,8 +1098,7 @@
                 glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height);
                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
                                           GL_RENDERBUFFER, renderbuffer);
-                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+                glClear(clear_bits[i]);
                 break;
             }
             default: FAIL() << "Unrecognized binding type";
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index d3235da..9fb7ac4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -34,7 +34,6 @@
 
 public class WifiEnterpriseConfigTest extends AndroidTestCase {
     private  WifiManager mWifiManager;
-
     private static final String SSID = "\"TestSSID\"";
     private static final String IDENTITY = "identity";
     private static final String PASSWORD = "password";
@@ -684,6 +683,9 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        if(!hasWifi()) {
+            return;
+        }
         mWifiManager = (WifiManager) mContext
                 .getSystemService(Context.WIFI_SERVICE);
         assertNotNull(mWifiManager);
@@ -802,6 +804,9 @@
     }
 
     public void testEnterpriseConfigDoesNotPrintPassword() {
+        if(!hasWifi()) {
+            return;
+        }
         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
         final String identity = "IdentityIsOkayToBeDisplayedHere";
         final String password = "PasswordIsNotOkayToBeDisplayedHere";
diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java
index cef9e2f..1b8cf77 100644
--- a/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java
+++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigCtsActivity.java
@@ -16,83 +16,176 @@
 
 package android.opengl.cts;
 
+import static org.junit.Assert.assertTrue;
+
 import android.app.Activity;
-import android.content.Intent;
+import android.content.Context;
 import android.opengl.GLSurfaceView;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.WindowManager;
 
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+
 /**
  * {@link Activity} with a {@link GLSurfaceView} that chooses a specific configuration.
  */
 public class EglConfigCtsActivity extends Activity {
 
+    private final String TAG = this.getClass().getSimpleName();
+
     public static final String CONFIG_ID_EXTRA = "eglConfigId";
 
     public static final String CONTEXT_CLIENT_VERSION_EXTRA = "eglContextClientVersion";
 
+    private static final int EGL_OPENGL_ES_BIT = 0x1;
+    private static final int EGL_OPENGL_ES2_BIT = 0x4;
+
     private EglConfigGLSurfaceView mView;
 
     private CountDownLatch mFinishedDrawing;
+    private CountDownLatch mFinishedTesting;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        int configId = getConfigId();
-        int contextClientVersion = getContextClientVersion();
-        setTitle("EGL Config Id: " + configId + " Client Version: " + contextClientVersion);
 
         // Dismiss keyguard and keep screen on while this test is on.
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                 WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
                 WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
 
-        mFinishedDrawing = new CountDownLatch(1);
-        mView = new EglConfigGLSurfaceView(this, configId, contextClientVersion, new Runnable() {
-            @Override
-            public void run() {
-                mFinishedDrawing.countDown();
-            }
-        });
-        setContentView(mView);
-    }
-
-    private int getConfigId() {
-        Intent intent = getIntent();
-        if (intent != null) {
-            return intent.getIntExtra(CONFIG_ID_EXTRA, 0);
-        } else {
-            return 0;
-        }
-    }
-
-    private int getContextClientVersion() {
-        Intent intent = getIntent();
-        if (intent != null) {
-            return intent.getIntExtra(CONTEXT_CLIENT_VERSION_EXTRA, 0);
-        } else {
-            return 0;
+        int[] configIds = getEglConfigIds(EGL_OPENGL_ES_BIT);
+        int[] configIds2 = getEglConfigIds(EGL_OPENGL_ES2_BIT);
+        assertTrue(configIds.length + configIds2.length > 0);
+        mFinishedTesting = new CountDownLatch(configIds.length + configIds2.length);
+        try {
+            runConfigTests(configIds, 1);
+            runConfigTests(configIds2, 2);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Caught exception");
         }
     }
 
     @Override
     protected void onResume() {
         super.onResume();
-        mView.onResume();
+        if (mView != null)
+        {
+            mView.onResume();
+        }
     }
 
     @Override
     protected void onPause() {
         super.onPause();
-        mView.onPause();
+        if (mView != null)
+        {
+            mView.onPause();
+        }
     }
 
-    public void waitToFinishDrawing() throws InterruptedException {
-        if (!mFinishedDrawing.await(3, TimeUnit.SECONDS)) {
-            throw new IllegalStateException("Coudn't finish drawing frames!");
+    private void runConfigTests(int[] configIds, int contextClientVersion)
+            throws InterruptedException {
+        Context context = this;
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                for (int configId : configIds) {
+                    mFinishedDrawing = new CountDownLatch(1);
+
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            setTitle("EGL Config Id: " + configId + " Client Version: " + contextClientVersion);
+                            mView = new EglConfigGLSurfaceView(context, configId, contextClientVersion, new Runnable() {
+                                @Override
+                                public void run() {
+                                    mFinishedDrawing.countDown();
+                                }
+                            });
+                            setContentView(mView);
+                        }
+                    });
+
+                    try {
+                        waitToFinishDrawing();
+                    } catch (Exception e) {
+                        Log.e(TAG, "Timed out!");
+                    }
+
+                    mFinishedTesting.countDown();
+                }
+            }
+        };
+        thread.start();
+    }
+
+    private void waitToFinishDrawing() throws InterruptedException {
+        if (!mFinishedDrawing.await(5, TimeUnit.SECONDS)) {
+            throw new IllegalStateException("Couldn't finish drawing frames!");
+        }
+    }
+
+    void waitToFinishTesting() throws InterruptedException {
+        if (!mFinishedTesting.await(300, TimeUnit.SECONDS)) {
+            throw new IllegalStateException("Couldn't finish testing!");
+        }
+    }
+
+    private static int[] getEglConfigIds(int renderableType) {
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+        int[] numConfigs = new int[1];
+
+        int[] attributeList = new int[] {
+                EGL10.EGL_RENDERABLE_TYPE, renderableType,
+
+                // Avoid configs like RGBA0008 which crash even though they have the window bit set.
+                EGL10.EGL_RED_SIZE, 1,
+                EGL10.EGL_GREEN_SIZE, 1,
+                EGL10.EGL_BLUE_SIZE, 1,
+
+                EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
+                EGL10.EGL_NONE
+        };
+
+        if (egl.eglInitialize(display, null)) {
+            try {
+                if (egl.eglChooseConfig(display, attributeList, null, 0, numConfigs)) {
+                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
+                    if (egl.eglChooseConfig(display, attributeList, configs, configs.length,
+                            numConfigs)) {
+                        int[] configIds = new int[numConfigs[0]];
+                        for (int i = 0; i < numConfigs[0]; i++) {
+                            int[] value = new int[1];
+                            if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_ID,
+                                    value)) {
+                                configIds[i] = value[0];
+                            } else {
+                                throw new IllegalStateException("Couldn't call eglGetConfigAttrib");
+                            }
+                        }
+                        return configIds;
+                    } else {
+                        throw new IllegalStateException("Couldn't call eglChooseConfig (1)");
+                    }
+                } else {
+                    throw new IllegalStateException("Couldn't call eglChooseConfig (2)");
+                }
+            } finally {
+                egl.eglTerminate(display);
+            }
+        } else {
+            throw new IllegalStateException("Couldn't initialize EGL.");
         }
     }
 }
diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
index 3e5565e..613456a 100644
--- a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
@@ -25,6 +25,7 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
+import static androidx.test.internal.util.Checks.checkState;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -36,14 +37,16 @@
 import javax.microedition.khronos.egl.EGLContext;
 import javax.microedition.khronos.egl.EGLDisplay;
 
+import android.util.Log;
+import java.lang.Runnable;
+
 /**
  * Test that gets a list of EGL configurations and tries to use each one in a GLSurfaceView.
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class EglConfigTest {
-    private static final int EGL_OPENGL_ES_BIT = 0x1;
-    private static final int EGL_OPENGL_ES2_BIT = 0x4;
+    private final String TAG = this.getClass().getSimpleName();
 
     private Instrumentation mInstrumentation;
 
@@ -58,75 +61,11 @@
 
     @Test
     public void testEglConfigs() throws Exception {
-        int[] configIds = getEglConfigIds(EGL_OPENGL_ES_BIT);
-        int[] configIds2 = getEglConfigIds(EGL_OPENGL_ES2_BIT);
-        assertTrue(configIds.length + configIds2.length > 0);
-        runConfigTests(configIds, 1);
-        runConfigTests(configIds2, 2);
-    }
-
-    private void runConfigTests(int[] configIds, int contextClientVersion)
-            throws InterruptedException {
-        for (int configId : configIds) {
-            Intent intent = new Intent(InstrumentationRegistry.getTargetContext(),
-                    EglConfigCtsActivity.class);
-            intent.putExtra(EglConfigCtsActivity.CONFIG_ID_EXTRA, configId);
-            intent.putExtra(EglConfigCtsActivity.CONTEXT_CLIENT_VERSION_EXTRA,
-                    contextClientVersion);
-            EglConfigCtsActivity activity = mActivityRule.launchActivity(intent);
-            activity.waitToFinishDrawing();
-            // TODO(b/30948621): Remove the sleep below once b/30948621 is fixed.
-            Thread.sleep(500);
-            activity.finish();
-            mInstrumentation.waitForIdleSync();
-        }
-    }
-
-    private static int[] getEglConfigIds(int renderableType) {
-        EGL10 egl = (EGL10) EGLContext.getEGL();
-        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-        int[] numConfigs = new int[1];
-
-        int[] attributeList = new int[] {
-                EGL10.EGL_RENDERABLE_TYPE, renderableType,
-
-                // Avoid configs like RGBA0008 which crash even though they have the window bit set.
-                EGL10.EGL_RED_SIZE, 1,
-                EGL10.EGL_GREEN_SIZE, 1,
-                EGL10.EGL_BLUE_SIZE, 1,
-
-                EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
-                EGL10.EGL_NONE
-        };
-
-        if (egl.eglInitialize(display, null)) {
-            try {
-                if (egl.eglChooseConfig(display, attributeList, null, 0, numConfigs)) {
-                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
-                    if (egl.eglChooseConfig(display, attributeList, configs, configs.length,
-                            numConfigs)) {
-                        int[] configIds = new int[numConfigs[0]];
-                        for (int i = 0; i < numConfigs[0]; i++) {
-                            int[] value = new int[1];
-                            if (egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_ID,
-                                    value)) {
-                                configIds[i] = value[0];
-                            } else {
-                              throw new IllegalStateException("Couldn't call eglGetConfigAttrib");
-                            }
-                        }
-                        return configIds;
-                    } else {
-                        throw new IllegalStateException("Couldn't call eglChooseConfig (1)");
-                    }
-                } else {
-                    throw new IllegalStateException("Couldn't call eglChooseConfig (2)");
-                }
-            } finally {
-                egl.eglTerminate(display);
-            }
-        } else {
-            throw new IllegalStateException("Couldn't initialize EGL.");
-        }
+        Intent intent = new Intent(InstrumentationRegistry.getTargetContext(),
+                EglConfigCtsActivity.class);
+        EglConfigCtsActivity activity = mActivityRule.launchActivity(intent);
+        activity.waitToFinishTesting();
+        activity.finish();
+        mInstrumentation.waitForIdleSync();
     }
 }
diff --git a/tests/tests/os/src/android/os/cts/EnvironmentTest.java b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
index 0f2ac62..622d35a 100644
--- a/tests/tests/os/src/android/os/cts/EnvironmentTest.java
+++ b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
@@ -83,7 +83,12 @@
         final long maxInodes = maxsize / 4096;
         // Assuming the smallest storage would be 4GB, min # of free inodes
         // in EXT4/F2FS must be larger than 128k for Android to work properly.
-        final long minInodes = 128 * 1024;
+        long minInodes = 128 * 1024;
+        final long size4GB = 4294967296l;
+        //If the storage size is smaller than 4GB, let's consider 32k for 1GB.
+        if (maxsize < size4GB) {
+            minInodes = 32 * 1024;
+        }
 
         if (stat.f_ffree >= minInodes && stat.f_ffree <= maxInodes
             && stat.f_favail <= stat.f_ffree) {
diff --git a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
index 8609e33..84c2dd6 100644
--- a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
+++ b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
@@ -25,11 +25,15 @@
 import static android.content.Context.WIFI_P2P_SERVICE;
 import static android.content.Context.WIFI_SERVICE;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 
+import android.app.WallpaperManager;
 import android.content.Context;
 import android.platform.test.annotations.AppModeInstant;
 
+import com.android.compatibility.common.util.RequiredServiceRule;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -68,8 +72,14 @@
 
     @Test
     public void cannotGetWallpaperManager() {
-        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
-                WALLPAPER_SERVICE));
+        WallpaperManager mgr  = (WallpaperManager) InstrumentationRegistry.getTargetContext()
+                .getSystemService(WALLPAPER_SERVICE);
+        boolean supported = RequiredServiceRule.hasService("wallpaper");
+        if (supported) {
+            assertNull(mgr);
+        } else {
+            assertFalse(mgr.isWallpaperSupported());
+        }
     }
 
     @Test
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index 975796d..6d6e867 100644
--- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml
+++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
@@ -216,6 +216,12 @@
         android:label="@string/car_permission_label_storage_monitoring"
         android:description="@string/car_permission_desc_storage_monitoring" />
 
+    <permission
+        android:name="android.car.permission.CAR_TEST_SERVICE"
+        android:protectionLevel="privileged|signature"
+        android:label="@string/car_permission_label_car_test_service"
+        android:description="@string/car_permission_desc_car_test_service" />
+
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.DEVICE_POWER" />
     <uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" />
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
index 9e65d0b..2668d4d 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreUiTest.java
@@ -16,54 +16,33 @@
 
 package android.provider.cts;
 
-import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
-import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.CAMERA;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
-import static android.Manifest.permission.RECORD_AUDIO;
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
-
 import android.app.Activity;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.UriPermission;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.media.ExifInterface;
 import android.media.MediaScannerConnection;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
-import android.provider.MediaStore;
 import android.provider.cts.GetResultActivity.Result;
+import android.provider.MediaStore;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.test.InstrumentationTestCase;
 import android.text.format.DateUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-
-import androidx.core.content.FileProvider;
-import androidx.test.InstrumentationRegistry;
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -144,127 +123,6 @@
         }
     }
 
-    private void maybeClick(UiSelector sel) {
-        try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
-    }
-
-    private void maybeClick(BySelector sel) {
-        try { mDevice.findObject(sel).click(); } catch (Throwable ignored) { }
-    }
-
-    private void maybeGrantRuntimePermission(String pkg, Set<String> requested, String permission) {
-        if (requested.contains(permission)) {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .grantRuntimePermission(pkg, permission);
-        }
-    }
-
-    /**
-     * Verify that whoever handles {@link MediaStore#ACTION_IMAGE_CAPTURE} can
-     * correctly write the contents into a passed {@code content://} Uri.
-     */
-    public void testImageCapture() throws Exception {
-        final Context context = getInstrumentation().getContext();
-        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
-            Log.d(TAG, "Skipping due to lack of camera");
-            return;
-        }
-
-        final File targetDir = new File(context.getFilesDir(), "debug");
-        final File target = new File(targetDir, "capture.jpg");
-
-        targetDir.mkdirs();
-        assertFalse(target.exists());
-
-        final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-        intent.putExtra(MediaStore.EXTRA_OUTPUT,
-                FileProvider.getUriForFile(context, "android.provider.cts.fileprovider", target));
-
-        // Figure out who is going to answer the phone
-        final ResolveInfo ri = context.getPackageManager().resolveActivity(intent, 0);
-        final String pkg = ri.activityInfo.packageName;
-        Log.d(TAG, "We're probably launching " + ri);
-
-        final PackageInfo pi = context.getPackageManager().getPackageInfo(pkg,
-                PackageManager.GET_PERMISSIONS);
-        final Set<String> req = new HashSet<>();
-        req.addAll(Arrays.asList(pi.requestedPermissions));
-
-        // Grant them all the permissions they might want
-        maybeGrantRuntimePermission(pkg, req, CAMERA);
-        maybeGrantRuntimePermission(pkg, req, ACCESS_COARSE_LOCATION);
-        maybeGrantRuntimePermission(pkg, req, ACCESS_FINE_LOCATION);
-        maybeGrantRuntimePermission(pkg, req, RECORD_AUDIO);
-        maybeGrantRuntimePermission(pkg, req, READ_EXTERNAL_STORAGE);
-        maybeGrantRuntimePermission(pkg, req, WRITE_EXTERNAL_STORAGE);
-        SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
-
-        mActivity.startActivityForResult(intent, REQUEST_CODE);
-        mDevice.waitForIdle();
-
-        // To ensure camera app is launched
-        SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-
-        // Try a couple different strategies for taking a photo: first take a
-        // photo and confirm using hardware keys
-        mDevice.pressKeyCode(KeyEvent.KEYCODE_CAMERA);
-        mDevice.waitForIdle();
-        SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-        mDevice.pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
-        mDevice.waitForIdle();
-
-        // Maybe that gave us a result?
-        Result result = mActivity.getResult(15, TimeUnit.SECONDS);
-        Log.d(TAG, "First pass result was " + result);
-
-        // Hrm, that didn't work; let's try an alternative approach of digging
-        // around for a shutter button
-        if (result == null) {
-            maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
-            mDevice.waitForIdle();
-            SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-            maybeClick(new UiSelector().resourceId(pkg + ":id/shutter_button"));
-            mDevice.waitForIdle();
-            maybeClick(new UiSelector().resourceId(pkg + ":id/done_button"));
-            mDevice.waitForIdle();
-
-            result = mActivity.getResult(15, TimeUnit.SECONDS);
-            Log.d(TAG, "Second pass result was " + result);
-        }
-
-        // Grr, let's try hunting around even more
-        if (result == null) {
-            maybeClick(By.pkg(pkg).descContains("Capture"));
-            mDevice.waitForIdle();
-            SystemClock.sleep(5 * DateUtils.SECOND_IN_MILLIS);
-            maybeClick(By.pkg(pkg).descContains("Done"));
-            mDevice.waitForIdle();
-
-            result = mActivity.getResult(15, TimeUnit.SECONDS);
-            Log.d(TAG, "Third pass result was " + result);
-        }
-
-        assertNotNull("Expected to get a IMAGE_CAPTURE result; your camera app should "
-                + "respond to the CAMERA and DPAD_CENTER keycodes", result);
-
-        assertTrue("exists", target.exists());
-        assertTrue("has data", target.length() > 65536);
-
-        // At the very least we expect photos generated by the device to have
-        // sane baseline EXIF data
-        final ExifInterface exif = new ExifInterface(new FileInputStream(target));
-        assertAttribute(exif, ExifInterface.TAG_MAKE);
-        assertAttribute(exif, ExifInterface.TAG_MODEL);
-        assertAttribute(exif, ExifInterface.TAG_DATETIME);
-    }
-
-    private static void assertAttribute(ExifInterface exif, String tag) {
-        final String res = exif.getAttribute(tag);
-        if (res == null || res.length() == 0) {
-            Log.d(TAG, "Expected valid EXIF tag for tag " + tag);
-        }
-    }
-
     private boolean supportsHardware() {
         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
         return !pm.hasSystemFeature("android.hardware.type.automotive")
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
index 60e27e6..bccbe59 100644
--- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -107,6 +107,7 @@
             } catch (SecurityException e) {
                 String msg = e.getMessage();
                 if ((msg == null) || msg.contains("android.permission.DUMP")) {
+                    Log.d(TAG, "Service " + service + " correctly checked permission");
                     // Service correctly checked for DUMP permission, yay
                 } else {
                     // Service is throwing about something else; they're
@@ -115,7 +116,9 @@
                     continue;
                 }
             } catch (TransactionTooLargeException | DeadObjectException e) {
-                // SELinux likely prevented the dump - assume safe
+                // SELinux likely prevented the dump - assume safe, but log anywasy
+                // (as the exception might happens in some devices but not on others)
+                Log.w(TAG, "Service " + service + " threw exception: " + e);
                 continue;
             } finally {
                 out.close();
diff --git a/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
new file mode 100644
index 0000000..2a2e8e4
--- /dev/null
+++ b/tests/tests/slice/src/android/slice/cts/SliceProviderTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2019 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.slice.cts;
+
+import android.app.slice.Slice;
+import android.app.slice.SliceSpec;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.Bundle;
+
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.android.collect.Lists;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SliceProviderTest {
+
+    private static final String VALID_AUTHORITY = "android.slice.cts";
+    private static final String SUSPICIOUS_AUTHORITY = "com.suspicious.www";
+    private static final String ACTION_BLUETOOTH = "/action/bluetooth";
+    private static final String VALID_BASE_URI_STRING = "content://" + VALID_AUTHORITY;
+    private static final String VALID_ACTION_URI_STRING =
+            "content://" + VALID_AUTHORITY + ACTION_BLUETOOTH;
+    private static final String SHADY_ACTION_URI_STRING =
+            "content://" + SUSPICIOUS_AUTHORITY + ACTION_BLUETOOTH;
+
+    @Rule
+    public ActivityTestRule<Launcher> mLauncherActivityTestRule = new ActivityTestRule<>(Launcher.class);
+
+    private Uri validBaseUri = Uri.parse(VALID_BASE_URI_STRING);
+    private Uri validActionUri = Uri.parse(VALID_ACTION_URI_STRING);
+    private Uri shadyActionUri = Uri.parse(SHADY_ACTION_URI_STRING);
+
+    private ContentResolver mContentResolver;
+
+    @Before
+    public void setUp() {
+        mContentResolver = mLauncherActivityTestRule.getActivity().getContentResolver();
+    }
+
+    @Test
+    public void testCallSliceUri_ValidAuthority() {
+        doQuery(validActionUri);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testCallSliceUri_ShadyAuthority() {
+        doQuery(shadyActionUri);
+    }
+
+    private Slice doQuery(Uri actionUri) {
+        Bundle extras = new Bundle();
+        extras.putParcelable("slice_uri", actionUri);
+        extras.putParcelableArrayList("supported_specs", Lists.newArrayList(
+                    new SliceSpec("androidx.slice.LIST", 1),
+                    new SliceSpec("androidx.app.slice.BASIC", 1),
+                    new SliceSpec("androidx.slice.BASIC", 1),
+                    new SliceSpec("androidx.app.slice.LIST", 1)
+            ));
+        Bundle result = mContentResolver.call(
+                validBaseUri,
+                SliceProvider.METHOD_SLICE,
+                null,
+                extras
+        );
+        return result.getParcelable(SliceProvider.EXTRA_SLICE);
+    }
+
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 0eabad7..9095ed0 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -92,8 +92,9 @@
 
     @Test
     public void testListen() throws Throwable {
-        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
-            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+        if (!InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.d(TAG, "Skipping test that requires PackageManager.FEATURE_TELEPHONY");
             return;
         }
 
@@ -186,7 +187,9 @@
         }
 
         // Make sure devices without MMS service won't fail on this
-        if (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE) {
+        if (InstrumentationRegistry.getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
+                && (mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE)) {
             assertFalse(mTelephonyManager.getMmsUserAgent().isEmpty());
             assertFalse(mTelephonyManager.getMmsUAProfUrl().isEmpty());
         }
diff --git a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
index 4d1756c..87f9de6 100644
--- a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
@@ -309,6 +309,7 @@
         mActivityRule.runOnUiThread(() -> {
             mActivity.getWindow().setExitTransition(new Fade());
             Intent intent = new Intent(mActivity, TargetActivity.class);
+            intent.putExtra(TargetActivity.EXTRA_USE_ANIMATOR, true);
             ActivityOptions activityOptions =
                     ActivityOptions.makeSceneTransitionAnimation(mActivity);
             mActivity.startActivity(intent, activityOptions.toBundle());
@@ -372,7 +373,7 @@
 
         TargetActivity targetActivity = waitForTargetActivity();
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
         assertEquals(View.VISIBLE, targetActivity.startVisibility);
         assertEquals(View.VISIBLE, targetActivity.endVisibility);
 
@@ -385,14 +386,13 @@
             targetActivity.finishAfterTransition();
         });
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
         assertEquals(View.VISIBLE, targetActivity.startVisibility);
         assertEquals(View.VISIBLE, targetActivity.endVisibility);
 
-        assertTrue(targetActivity.transitionComplete.await(1, TimeUnit.SECONDS));
-        verify(mReenterListener, within(3000)).onTransitionEnd(any());
-
-        TargetActivity.sLastCreated = null;
+        assertTrue(targetActivity.transitionComplete.await(5, TimeUnit.SECONDS));
+        verify(mReenterListener, within(5000)).onTransitionStart(any());
+        verify(mReenterListener, within(5000)).onTransitionEnd(any());
     }
 
     // Starting a shared element transition and then removing the view shouldn't cause problems.
diff --git a/tests/tests/transition/src/android/transition/cts/TargetActivity.java b/tests/tests/transition/src/android/transition/cts/TargetActivity.java
index a710ca0..9cbd993 100644
--- a/tests/tests/transition/src/android/transition/cts/TargetActivity.java
+++ b/tests/tests/transition/src/android/transition/cts/TargetActivity.java
@@ -66,7 +66,9 @@
 
         if (useAnimator) {
             enterTransition = new TrackingVisibilityWithAnimator();
+            enterTransition.setDuration(2000);
             returnTransition = new TrackingVisibilityWithAnimator();
+            returnTransition.setDuration(2000);
         }
 
         if (excludeId != 0) {
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
index 3a60cd4..8fb6bba 100644
--- a/tests/tests/transition/src/android/transition/cts/TransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
@@ -541,7 +541,7 @@
         Animator animator = transition.animators.get(redSquare);
         assertFalse(animator.isRunning());
         Animator.AnimatorListener listener = transition.listeners.get(redSquare);
-        verify(listener, within(250)).onAnimationStart(any(), eq(false));
+        verify(listener, within(1000)).onAnimationStart(any(), eq(false));
         endTransition();
     }
 
diff --git a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
index 27c388a..6314ec5 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -105,7 +105,8 @@
     private static final String WHITE_SPACES = " \r \n \t \f ";
 
     private static final String PARAM_CANONICAL_GENRE = "canonical_genre";
-    private static final String NON_EXISTING_COLUMN_NAME = "non_existing_column";
+    private static final String[] NON_EXISTING_COLUMN_NAMES =
+            {"non_existing_column", "another non-existing column --"};
 
     private String mInputId;
     private ContentResolver mContentResolver;
@@ -336,15 +337,20 @@
     private void verifyNonExistingColumn(Uri channelUri, long channelId) {
         String[] projection = {
                 Channels._ID,
-                NON_EXISTING_COLUMN_NAME
+                NON_EXISTING_COLUMN_NAMES[0],
+                NON_EXISTING_COLUMN_NAMES[1]
         };
         try (Cursor cursor = mContentResolver.query(channelUri, projection, null, null, null)) {
             assertNotNull(cursor);
             assertEquals(cursor.getCount(), 1);
             assertTrue(cursor.moveToNext());
             assertEquals(channelId, cursor.getLong(0));
+            assertEquals(NON_EXISTING_COLUMN_NAMES[0], cursor.getColumnName(1));
             assertNull(cursor.getString(1));
             assertEquals(0, cursor.getInt(1));
+            assertEquals(NON_EXISTING_COLUMN_NAMES[1], cursor.getColumnName(2));
+            assertNull(cursor.getString(2));
+            assertEquals(0, cursor.getInt(2));
         }
     }
 
@@ -533,7 +539,8 @@
             return;
         }
         ContentValues values = createDummyChannelValues(mInputId, false);
-        values.put(NON_EXISTING_COLUMN_NAME, "dummy value");
+        values.put(NON_EXISTING_COLUMN_NAMES[0], "dummy value 0");
+        values.put(NON_EXISTING_COLUMN_NAMES[1], "dummy value 1");
         Uri rowUri = mContentResolver.insert(mChannelsUri, values);
         long channelId = ContentUris.parseId(rowUri);
         Uri channelUri = TvContract.buildChannelUri(channelId);
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
index f1838e2..641d6c9 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -212,9 +212,9 @@
             display.getRealSize(size);
             display.getMetrics(metrics);
 
-            View decorView = getWindow().getDecorView();
-            Rect boundsToCheck = new Rect(0, 0, decorView.getWidth(), decorView.getHeight());
-            int[] topLeft = decorView.getLocationOnScreen();
+            View testAreaView = findViewById(android.R.id.content);
+            Rect boundsToCheck = new Rect(0, 0, testAreaView.getWidth(), testAreaView.getHeight());
+            int[] topLeft = testAreaView.getLocationOnScreen();
             boundsToCheck.offset(topLeft[0], topLeft[1]);
 
             if (boundsToCheck.width() < 90 || boundsToCheck.height() < 90) {
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
index db6bbb9..3c508a9 100644
--- a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
@@ -87,7 +87,10 @@
     }
 
     private boolean runTest(BroadcastUtils.TestcaseType test, int expectedMode) throws Exception {
-        if (!startTestAndWaitForBroadcast(test, VOICE_SETTINGS_PACKAGE, VOICE_INTERACTION_CLASS)) {
+        if (!startTestAndWaitForChange(test,
+                Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON),
+                VOICE_SETTINGS_PACKAGE,
+                VOICE_INTERACTION_CLASS)) {
             return false;
         }
 
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java
index e01f3b9..e157ad0 100644
--- a/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java
@@ -92,7 +92,9 @@
     }
 
     private boolean runTest(BroadcastUtils.TestcaseType test, int expectedMode) throws Exception {
-        if (!startTestAndWaitForBroadcast(test, VOICE_SETTINGS_PACKAGE, VOICE_INTERACTION_CLASS)) {
+        if (!startTestAndWaitForChange(test,
+                Settings.Global.getUriFor(ZEN_MODE), VOICE_SETTINGS_PACKAGE,
+                VOICE_INTERACTION_CLASS)) {
             return false;
         }
 
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 6d69945..674cd36 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1889,7 +1889,7 @@
         final int previousScrollX = mOnUiThread.getScrollX();
         final int previousScrollY = mOnUiThread.getScrollY();
 
-        mOnUiThread.flingScroll(100, 100);
+        mOnUiThread.flingScroll(10000, 10000);
 
         new PollingCheck() {
             @Override
diff --git a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
index b469212..2deb847 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
@@ -195,6 +195,10 @@
         Uri uri = Uri.parse("ctstest://tabhost_tabspec/test");
         final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
 
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
+                null, false);
+
         mActivity.runOnUiThread(() -> {
             TabHost.TabSpec tabSpec = mTabHost.newTabSpec("tab spec");
             tabSpec.setIndicator("tab");
@@ -203,10 +207,6 @@
             mTabHost.setCurrentTab(1);
         });
 
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        ActivityMonitor am = instrumentation.addMonitor(MockURLSpanTestActivity.class.getName(),
-                null, false);
-
         Activity newActivity = am.waitForActivityWithTimeout(5000);
         assertNotNull(newActivity);
         newActivity.finish();